<?php
namespace App\Mvc\View;

/**
 * Trait used by Popup/FormAbstract & Window/FormAbstract
 */
trait FormTrait
{

    /**
	 * The class name which generates the form for the current action.
	 * @var String
	 */
	protected $formClassName='View_Utils_FormAdmin';

	/**
	 * Return true/false if popup has options associated
	 * @var Boolean
	 */
	protected $hasOptions = false;

    /**
	 * Returns the form object.
	 * @param Array $formValues - the form fields values
	 * @return \Engine\Form\General - the form object
	 */
	protected function render_getForm($formValues)
	{
		// check if the formClassName was set
		if (!$this->formClassName) {
			throw new \Exception('You did not set the `formClassName` class attribute for the class `'.get_called_class().'`.');
		}

		// the current ns
		$namespace = getClassNamespace(get_called_class());

		$className =  "\\{$namespace}\\{$this->formClassName}";
		$formMngObj = new $className($this->controller);

		if ($formValues!==null) {
			$formMngObj->setValues($formValues);
		}

		// force the submit button name
		if ($this->input['formSubmitButtonName']) {
			$formMngObj->setSubmitButtonName($this->input['formSubmitButtonName']);
		}

		$form = $formMngObj->getForm();

		if ($formValues && $this->input['formSubmitButtonName'] && !($formValues[$this->input['formSubmitButtonName']]??null)) {
			// all forms should have the focus set on the first input
			$form->setFocus(true);
		}

		return $form;
	}

    /**
	 * (non-PHPdoc)
	 * @see \App\Mvc\ViewAbstract::assignMessages()
	 */
	protected function assignMessages(?\Engine\Form\General $form, \MessageStack $showMessage) // TODO: [nonMVC] - should this acrtually be used?
	{
		if ($this->messagesCollector) {
			if (!$form) {
				$showMessage->addFromMessageCollector($this->messagesCollector);
				return;
			}

			foreach ($this->messagesCollector->getMessages() as $msg) {
				// the message will be attached to the corresponding field in the form
				$element = null;
				$container = null;

				if ($form && $msg->getField()) {
					// search the element in the form
					list($element, $container) = $form->findFirstElementAndContainerByElementName($msg->getField());
					if ($element && get_class($element)=='Engine\Form\Input\Hidden') {
						$element = null;
						$container = null;
					}
				}

				if ($element) {
					// add the message to the specific element
					$element->addMessage($msg->getType(), $msg->getText());

                    // go up the container parents tree and mark all parents as not collapsed, in order to make the element visible in the interface
					if ($container) {
						do {
							if ($container->getCollapsible()) {
								$container->setCollapsed(false);
							}

							$container = $container->getParent();
						} while($container);
					}
				}
				// the element wasn't found, assign the message into the main form
				else {

					$text = $msg->getText();
					if ($msg->getField()) {
						$text .= sprintf(' (%s)', $msg->getField());
					}

					if ($form) {
						$form->getMessagesObj()->Set($msg->getType(), $text);
					}
					else {
						$showMessage->getMessagesObj()->Set($msg->getType(), $text);
					}
				}
			}
		}
	}

    /**
	 * Set popup options
	 * @param \App\Mvc\View\Utils\RowOptions\Container\Simple $options
	 */
	public function getOptions(\App\Mvc\View\Utils\RowOptions\Container\Simple $options)
	{
	}

	/**
	 * Return if popup has options associated
	 * @return boolean
	 */
	public function hasOptions()
	{
		return $this->hasOptions;
	}
}
