<?php namespace ProcessWire;

/**
 * An Inputfield for handling "submit" buttons
 * 
 * ProcessWire 3.x, Copyright 2015 by Ryan Cramer
 * https://processwire.com
 * License: MPL 2.0
 *
 */
class InputfieldSubmit extends Inputfield {

	public static function getModuleInfo() {
		return array(
			'title' => __('Submit', __FILE__), // Module Title
			'summary' => __('Form submit button', __FILE__), // Module Summary
			'version' => 102,
			'permanent' => true, 
			);
	}

	/**
	 * Additional dropdown actions added to the button
	 * 
	 * @var array
	 * 
	 */
	protected $dropdownItems = array();

	/**
	 * Init
	 * 
	 */
	public function init() {
		parent::init();
		$this->attr('type', 'submit'); 
		$this->attr('name', 'submit'); 
		$this->attr('value', $this->_('Submit')); // Standard submit button label
		$this->attr('class', 'ui-button ui-widget ui-state-default ui-corner-all');
		$this->skipLabel = Inputfield::skipLabelBlank; 
		
		// name of 'hidden' input that will receive the clicked dropdown item value
		$this->set('dropdownInputName', '_action_value');
	}

	/**
	 * Render the button
	 * 
	 * @return string
	 * 
	 */
	public function ___render() {
		$attrs  = $this->getAttributesString();
		$icon = $this->icon ? $this->sanitizer->name($this->icon) : '';
		$icon = $icon ? "<i class='fa fa-$icon'></i> " : '';
		$value = $this->entityEncode($this->attr('value'));
		$out = "\n<button $attrs><span class='ui-button-text'>$icon$value</span></button>";
		if(count($this->dropdownItems)) $out .= $this->renderDropdown();
		return $out; 
	}

	/**
	 * Render the dropdown to accompany the button
	 * 
	 * @return string
	 * 
	 */
	protected function renderDropdown() {

		if($this->wire('input')->get('modal') || $this->wire('session')->get('touch')) return '';
		
		$config = $this->wire('config');
		$file = $config->debug ? 'dropdown.js' : 'dropdown.min.js';
		$config->scripts->add($config->urls->InputfieldSubmit . $file);
		$numValues = 0;
		$dropdownID = $this->attr('id') . '_dropdown';
		$out = '';
		$out  = "<ul id='$dropdownID' class='pw-button-dropdown' data-my='left top' data-at='left bottom+1'>";

		foreach($this->dropdownItems as $item) {
			
			// entity encode all the labels in the dropdown
			foreach($item as $k => $v) {
				if($k == 'type') continue;
				$item[$k] = htmlentities($v, ENT_QUOTES, "UTF-8");
			}
			
			if($item['type'] == 'link') {
				// direct link
				$out .= "<li><a href='$item[value]'>";
			} else {
				// populate hidden input with value before submit
				$out .= "<li><a data-dropdown-value='$item[value]' href='#'>";
				$numValues++;
			}
			// icon to accompany label
			if($item['icon']) $out .= "<i class='fa fa-fw fa-$item[icon]'></i>";
					
			// label and finish item
			$out .= "$item[label]</a></li>";
		}
		
		$out .= "</ul>";
		
		if($numValues) {
			// there are values that can be populated to a hidden input
			$inputID = $dropdownID . '_value';
			$out = "<input type='hidden' name='{$this->dropdownInputName}' id='$inputID' value='' />" .
				str_replace("<ul ", "<ul data-dropdown-input='#$inputID' ", $out);
		}
	
		// script to initialize this dropdown immediately
		$out .= "<script>InputfieldSubmitDropdown.init('#{$this->id}')</script>";
		
		return $out; 
	}

	/**
	 * Process input
	 * 
	 * @param WireInputData $input
	 * @return $this
	 * 
	 */
	public function ___processInput(WireInputData $input) {
		// submit buttons don't need to process any input
		return $this; 
	}

	/**
	 * Add a dropdown item to this button
	 * 
	 * @param string string $type Either 'link' or 'value'
	 * @param string|int $value
	 * @param string $label
	 * @param string $icon
	 * 
	 */
	protected function addActionItem($type, $value, $label, $icon) {
		if(!$icon) $icon = 'angle-double-right';
		$this->dropdownItems[] = array(
			'type' => $type,
			'value' => $value,
			'label' => $label,
			'icon' => $icon,
		);
	}

	/**
	 * Add a dropdown action item that populates a new 'value' for the submit button
	 * 
	 * This also populates the value to $_POST['_action_value']
	 * 
	 * @param string $value Value to populate to hidden input when dropdown item is selected/clicked.
	 * @param string $label Text label to accompany the item
	 * @param string $icon Icon name (optional)
	 * 
	 */
	public function addActionValue($value, $label, $icon = '') {
		$this->addActionItem('value', $value, $label, $icon);
	}

	/**
	 * Add a dropdown action item that links to a URL
	 *
	 * @param string $url URL to link to
	 * @param string $label Text label to accompany the item
	 * @param string $icon Icon name (optional)
	 *
	 */
	public function addActionLink($url, $label, $icon = '') {
		$this->addActionItem('link', $url, $label, $icon);
	}
	
}
