<?php

namespace Engine\Form\Input;

class Matrix extends \Engine\Form\Input\ElementAbstract
{
	protected $class = "matrix";

	protected $childs = [];

	protected $url = null;

	protected $saveHandler = null;

	protected $rowRenderHandler = null;

	protected $disabledRows = [];

	/**
	 * Creates a matrix object
	 * @param String $label
	 * @param String $name
	 * @param String $value
	 */
	public function __construct($label=null, $name=null, $value=null)
	{
		parent::__construct($label, $name, $value);

		$this->settings['minItems'] = 1;
		$this->settings['showCounter'] = false;
		$this->settings['addLocation'] = 'bottom'; // (bottom, top)

		$this->settings['operations'] = [];
		$this->settings['operations']['add'] = true;
		$this->settings['operations']['remove'] = true;

		# $this->settings['operations']['default'] = true;

		$this->style['startIndex'] = 0;

		$this->style['render_rowIndex'] = true;
	}

	/**
	 * Add row inside matrix
	 * @param \Engine\Form\Input\Matrix\Row $row
	 * @param string $type
	 * @return \Engine\Form\Input\Matrix
	 */
	public function addRow(\Engine\Form\Input\Matrix\Row $row)
	{
		$row->setParent($this);
		$row->setStyle('operations_add', $this->settings['operations']['add']);
		$row->setStyle('operations_remove', $this->settings['operations']['remove']);
		$row->setStyle('render_rowIndex', $this->getStyle('render_rowIndex'));
		$this->childs[get_class($row)] = $row;
		return $this;
	}

	/**
	 * Get a specific defined row
	 * @param row class $type
	 * @return \Engine\Form\Input\Matrix\Row
	 */
	public function getRow($type)
	{
		return $this->childs[$type];
	}

	/**
	 * Set url for clone row ( client will make a request to this url)
	 * @param String $url
	 * @return \Engine\Form\Input\Matrix
	 */
	public function setUrl($url)
	{
		$this->url = $url;
		return $this;
	}

	/**
	 * Get url
	 * @return String
	 */
	public function getUrl()
	{
		return $this->url;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::setValue()
	 */
	public function setValue($value)
	{
		if (!$value) {
			$value = [];
		}
		return parent::setValue(array_values($value));
	}

	/**
	 * Set the list of disabled rows. The list should be an indexed list of keys, associated with $this->values
	 * @return \Engine\Form\Input\Matrix
	 */
	public function setDisabledRows($keys)
	{
		$this->disabledRows = $keys;
		return $this;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::getTemplateParams()
	 */
	protected function getTemplateParams($templateClass = null, $parentElement = null)
	{
		$params = parent::getTemplateParams($templateClass, null);

		$params['disabledRows'] = $this->disabledRows;
		$params['rowRenderHandler'] = $this->rowRenderHandler;

		return $params;
	}

	/**
	 * The "save" callback handler
	 * @return \Engine\Form\Input\Matrix
	 */
	public function setSaveHandler($callback)
	{
		$this->saveHandler = $callback;
		return $this;
	}

	public function setRenderRowCallback($callback)
	{
		$this->rowRenderHandler = $callback;
		return $this;
	}

	public function getRenderRowCallback()
	{
		return $this->rowRenderHandler;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::render()
	 */
	public function render($templateClass = null, $parentElement = null)
	{
		// if the saveHandler is set, call it now, to do the actual matrix save-to-storage
		if ($this->saveHandler) {
			// PHP gives: "'Serialization of 'Closure' is not allowed", so remove the assigned closure
			$svh = $this->saveHandler;
			$this->saveHandler = null;

			$rrh = $this->rowRenderHandler;
			$this->rowRenderHandler = null;

			call_user_func_array($svh, [$this]);
			$this->saveHandler = $svh;
			$this->rowRenderHandler = $rrh;
		}

		return parent::render($templateClass, $parentElement);
	}
}
