<?php
/**
 * --------------------------------------------------------------------------------------------
 * VP Custom Filter Module - Joomla! 3 Module for VirtueMart 3.0
 * --------------------------------------------------------------------------------------------
 * @package    VP Custom Filter Module
 * @author     Abhishek Das
 * @copyright  Copyright (C) 2012-2021 VirtuePlanet Services LLP. All rights reserved.
 * @license    GNU General Public License version 2. http://www.gnu.org/licenses/gpl-2.0.html
 * @link       http://www.virtueplanet.com
 * --------------------------------------------------------------------------------------------
*/
defined('_JEXEC') or die;

JFormHelper::loadFieldClass('list');

/**
 * Form Field class for the Joomla Platform.
 * Displays options as a list of check boxes.
 * Multiselect may be forced to be true.
 *
 * @see    JFormFieldCheckbox
 * @since  11.1
 */
class JFormFieldVpcfbutton extends JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  11.1
	 */
	protected $type = 'Vpcfbutton';

	/**
	 * Flag to tell the field to always be in multiple values mode.
	 *
	 * @var    boolean
	 * @since  11.1
	 */
	protected $forceMultiple = true;

	/**
	 * The comma seprated list of checked checkboxes value.
	 *
	 * @var    mixed
	 * @since  3.2
	 */
	public $checkedOptions;

	/**
	 * Method to get certain otherwise inaccessible properties from the form field object.
	 *
	 * @param   string  $name  The property name for which to the the value.
	 *
	 * @return  mixed  The property value or null.
	 *
	 * @since   3.2
	 */
	public function __get($name)
	{
		switch ($name)
		{
			case 'forceMultiple':
			case 'checkedOptions':
			case 'customfield_type':
			case 'is_list':
			case 'display_style':
			case 'max_height':
			case 'show_product_count':
			case 'id_prefix':
				return $this->$name;
		}

		return parent::__get($name);
	}

	/**
	 * Method to set certain otherwise inaccessible properties of the form field object.
	 *
	 * @param   string  $name   The property name for which to the the value.
	 * @param   mixed   $value  The value of the property.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public function __set($name, $value)
	{
		switch ($name)
		{
			case 'checkedOptions':
				$this->checkedOptions = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to get the radio button field input markup.
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   11.1
	 */
	protected function getInput()
	{
		$xmlOptions = $this->element->xpath('option');

		if(empty($xmlOptions))
		{
			return '';
		}
		
		$doc = JFactory::getDocument();
		
		if(!empty($this->element['id_prefix']))
		{
			$this->id = $this->element['id_prefix'] . '_' . $this->id;
		}
		
		$fieldname = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname);
		$options   = array();
		$hasValue  = (isset($this->value) && !empty($this->value));

		// If a value has been stored, use it. Otherwise, use the defaults.
		$checkedOptions = $hasValue ? $this->value : $this->checkedOptions;
		$checkedOptions = (array) $checkedOptions;
		
		$showProductCount = isset($this->element['show_product_count']) ? $this->element['show_product_count'] : '0';
		$showProductCount = ($showProductCount == 'true' || $showProductCount == 'checked' || $showProductCount == '1');
		
		$showQuickSearch = isset($this->element['show_quicksearch']) ? $this->element['show_quicksearch'] : '0';
		$showQuickSearch = ($showQuickSearch == 'true' || $showQuickSearch == 'checked' || $showQuickSearch == '1');
		
		$showClear = isset($this->element['show_clear']) ? $this->element['show_clear'] : '0';
		$showClear = ($showClear == 'true' || $showClear == '1');
		
		$clear_url = isset($this->element['clear_url']) ? $this->element['clear_url'] : '';
		
		$maxHeight = isset($this->element['max_height']) ? (int) $this->element['max_height'] : 0;
		
		$nofollow = isset($this->element['nofollow']) ? (int) $this->element['nofollow'] : 0;
		
		$displayStyle = isset($this->element['display_style']) ? (string) $this->element['display_style'] : 'checkbox';
		$inputType    = ($displayStyle == 'url') ? 'checkbox' : $displayStyle;
		
		$hiddenFormat = '<input type="hidden" name="%1$s" value="0" data-vpfcnone="true" disabled />';
		$format       = '<input type="' . $inputType . '" id="%1$s" name="%2$s" value="%3$s" %4$s />';
		
		$html = array();
		
		$html[] = '<fieldset id="' . $this->id . '" class="' . trim($this->class . ' vpcf-' . $displayStyle . '-buttons') . '"' .
		          ($this->required ? ' required aria-required="true"' : '') .
		          ($this->autofocus ? ' autofocus' : '') . '>';
		
		if($showClear && !empty($clear_url))
		{
			$clearHtml  = '<div class="vpcf-clear-cont">';
			$clearHtml .= '<a href="' . htmlspecialchars($clear_url, ENT_COMPAT, 'UTF-8') . '" data-vpcfurl="true"' . ($nofollow ? ' rel="nofollow"' : '') . '><span class="vpcf-clearmark">&#10005;</span>' . JText::_('PLG_SYSTEM_VPFRAMEWORK_CLEAR_FILTER') . '</a>';
			$clearHtml .= '</div>';
			
			$html['clear'] = $clearHtml;
		}
		
		if($showQuickSearch)
		{
			$html['search'] = '<input type="text" id="search_' . $this->id . '" class="vpcf-quicksearch form-control input-sm" placeholder="' . JText::_('PLG_SYSTEM_VPFRAMEWORK_FILTER_QUICKSEARCH') . '" autocomplete="off" value="" />';
		}
		
		$html[] = sprintf($hiddenFormat, $this->name);
		
		$html[] = '<div id="vpcf_options_' . $this->id . '" class="vpcf-options">';
		
		if($maxHeight > 0)
		{
			$doc->addStyleDeclaration('#vpcf_options_' . $this->id . '{max-height:' . $maxHeight . 'px;}');
		}
		
		$i = 0;
		$allDisabled = true;
		$hasChecked = false;
		
		foreach ($xmlOptions as $option)
		{
			$value = (string) $option['value'];
			$text = trim((string) $option) ? trim((string) $option) : $value;

			$disabled = (string) $option['disabled'];
			$disabled = ($disabled == 'true' || $disabled == 'disabled' || $disabled == '1');
			$disabled = $disabled || ($this->readonly && $value != $this->value);

			$checked = (string) $option['checked'];
			$checked = ($checked == 'true' || $checked == 'checked' || $checked == '1');
			
			$hide_name = (string) $option['hide_name'];
			$hide_name = ($hide_name == 'true' || $hide_name == 'checked' || $hide_name == '1');

			$selected = (string) $option['selected'];
			$selected = ($selected == 'true' || $selected == 'selected' || $selected == '1');
			
			$class = (string) $option['class'];
			$class = !empty($class) ? $class : 'btn btn-fieldvalue';
			
			$url = (string) $option['url'];

			$product_count = (string) $option['product_count'];
			
			if($showProductCount && empty($product_count))
			{
				$disabled = true;
			}
			
			$tmp = array(
					'value'    => $value,
					'text'     => JText::alt($text, $fieldname),
					'disable'  => $disabled,
					'class'    => $class,
					'selected' => ($checked || $selected),
					'checked'  => ($checked || $selected),
					'url'      => htmlspecialchars($url, ENT_COMPAT, 'UTF-8'),
					'product_count' => $product_count,
					'hide_name' => $hide_name
				);

			// Set some event handler attributes. But really, should be using unobtrusive js.
			$tmp['onclick']  = (string) $option['onclick'];
			$tmp['onchange']  = (string) $option['onchange'];

			// Add the option object to the result set.
			$option = (object) $tmp;
			
			// Initialize some option attributes.
			$checked = in_array((string) $option->value, $checkedOptions) && !$disabled ? 'checked' : '';

			// In case there is no stored value, use the option's default state.
			$checked     = (!$hasValue && $option->checked && !$disabled) ? 'checked' : $checked;
			
			$disabled    = !empty($option->disable) || $disabled ? 'disabled' : '';

			// Initialize some JavaScript option attributes.
			$onclick  = !empty($option->onclick) ? 'onclick="' . $option->onclick . '"' : '';
			$onchange = !empty($option->onchange) ? 'onchange="' . $option->onchange . '"' : '';

			$oid        = $this->id . $i;
			$value      = htmlspecialchars($option->value, ENT_COMPAT, 'UTF-8');
			$attributes = array_filter(array($checked, $disabled, $onchange, $onclick));
			
			if(!empty($checked))
			{
				$hasChecked = true;
			}
			
			if($option->hide_name)
			{
				$optionText = '<span class="sr-only">' . $option->text . '</span>';
			}
			else
			{
				$optionText = $option->text;
			}
			
			$title = $option->text;
			
			if($showProductCount && $option->product_count > 0)
			{
				$title .= '&nbsp;(' . (int) $option->product_count . ')';
			}

			$html[] = '<label for="' . $oid . '">';
			$html[] = sprintf($format, $oid, $this->name, $value, implode(' ', $attributes));
			
			if(!empty($option->url) && !$disabled)
			{
				$html[] = '<a href="' . $option->url . '" class="' . trim($option->class . ' vpcf-option-name hasTooltip') . '" title="' . $title . '" data-vpcfurl="true"' . ($nofollow ? ' rel="nofollow"' : '') . '>';
				$html[] = $optionText;
				$html[] = '</a>';
			}
			else
			{
				$html[] = $disabled ? '<span class="' . trim($option->class . ' vpcf-option-name hasTooltip disabled') . '" title="' . $title . '">' . $optionText . '</span>' : $optionText;
			}
			
			if(!$disabled)
			{
				$allDisabled = false;
			}
			
			$html[] = '</label>';
			
			$i++;
		}
		
		$html[] = '</div>';
		$html[] = '</fieldset>';
		
		if($allDisabled && $showQuickSearch)
		{
			unset($html['search']);
		}
		
		if($allDisabled || !$hasChecked)
		{
			unset($html['clear']);
		}
		
		return implode($html);
	}
	
	/**
	 * Method to attach a JForm object to the field.
	 *
	 * @param   SimpleXMLElement  $element  The SimpleXMLElement object representing the `<field>` tag for the form field object.
	 * @param   mixed             $value    The form field value to validate.
	 * @param   string            $group    The field name group control value. This acts as as an array container for the field.
	 *                                      For example if the field has name="foo" and the group value is set to "bar" then the
	 *                                      full field name would end up being "bar[foo]".
	 *
	 * @return  boolean  True on success.
	 *
	 * @see     JFormField::setup()
	 * @since   3.2
	 */
	public function setup(SimpleXMLElement $element, $value, $group = null)
	{
		$return = parent::setup($element, $value, $group);

		if ($return)
		{
			$this->checkedOptions = (string) $this->element['checked'];
		}

		return $return;
	}
}
