<?php
/*****************************************************************************
 * AssetIterator.php
 * Contains key class AssetIterator.
 *
 * Kabuki CMS (C) 2013-2015, Aaron van Geffen
 *****************************************************************************/

class AssetIterator extends Asset
{
	private $return_format;
	private $res_assets;
	private $res_meta;

	protected function __construct($res_assets, $res_meta, $return_format)
	{
		$this->db = Registry::get('db');
		$this->res_assets = $res_assets;
		$this->res_meta = $res_meta;
		$this->return_format = $return_format;
	}

	public function next()
	{
		$row = $this->db->fetch_assoc($this->res_assets);

		// No more rows?
		if (!$row)
			return false;

		// Looks up metadata.
		$row['meta'] = [];
		while ($meta = $this->db->fetch_assoc($this->res_meta))
		{
			if ($meta['id_asset'] != $row['id_asset'])
				continue;

			$row['meta'][$meta['variable']] = $meta['value'];
		}

		// Reset internal pointer for next asset.
		$this->db->data_seek($this->res_meta, 0);

		if ($this->return_format == 'object')
			return new Asset($row);
		else
			return $row;
	}

	public function reset()
	{
		$this->db->data_seek($this->res_assets, 0);
		$this->db->data_seek($this->res_meta, 0);
	}

	public function clean()
	{
		if (!$this->res_assets)
			return;

		$this->db->free_result($this->res_assets);
		$this->res_assets = null;
	}

	public function num()
	{
		return $this->db->num_rows($this->res_assets);
	}

	public static function all()
	{
		return self::getByOptions();
	}

	public static function getByOptions(array $options = [], $return_count = false, $return_format = 'object')
	{
		$params = [
			'limit' => isset($options['limit']) ? $options['limit'] : 0,
			'order' => isset($options['order']) && in_array($options['order'], ['id_asset', 'subdir', 'filename', 'title',
				'mime_type', 'image_width', 'image_height', 'date_captured']) ? $options['order'] : 'id_asset',
			'direction' => isset($options['direction']) ? $options['direction'] : 'asc',
		];

		if (isset($options['offset']))
			$params['offset'] = $options['offset'];
		elseif (isset($options['page']) && $options['page'] >= 1)
			$params['offset'] = $params['limit'] * ($options['page'] - 1);
		else
			$params['offset'] = 0;

		$where = [];

		if (isset($options['mime_type']))
		{
			$params['mime_type'] = $options['mime_type'];
			if (is_array($options['mime_type']))
				$where[] = 'a.mimetype IN({array_string:mime_type})';
			else
				$where[] = 'a.mimetype = {string:mime_type}';
		}
		if (isset($options['id_tag']))
		{
			$params['id_tag'] = $options['id_tag'];
			$where[] = 'id_asset IN(
				SELECT l.id_asset
				FROM assets_tags AS l
				WHERE l.id_tag = {int:id_tag})';
		}

		// Make it valid SQL.
		$order = 'a.' . $params['order'] . ' ' . ($params['direction'] == 'desc' ? 'DESC' : 'ASC');
		$where = empty($where) ? '1' : implode(' AND ', $where);

		// And ... go!
		$db = Registry::get('db');

		// Get a resource object for the assets.
		$res_assets = $db->query('
			SELECT a.*
			FROM assets AS a
			WHERE ' . $where . '
			ORDER BY ' . $order . (!empty($params['limit']) ? '
			LIMIT {int:offset}, {int:limit}' : ''),
			$params);

		// Get a resource object for the asset meta.
		$res_meta = $db->query('
			SELECT id_asset, variable, value
			FROM assets_meta
			WHERE id_asset IN(
				SELECT id_asset
				FROM assets AS a
				WHERE ' . $where . '
			)
			ORDER BY id_asset',
			$params);

		$iterator = new self($res_assets, $res_meta, $return_format);

		// Returning total count, too?
		if ($return_count)
		{
			$count = $db->queryValue('
				SELECT COUNT(*)
				FROM assets AS a
				WHERE ' . $where,
				$params);

			return [$iterator, $count];
		}
		else
			return $iterator;
	}
}