<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package fusionLib
 * @copyright Copyright (c) 2015 fusionLib. All rights reserved.
 * @link http://fusionlib.com
 */

/**
 * flFormElementTextSuggest Class
 *
 * Single line text input form element.
 *
 * @package fusionLib
 */
class flFormElementTextSuggest extends flFormElementText {

	/**
	 * Array of options.
	 *
	 * @var array
	 */
	protected $options = null;

	/**
	 * The file to load options from.
	 *
	 * @var string
	 */
	protected $file = null;

	/**
	 *	Construct the element.
	 *
	 *	@param flForm $form The form the element will be used with or null if not using flForm
	 *	@param string $name The name of the element.
	 *	@param string $default The default value of the element.
	 */
	function __construct($form, $name, $default = null) {
		parent::__construct($form, $name, $default);
		$this->autocomplete = 'off';
	}

	/**
	 * Set the options from an array.
	 *
	 * @param array $options The array of options.
	 */
	function setOptions($options) {
		$this->options = $options;
	}

	/**
	 * Set the file to load options from, each line is a single option.
	 *
	 * @param string $file The file to load the options from.
	 */
	function setOptionsFile($file) {
		$this->file = $file;
	}

	/**
	 * Draw the element.
	 *
	 * @return string Element HTML.
	 */
	function render() {

		// If AJAX request then grab it
		$request = $this->form->getRequest();
		if ($request->isXmlHttpRequest() && $request->hasPost('suggest_q') && $request->hasPost('suggest_n') && $request->getPost('suggest_n') == $this->name) {

			// Scan the possible options for matches
			$q = $request->getPost('suggest_q', '');
			$selected = array();
			if(strlen($q) >= 3) {
				if($this->file && ($fp = @fopen($this->file, 'r'))) {
					while ($line = fgets($fp, 4096)) {
						if ($line[0] != '#' && stripos($line, $q) !== false)
							$selected[] = fusionLib::htmlChars(trim($line));
					}
					fclose($fp);
				}
				else if($this->options) {
					foreach ($this->options as $o) {
						if (stripos($o, $q) !== false)
							$selected[] = fusionLib::htmlChars($o);
					}
				}
			}

			// Send AJAX response with matched options
			$response = new flResponse($request);
			$response->setContentType('application/json')
				->noCache()
				->setBody(json_encode($selected))
				->sendResponse();
			die;
		}

		$html = "<input type=\"text\" id=\"$this->name\" name=\"$this->name\" value=\"" . $this->_getValueEscaped() . '"';
		if($this->maxLength !== null) $html .= " maxlength=\"$this->maxLength\"";
		return $html . $this->attribHTML() . " />\n<div class=\"suggestwidget\"><div id=\"{$this->name}-suggestions\" class=\"suggestwidgetpopup hide\"></div></div>";
	}

	/**
	 * Get the JavaScript for the element if any.
	 *
	 * @return string The string holding the JavaScript for the element.
	 */
	function getJavaScript() {
		$js = "function updateSuggestions{$this->name}() {
	var q = \$fl(this).val();
	if(q.length >= 3) {
		// Do the AJAX call
		\$fl.ajax(\$fl('#" . $this->form->getName() . "')[0].action, {
			type: 'post',
			timeout: 3000,
			async: true,
			success: function(d) {
				var html = '',
					suggest = \$fl('#{$this->name}-suggestions');
				for(var i=0;i<d.length;i++)
					html += '<li>' + d[i] + '</li>'
				if(html.length) {
					html = '<ul>' + html + '</ul>';
					suggest.html(html).removeClass('hide');
				}
				else {
					suggest.html('').addClass('hide')
				}
			},
			data: { suggest_n: '$this->name', suggest_q: q }
		});
	}
	else
		\$fl('#{$this->name}-suggestions').html('').addClass('hide');
}
\$fl('#{$this->name}')
	.bind('keyup', updateSuggestions{$this->name})
	.bind('focus', updateSuggestions{$this->name})
	.bind('blur', function() {
		setTimeout(function() {
			\$fl('#{$this->name}-suggestions').addClass('hide');
		}, 200);
	});
\$fl('#{$this->name}-suggestions').bind('click', function(e) {
	\$fl('#{$this->name}').val(\$fl(e.target).text()).focus();
	e.preventDefault();
	return false;
});
";
		return parent::getJavaScript() . $js;
	}
}
