<?php

namespace Engine\Form\Input;

/**
 * Form input for date interval (start-end dates)
 * @author Lucian
 */
class DateInterval extends \Engine\Form\Input\ElementAbstract
{
	protected $class = "dateInterval";	// this decides what CSS classes are used, and what TPL file is handlig the render() method for this class

	/**
	 * The internal date objects
	 * @var \Engine\Form\Input\Date
	 */
	protected $date1 = null;

	/**
	 * The internal date objects
	 * @var \Engine\Form\Input\Date
	 */
	protected $date2 = null;

	public function __construct($label=null, $name=null, $value=[]){
		parent::__construct($label, null, null);

		if(!$value)$value = [];	// to avoid PHP errors when calling reset(null) / end(null)

		// setup the internal date objects
		$this->date1 = \Engine\Form\Input\Date::create(null, "{$name}[start]", null);
		$this->date2 = \Engine\Form\Input\Date::create(null, "{$name}[end]", null);

		if(isset($value['start']) || isset($value['end'])){
			$this->date1->setValue($value['start']);
			$this->date2->setValue($value['end']);
		}
		else{
			$this->date1->setValue(reset($value));
			$this->date2->setValue(next($value));
		}

		$this->setName($name);
	}

	/**
	 * Get the start date
	 * @return String
	 */
	public function getStart(){ return $this->date1->getValue(); }

	/**
	 * Set the start date
	 */
	public function setStart($date){ $this->date1->setValue($date); return $this; }

	/**
	 * Get the end date
	 * @return String
	 */
	public function getEnd(){ return $this->date2->getValue(); }

	/**
	 * Set the start date
	 */
	public function setEnd($date){ $this->date2->setValue($date); return $this; }

	/**
	 * Set the start and end date
	 */
	public function setValue($interval){

		if(isset($interval['start']) || isset($interval['end'])){
			$this->date1->setValue($interval['start']);
			$this->date2->setValue($interval['end']);
		}
		elseif($interval){
			$this->date1->setValue(reset($interval));
			$this->date2->setValue(next($interval));
		}

		return $this;
	}

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

		if($this->disabled){
			$this->date1->setDisabled($this->disabled);
			$this->date2->setDisabled($this->disabled);
		}

		if ($this->getInvisible()){
			$this->date1->setInvisible($this->getInvisible());
			$this->date2->setInvisible($this->getInvisible());
		}

		$params['date1'] = $this->date1;
		$params['date2'] = $this->date2;

		return $params;
	}


	/**
	 * [validator] Setup a parameter to be sent down to the validator
	 * @param String $key
	 * @param Mixed $value
	 */
	public function setValidatorParam($key, $value){
		switch($key){
			case 'maxDifference':
				// max difference between date1 & date2 in days
				$this->settings['maxDifference'] = (int)$value;
				return $this;
			break;

			case 'denyOpenIntervals':
				// always require some kind of date in the inputs
				$this->settings['denyOpenIntervals'] = (bool)$value;
				return $this;
			break;

			case 'correlateValues':
				// date1 should not get bigger than date2
				// date2 should not get smaller than date1
				$this->date1->setValidatorParam('maxValueElement', $this->date2->getId());
				$this->date2->setValidatorParam('minValueElement', $this->date1->getId());
				return $this;
			break;

			case 'showDifference':
				$this->settings['showDifference'] = $value;
				return $this;
			break;

			case 'mandatory':
				$this->date1->setMandatory($value);
				$this->date2->setMandatory($value);
				return $this;
			break;

			case 'minValue':
			case 'maxValue':
				$this->date1->setValidatorParam($key, $value);
				$this->date2->setValidatorParam($key, $value);
				return $this;
			break;

			case 'type':
				$this->date1->setValidatorParam($key, $value);
				$this->date2->setValidatorParam($key, $value);
				return $this;
			break;
		}

		return parent::setValidatorParam($key, $value);
	}


	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::addEvent()
	 */
	public function addEvent($event, $jsCallback){
		switch($event){
			case 'onChange':
				$this->date1->addEvent($event, $jsCallback);
				$this->date2->addEvent($event, $jsCallback);
				return $this;
			break;
		}

		return parent::addEvent($event, $jsCallback);
	}

	/**
	 * Set the element name
	 * @param String $name
	 */
	public function setName($name){

		$this->date1->setName("{$name}[start]");
		$this->date2->setName("{$name}[end]");

		$this->name = $name;

		return $this;
	}

	/**
	 * Set the element name
	 * @param String $name
	 */
	public function setId($ids){
		// check input
		if (!is_array($ids) or count($ids)!=2) {
			throw new \Exception('`Date interval` field id can only be set as an array.');
		}

		if(isset($ids['start']) || isset($ids['end'])){
			$this->date1->setId($ids['start']);
			$this->date2->setId($ids['end']);
		}
		elseif($ids){
			$this->date1->setId(reset($ids));
			$this->date2->setId(next($ids));
		}
		return $this;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::getValue()
	 */
	public function getValue()
	{
		return [
			'start' => 	$this->date1->getValue(),
			'end' => 	$this->date2->getValue(),
		];
	}

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

		\App\Loader_Lang::getInstance()->loadAppFile("_customLoad/formField/inputs/DateInterval.lang.php");
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::renderFilterOverview()
	 */
	public function renderFilterOverview()
	{
		$this->loadTranslations();

		$inputLang = \App\Loader_Lang::getInstance()->getSection("Engine/Form/Input/DateInterval");

		if ($this->date1->getValue() && $this->date2->getValue()) {
			return sprintf("%s - %s",
				\Engine\DateTime::createFromIsoDate($this->date1->getValue())->formatDateStd(),
				\Engine\DateTime::createFromIsoDate($this->date2->getValue())->formatDateStd()
			);
		}
		elseif ($this->date1->getValue()) {
			return sprintf($inputLang['after'],
				\Engine\DateTime::createFromIsoDate($this->date1->getValue())->formatDateStd()
			);
		}
		elseif ($this->date2->getValue()) {
			return sprintf($inputLang['before'],
				\Engine\DateTime::createFromIsoDate($this->date2->getValue())->formatDateStd()
			);
		}
		else {
			return $inputLang['anytime'];
		}
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::getDefaultValue()
	 */
	public function getDefaultValue()
	{
		$this->defaultValue = [
			'start' => 	(string)$this->date1->getDefaultValue(),
			'end' => 	(string)$this->date2->getDefaultValue(),
		];
		return $this->defaultValue;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::setDefault()
	 */
	public function setDefault($default = [])
	{
		$this->date1->setDefault($default['start']);
		$this->date2->setDefault($default['end']);
		return $this;
	}

	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::setDefaultValue()
	 */
	public function setDefaultValue($value)
	{
		$this->date1->setDefaultValue($value['start']);
		$this->date2->setDefaultValue($value['end']);
		return $this;
	}


	/**
	 * (non-PHPdoc)
	 * @see \Engine\Form\Input\ElementAbstract::shouldRenderOverview()
	 */
	public function shouldRenderOverview()
	{
		$v1 = $this->getValue();
		$v2 = $this->getDefaultValue();
		return ($v1['start'] != $v2['start']) || ($v1['end'] != $v2['end']);
	}
}
