<?php
namespace ModulesAbstract\Admin\Access;

abstract class View_Utils_FormAdmin extends \App\Mvc\View_Utils_FormAbstract
{
	/**
	 * The current access class
	 */
	protected $currentAccess = null;

	/**
	 * Assign the object that handles current accessible sections/options
	 * @return \ModulesAbstract\Admin\Access\View_Utils_FormAdmin
	 */
	public function setCurrentAccess($currentAccess)
	{
		$this->currentAccess = $currentAccess;
		return $this;
	}


	/**
	 * Creates the form for department insert/update.
	 * @see \App\Mvc\View_Utils_FormAbstract::getForm()
	 */
	public function getForm()
	{
		$form = \Engine\Form\General::create();

		$searchContainer = \Engine\Form\Container\Vl::create();
		$form->addContainer($searchContainer);

		$searchField = \Engine\Form\Input\Text::create('', '', '');
		$searchField->setPlaceholder($this->lang['index']['search']['placeholder']);
		$searchField->setId('search');
		$searchField->getOptionsMenu()->append(\App\Mvc\View\Utils\RowOptions\Option\Option::create('searchEverything_prevMatch')
			->setIcon('moveUp')
			->setDisabled()
			->setDescription($this->lang['index']['search']['prevMatch'])
			->setJsCallback("MVC.AdminAccess.searchEverything_prevMatch()")
		);
		$searchField->getOptionsMenu()->append(\App\Mvc\View\Utils\RowOptions\Option\Option::create('searchEverything_nextMatch')
			->setIcon('moveDown')
			->setDisabled()
			->setDescription($this->lang['index']['search']['nextMatch'])
			->setJsCallback("MVC.AdminAccess.searchEverything_nextMatch()")
		);
		$searchContainer->addElement($searchField);

		$formColumns = new \Engine\Form\Container\Columns();
		$form->addContainer($formColumns);

		$cLeft = \Engine\Form\Container\Fieldset::create($this->lang['index']['col1']['fieldset']['title']);
		$formColumns->addContainer($cLeft);

		$cRight = \Engine\Form\Container\Fieldset::create($this->lang['index']['col2']['fieldset']['title']);
		$formColumns->addContainer($cRight);

		// sections
		$sectionsTree = \Engine\Form\Container\Tree::create('');
		$cLeft->addContainer($sectionsTree);
		$sectionsTree->setStyle('asElement', false);
		$sectionsTree->setName('sections');

		$referenceAccess = \App\UserAccess\ReferenceUserAccess::getInstance()->getAccessTree();

		$this->importMenuStructureIntoTreeContainer($referenceAccess, $sectionsTree, $sectionsTree);

		// options
		$this->importMenuOptionsAsFieldsetContainers($referenceAccess, $cRight, [
			'depth' =>   0,
			'parents' => [],
		]);

		// submit button
		$form->addElement(new \Engine\Form\Input\Hidden('', $this->submitButtonName, 1));
		return $form;
	}


	/**
	 * Import menu tree structure into the checkboxes tree container
	 * @param array $tree
	 * @param \Engine\Form\Container\Tree $containerTree
	 * @param \Engine\Form\Container\Tree $treeRoot
	 */
	private function importMenuStructureIntoTreeContainer(array $tree, \Engine\Form\Container\Tree $containerTree, \Engine\Form\Container\Tree $treeRoot)
	{
		foreach ($tree as $child) {
			$element = \Engine\Form\Input\Checkbox::create(($child['label']?:$child['id']), $treeRoot->getName()."[{$child['id']}]", $this->currentAccess->hasAccessToSection($child['id']));	// the childSensitive items get their values from childs
			$element->setStyle('renderMode', 'inherit');
			$element->setStyle('highlight', 'current');

			if ($child['accessLevel']=='always') {
				$element->setDisabled();
			}

			$newInput = $containerTree->addElement($element);

			if ($child['options']) {
				$newInput->setCustomHTML(sprintf("<a href='#;' class='showOptions' tooltip='%s' data-target='%s' disabled='disabled'><var class='icon-add' data-icon='add'></var></a>", $this->lang['index']['col1']['showOptions']['tooltip'], $this->createFieldsetId($child['id'])), "pre");
			}
			else {
				$newInput->setCustomHTML(sprintf("<a href='#;' class='showOptions disabled' data-target='%s' disabled='disabled'><var class='icon-add' data-icon='add'></var></a>", $this->createFieldsetId($child['id'])), "pre");
			}

			if ($child['children']) {
				$newContainer = $newInput->addContainer($containerTree::create(''));
				$element->setStyle('highlight', 'current');

				$element->setExtraInfo('childController', true);	// clicking this item will cause all childs to also get "clicked & checked"
				$element->setExtraInfo('childSensitive', false);	// clicking all its childs, will cause it to also get "clicked & checked". This will render the input to be "automatic" instead, and the user cant control it

				$this->importMenuStructureIntoTreeContainer($child['children'], $newContainer, $treeRoot);
			}
		}
	}


	/**
	 * Import menu tree options into fieldsets
	 * @param array $tree
	 * @param \Engine\Form\Container\GeneralAbstract $cRight
	 * @throws \Exception
	 */
	private function importMenuOptionsAsFieldsetContainers(array $tree, \Engine\Form\Container\GeneralAbstract $cRight, $options)
	{
		foreach ($tree as $child) {
			if ($child['options']) {
				$fieldset = \Engine\Form\Container\Fieldset::create($child['label']);
				$fieldset->setId($this->createFieldsetId($child['id']));
				$cRight->addContainer($fieldset);

				foreach ($child['options'] as $opt) {
					switch ($opt['type']) {
						case 'checkbox':
							$element = \Engine\Form\Input\Checkbox::create(($opt['label']?:$opt['id']), "options[{$opt['id']}]", $this->currentAccess->hasAccessToOption($opt['id']));
							if ($opt['details']) {
								$element->setDetails($opt['details']);
							}
							$fieldset->addElement($element);
						break;

						case 'checkboxes':
							$element = \Engine\Form\Input\Checkboxes::create(($opt['label']?:$opt['id']), "options[{$opt['id']}]", (array)$this->currentAccess->getAccessOptionValue($opt['id']), $opt['possibleValuesTranslated']);
							$element->setStyle('renderMode', 'block');
							if ($opt['details']) {
								$element->setDetails($opt['details']);
							}
							$fieldset->addElement($element);
						break;

						case 'select':
							$element = \Engine\Form\Input\Select::create(($opt['label']?:$opt['id']), "options[{$opt['id']}]", $this->currentAccess->getAccessOptionValue($opt['id']), array_merge(['' => '-', ], $opt['possibleValuesTranslated']));
							if ($opt['details']) {
								$element->setDetails($opt['details']);
							}
							$element->setStyle('width', 150);
							$fieldset->addElement($element);
						break;

						default:
							throw new \Exception(sprintf("Invalid option type: '%s' for option '%s'. Please investigate", $opt['type'], $opt['id']));
					}
				}
			}

			if ($child['children']) {
				$o = $options;
				$o['depth']++;
				$o['parents'][]= $child;
				$this->importMenuOptionsAsFieldsetContainers($child['children'], $cRight, $o);
			}
		}
	}

	private function createFieldsetId($sectionId)
	{
		return sprintf("containerForOptions_%s", preg_replace("/[^a-zA-Z0-9_]/", "_", $sectionId));
	}
}
