<?php
namespace App\Mvc\View\Utils\Types;

/**
 * Class used by the listing views to define the available listing columns. This represents a container, that may hold multiple columns
 * @author Lucian Sirbu
 */
class ListingColumns
{
	/**
	 * The internal list of columns
	 * @var \Array:\App\Mvc\View\Utils\Types\ListingColumn
	 */
	protected $columns = [];

	/**
	 * Create a column
	 * @return \App\Mvc\View\Utils\Types\ListingColumns
	 */
	public static function create()
	{
		return new self();
	}

	/**
	 * Append a column at the end of the internal column list
	 * @param \App\Mvc\View\Utils\Types\ListingColumn $column
	 * @return \App\Mvc\View\Utils\Types\ListingColumns
	 */
	public function append(\App\Mvc\View\Utils\Types\ListingColumn $column)
	{
		$this->columns[] = $column;
		return $this;
	}

	/**
	 * Insert a column at a certain position in the internal columns list
	 * @param \App\Mvc\View\Utils\Types\ListingColumn $column
	 * @param int $index
	 * @return \App\Mvc\View\Utils\Types\ListingColumns
	 */
	public function insert(\App\Mvc\View\Utils\Types\ListingColumn $column, $index)
	{
		$columns = array_merge(
			array_slice($this->columns, 0, $index),
			[$column],
			array_slice($this->columns, $index)
		);

		$this->columns = $columns;
		return $this;
	}

	/**
	 * Get all defined columns
	 * @return \Array:\App\Mvc\View\Utils\Types\ListingColumn
	 */
	public function getAll($filters = [])
	{
		$ret = $this->columns;

		if ($filters) {
			$ret = [];
			foreach($this->columns as $column) {
				/* @var $column \App\Mvc\View\Utils\Types\ListingColumn */

				$matched = false;
				if (isset($filters['sortable'])) {
					if ($filters['sortable'] == $column->getSortable()) {
						$matched = true;
					}
				}

				if (isset($filters['visible'])) {
					if ($filters['visible'] == !$column->isInvisible()) {
						$matched = true;
					}
				}

				if ($matched) {
					$ret[] = $column;
				}
			}
		}

		return $ret;
	}

	/**
	 * Get a list of sortable columns
	 * @return \Array:\App\Mvc\View\Utils\Types\ListingColumn
	 */
	public function getAllSortable()
	{
		return $this->getAll(['sortable' => true,]);
	}

	/**
	 * Get a list of visible columns
	 * @return \Array:\App\Mvc\View\Utils\Types\ListingColumn
	 */
	public function getAllVisible()
	{
		return $this->getAll(['visible' => true,]);
	}

	/**
	 * Loops over all columns and load column labels
	 * @param array $lang
	 * @return \App\Mvc\View\Utils\Types\ListingColumns
	 */
	public function loadLabels($lang)
	{
		foreach($this->columns as $column){
			/* @var $column \App\Mvc\View\Utils\Types\ListingColumn */
			if(!$column->getLabel()){
				$column->loadLabel($lang);
			}
		}

		return $this;
	}

	/**
	 * Load the column settings from the specified param
	 * @param array $settings
	 * @return \App\Mvc\View\Utils\Types\ListingColumns
	 */
	public function loadSettings(Array $settings)
	{
		if ($settings) {
			// sort the internal list of columns according to the sort order defined by the user in $settings
			$dynamicOptionsOrder = array_keys($settings);
			usort($this->columns, function ($a, $b) use($dynamicOptionsOrder) {
				return array_search($a->getId(), $dynamicOptionsOrder) - array_search($b->getId(), $dynamicOptionsOrder);
			});

			// show/hide custom columns accordding to user preferences
			foreach($this->columns as $column) {
				$id = $column->getId();
				$col = $settings[$id];
				if ($col) {
					if (isset($col['visible'])) {
						$column->setInvisible(!$col['visible']);
					}
				}
			}
		}

		return $this;
	}
}
