<?php
namespace Engine\Form\Input\Matrix;

class Cell extends \Engine\Form\Input\ElementAbstract
{
	/**
	 * Matrix column parent
	 * @var \Engine\Form\Input\Matrix
	 */
	protected $parent = null;

	/**
	 * List with children of column
	 */
	protected $assocNewName = null;

	/**
	 * Set column parent
	 * @param \Engine\Form\Input\Matrix $parent
	 * @return \Engine\Form\Input\Matrix\Cell
	 */
	public function setParent($parent)
	{
		$this->parent = $parent;
		return $this;
	}

	/**
	 * Add element to column
	 * @param \Engine\Form\Input\ElementAbstract $element
	 * @return \Engine\Form\Input\Matrix\Cell
	 */
	public function addElement(\Engine\Form\Input\ElementAbstract $element)
	{
		$this->childs[] = $element;
		return $this;
	}

	/**
	 * Populate new input name
	 * @return \Engine\Form\Input\Matrix\Cell
	 */
	protected function populateAssocNewNames($element)
	{
		if ($element instanceof \Engine\Form\Input\ElementAbstract) {
			$this->assocNewName[$element->getName()] = $element;
		}

		if ($element instanceof \Engine\Form\Input\ElementWithElements) {
			foreach ($element->getChilds() as $childs) {
				foreach ($childs as $chd) {
					$this->populateAssocNewNames($chd);
				}
			}
			return $this;
		}

		// populate input element name for childs also
		foreach ($element->getChilds() as $chd) {
			$this->populateAssocNewNames($chd);
		}
		return $this;
	}

	/**
	 * Update children name (eg service[0][text11])
	 * @param String $index
	 */
	public function updateElementsNames($index)
	{
		// fill in $this->assocNewName
		if ($this->assocNewName == null) {
			$this->assocNewName = [];
			foreach ($this->getChilds() as $element) {
				$this->populateAssocNewNames($element);
			}
		}

		// do the actual name change
		foreach ($this->assocNewName as $oldName=>$element) {
			$newName = sprintf("%s[%s][%s]", $this->parent->getName(), $index, $oldName);
			$element->setId(null);
			$element->setName($newName);
		}
		return $this;
	}

	/**
	 * Reset children names to original names
	 * @return \Engine\Form\Input\Matrix\Cell
	 */
	public function resetElementsNames()
	{
		// do the actual name change
		foreach ($this->assocNewName as $oldName=>$element) {
			$element->setName($oldName);
		}
		return $this;
	}

	/**
	 * Render matrix column(non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::render()
	 */
	public function render($templateClass = null, $parentElement = null)
	{
		if ($this->dontRender) {	// DO NOT use the getInvisible() function, as that may be overloaded and return a false negative (see the hidden text input class for an example)
			return '';	// old-style invisible item (from formRow) :)
		}

		if ($templateClass==null) {
			$templateClass = $this->class;
		}

		$this->loadTranslations($templateClass);

		$element = $this->getTemplateParams($templateClass, $parentElement);

		$return = "";

		// setup the disabled status for childs
		$stats = [
			'elements' => 0,
			'containers' => 0,
			'pseudo-containers' => 0,
			'callbackResults' => [],
		];
		$this->traverseTree(
			function($child, $self, $callbackParams) {
				$child->setDisabled($callbackParams['disabled']);
			},
			$stats,
			['disabled'=>$this->getDisabled(),]
		);

		foreach ($element['childs'] as $chd) {
			$return.= $chd->render();
		}

		return $return;
	}


	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::setValue()
	 */
	public function setValue($value)
	{
		if ($this->assocNewName) {
			foreach ($this->assocNewName as $inputName=>$element) {
				if (isset($value[$inputName])) {
					$element->setValue($value[$inputName]);
				}
				else {
					$element->setValue(null);
				}
			}
		}
		return $this;
	}
}
