<?php
/**
 * DatetimePickerHelper
 *
 * @author   Ryuji AMANO <ryuji@ryus.co.jp>
 * @link http://www.netcommons.org NetCommons Project
 * @license http://www.netcommons.org/license.txt NetCommons License
 */

/**
 * DatetimePickerHelper
 * User: ryuji
 * Date: 2016/03/09
 * Time: 16:04
 */

App::uses('AppHelper', 'View/Helper');

/**
 * Class DatetimePickerHelper
 * このHelperはNetCommonsFormから使われる前提で開発されています。Viewから直接使われることは想定していません。
 */
class DatetimePickerHelper extends AppHelper {

/**
 * Other helpers used by FormHelper
 *
 * @var array
 */
	public $helpers = array(
		'Form',
		'Html',
	);

/**
 * @var array datetimePickerでfromTo制約するフィールドリスト
 */
	protected $_datetimeLink = array();

/**
 * @var array FromTo制約を付加するfromフィールド名のサフィックス
 * ex) publish_start
 */
	protected $_fromFieldSuffix = [
		'start',
		'from',
	];

/**
 * @var array FromTo制約を付加するtoフィールド名のサフィックス
 * ex) publish_end
 */
	protected $_toFieldSuffix = [
		'end',
		'to',
	];

/**
 * @var bool スクリプトロード済みでtrue
 */
	protected static $_loadedScript = false;

/**
 * NetCommonsForm::inputから呼ばれる。
 * type=datetimeだったらdatetimipicker有効
 * options = array('datetimepicker')あればdatetimepickerスクリプトロード
 *
 * @param string $fieldName field name
 * @param array $inputOptions options
 * @return array options
 */
	public function beforeFormInput($fieldName, $inputOptions) {
		if (Hash::get($inputOptions, 'type') === 'datetime') {
			$inputOptions = $this->_makeDatetimeOptions($fieldName, $inputOptions);
		}
		if (Hash::get($inputOptions, 'datetimepicker') || in_array('datetimepicker', $inputOptions)) {
			$this->_loadDatetimePicker();
			$this->_setLinkFieldName($fieldName, $inputOptions);
		}
		return $inputOptions;
	}

/**
 * datetimePickerFromToLink()をコールするscriptBlock出力
 *
 * @return void
 */
	public function beforeFormEnd() {
		if ($this->_datetimeLink) {
			$script = '';
			foreach ($this->_datetimeLink as $fromTo) {
				if (isset($fromTo['from']) && isset($fromTo['to'])) {
					// from to のペア有り
					$fromId = $this->Form->domId($fromTo['from']);
					$toId = $this->Form->domId($fromTo['to']);

					$script .= "datetimePickerFromToLink('{$fromId}', '{$toId}');\n";
				}
			}
			if ($script) {
				$scriptBlock = '$(function () {';
				$scriptBlock .= $script;
				$scriptBlock .= '});';
				$this->Html->scriptBlock($scriptBlock, ['inline' => false]);
				$this->_loadJsFile();
			}
		}
	}

/**
 * datetimepickerを使うフィールドをFromTo制約候補に追加する
 *
 * @param string $fieldName FieldName
 * @param array $options Options
 * @return void
 */
	protected function _setLinkFieldName($fieldName, $options) {
		$matches = array();
		$pattern = '/^(.*)_(' . implode('|', $this->_fromFieldSuffix) . ')$/';
		if (preg_match($pattern, $fieldName, $matches)) {
			$this->_datetimeLink[$matches[1]]['from'] = $fieldName;
		}

		$matches = array();
		$pattern = '/^(.*)_(' . implode('|', $this->_toFieldSuffix) . ')$/';
		if (preg_match($pattern, $fieldName, $matches)) {
			$this->_datetimeLink[$matches[1]]['to'] = $fieldName;
		}
	}

/**
 * datimepicker用オプション指定
 *
 * @param string $fieldName フィールド名
 * @param array $options オプション
 * @return mixed
 */
	protected function _makeDatetimeOptions($fieldName, $options) {
		//$this->DatetimePicker->usePicker();
		// $filedNameにモデル名が入ってるかは不定
		if (strpos($fieldName, '.') === false) {
			$fieldName = $this->Form->defaultModel . '.' . $fieldName;
		}

		$options['type'] = 'text';
		$options['datetimepicker'] = true;
		$options['convert_timezone'] = Hash::get($options, 'convert_timezone', true);
		$options['data-toggle'] = 'dropdown';
		$options['childDiv']['style'] = 'position:relative;' . Hash::get($options, 'childDiv.style', '');
		$options['childDiv']['style'] .= Hash::get($options, 'childDiv.style', '');
		// ng-modelを指定してなくてもdatetimepickerが動くようにする
		if (!isset($options['ng-model'])) {
			$options['ng-model'] = 'NetCommonsFormDatetimePickerModel_' . str_replace('.', '_', $fieldName);
			//'ng-init' => 'hoge=\'2011-01-01\'',
			// value > request->data > default
			$value = '';
			if (isset($options['value'])) {
				$value = $options['value'];
			} elseif (Hash::check($this->request->data, $fieldName)) {
				$value = Hash::get($this->request->data, $fieldName);
			} elseif (isset($options['default'])) {
				$value = $options['default'];
			}

			if ($value !== false) {
				$netCommonsTime = new NetCommonsTime();
				$value = $netCommonsTime->toUserDatetime($value);
			}
			$options['value'] = $value;
			$options['ng-value'] = $options['ng-model'];

			$options['ng-init'] = sprintf(
				'%s=\'%s\'',
				$options['ng-model'],
				$value
			);
			return $options;
		}
		return $options;
	}

/**
 * datetimepickerに必要なJSとCSSを読みこみ
 *
 * @return void
 */
	protected function _loadDatetimePicker() {
		if (self::$_loadedScript === false) {
			$this->_View->element('NetCommons.load_datetimepicker');
			self::$_loadedScript = true;
		}
	}

/**
 * FromTo制約をDatetimePickerに設定する関数をscriptBlockへ
 *
 * @return void
 */
	protected function _loadJsFile() {
		$this->Html->script(
			'/net_commons/js/datetime_picker_from_to_link.js',
			array(
				'plugin' => false,
				'once' => true,
				'inline' => false
			)
			);
	}

}
