<?php
namespace App\Mvc\View\Listing\Members;

/**
 * The class manages the parameters of a listing: allowed ordering columns, filters, results per page, current page, order column/direction.
 * The information is stored using Cache class in session.
 * @author Gabriel
 */
class Params
{
	/**
	 * The unique key for the cache location in session.
	 * @var String
	 */
	protected $cacheKey;

	/**
	 * The default values
	 * @var array
	 */
	protected $defaults = [];

	/**
	 * The current params
	 * @var array
	 */
	protected $data = [];

	/**
	 * Marked when internal data is actually changing, to know what sections to save/ignore
	 * @var array
	 */
	protected $dataChanged = [];

	/**
	 * The class constructor - sets the unique key for cache location.
	 * @param String $uniqueKey
	 */
	public function __construct($cacheKey)
	{
		$this->cacheKey = $cacheKey;
	}

	/**
	 * Set the default filters
	 * @param array $filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setDefaultFilters(?Array $filters=null)
	{
		$this->defaults['filters'] = $filters;
		return $this;
	}

	/**
	 * Get the internal defaults, as assigned initially
	 */
	public function getDefaultFilters()
	{
		return $this->defaults['filters'];
	}

	/**
	 * Set the currently defined filters
	 * @param array $filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setFilters(?Array $filters=null)
	{
		$this->dataChanged['filters'] = true;
		$this->data['filters'] = $filters;
		return $this;
	}

	/**
	 * Merge internal filters with new filters
	 * @param array $newFilters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function mergeFilters(?Array $newFilters=null)
	{
		$oldFilters = $this->getFilters();
		$filters = $oldFilters;
		foreach ($newFilters as $k=>$v) {
			$filters[$k] = $v;
		}

		return $this->setFilters($filters);
	}

	/**
	 * Get the currently defined filters
	 * @return array
	 */
	public function getFilters()
	{
		return ($this->data['filters']?:$this->defaults['filters']);
	}

	/**
	 * Set the currently defined filters
	 * @param array $filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setDynamicColumnsSettings(Array $dynamicColumnsSettings)
	{
		$this->dataChanged['dynamicColumnsSettings'] = true;
		$this->data['dynamicColumnsSettings'] = $dynamicColumnsSettings;
		return $this;
	}

	/**
	 * Get the currently defined filters
	 * @return array
	 */
	public function getDynamicColumnsSettings()
	{
		return ($this->data['dynamicColumnsSettings']?:[]);
	}

	/**
	 * Set the default listing params
	 * @param array $params
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setDefaultParams(Array $params)
	{
		$this->defaults['listingParams'] = $params;
		return $this;
	}

	/**
	 * Set a custom param
	 * @param string $key
	 * @param mixed $value
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setParam($key, $value)
	{
		$this->dataChanged['listingParams'] = true;
		$this->data['listingParams'][$key] = $value;
		return $this;
	}

	/**
	 * Get a custom param
	 * @param mixed $key
	 */
	public function getParam($key)
	{
		return (isset($this->data['listingParams'][$key])?$this->data['listingParams'][$key]:$this->defaults['listingParams'][$key]);
	}

	/**
	 * Set the current page
	 * @param int $page
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setCurrentPage($page)
	{
		return $this->setParam('currentPage', $page);
	}

	/**
	 * Get current page number
	 * @return int
	 */
	public function getCurrentPage()
	{
		return (int)$this->getParam('currentPage');
	}

	/**
	 * Set the results per page
	 * @param int $rpp
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setResultsPerPage($rpp)
	{
		return $this->setParam('resultsPerPage', $rpp);
	}

	/**
	 * Get the results per page
	 * @return int
	 */
	public function getResultsPerPage()
	{
		return (int)$this->getParam('resultsPerPage');
	}

	/**
	 * Set the currently ordered column
	 * @param string $column
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setOrderColumn($column)
	{
		return $this->setParam('orderColumn', $column);
	}

	/**
	 * Get the currently ordered column
	 * @return string
	 */
	public function getOrderColumn()
	{
		return $this->getParam('orderColumn');
	}

	/**
	 * Set the order direction
	 * @param string $direction : ASC/DESC
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function setOrderDirection($direction)
	{
		return $this->setParam('orderDirection', $direction);
	}

	/**
	 * Get the order direction
	 * @return string: ASC/DESC
	 */
	public function getOrderDirection()
	{
		return $this->getParam('orderDirection');
	}

	/**
	 * Completely resets the current filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function reset()
	{
		// cleans the current listing params
		$this->data = [
			'listingParams' => 		[],
			'filters' => 			[],
		];

		$this->dataChanged['listingParams'] = 	true;
		$this->dataChanged['filters'] = 		true;

		return $this;
	}

	/**
	 * Save the current filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function save()
	{
		if ($this->dataChanged['listingParams']??null) {
			\Engine\Storage\General::getInstance('session')->set(sprintf("%s/%s/listingParams", __CLASS__, $this->cacheKey), $this->data['listingParams']);
		}
		if ($this->dataChanged['filters']??null) {
			\Engine\Storage\General::getInstance('session')->set(sprintf("%s/%s/filters", __CLASS__, $this->cacheKey), $this->data['filters']);
		}
		if ($this->dataChanged['dynamicColumnsSettings']??null) {
			\Engine\Storage\General::getInstance('persistent')->set(sprintf("%s/%s/dynamicColumnsSettings", __CLASS__, $this->cacheKey), $this->data['dynamicColumnsSettings']);
		}

		return $this;
	}

	/**
	 * Load the current filters
	 * @return \App\Mvc\View\Listing\Members\Params
	 */
	public function load()
	{
		$this->data['listingParams'] = 			\Engine\Storage\General::getInstance('session')->get(sprintf("%s/%s/listingParams", __CLASS__, $this->cacheKey));
		$this->data['filters'] = 				\Engine\Storage\General::getInstance('session')->get(sprintf("%s/%s/filters", __CLASS__, $this->cacheKey));
		$this->data['dynamicColumnsSettings'] = \Engine\Storage\General::getInstance('persistent')->get(sprintf("%s/%s/dynamicColumnsSettings", __CLASS__, $this->cacheKey));
		return $this;
	}

}