<?php namespace ProcessWire;

/**
 * ProcessWire Radios Inputfield
 * 
 * ProcessWire 3.x, Copyright 2021 by Ryan Cramer
 * https://processwire.com
 * 
 * @property int $optionColumns Number of columns to display radios in, or 0 for vertical stacked, or 1 for inline (default=0)
 * @property string $optionWidth Alternative to optionColumns, specify option width like '222px', '22em', etc. or '1' for auto. 3.0.184+
 * 
 */

class InputfieldRadios extends InputfieldSelect {

	public static function getModuleInfo() {
		return array(
			'title' => __('Radio Buttons', __FILE__), // Module Title
			'summary' => __('Radio buttons for selection of a single item', __FILE__), // Module Summary
			'version' => 106,
			'permanent' => true, 
		);
	}

	public function init() {
		$this->set('optionColumns', 0);
		$this->set('optionWidth', ''); 
		parent::init();
	}

	public function ___render() {	
	
		$sanitizer = $this->wire()->sanitizer;

		$defaults = array(
			'wbr' => false, 
			'noSelectLabels' => true,
		);
		
		$settings = $this->wire()->config->get('InputfieldRadios');
		$settings = is_array($settings) ? array_merge($defaults, $settings) : $defaults;
		
		$this->checkDefaultValue();
		$inline = false;
		$columns = (int) $this->optionColumns;
		if($columns === 1) $inline = true; 
		$options = $this->getOptions();
		$optionWidth = $this->getOptionWidthCSS($this->optionWidth, $options);
		$entityEncodeLabels = $this->getSetting('entityEncodeText') === false ? false : true;
		$liAttr = '';

		if($optionWidth) {
			$liAttr = " style='width:$optionWidth'";
			$out = "<ul class='InputfieldRadiosWidth'>"; 

		} else if($columns) {
			if(count($options) >= $columns && !$inline) {
				$liWidth = round(100 / $columns)-1;  // 1% padding-right added from stylesheet
				$liAttr = " style='width: {$liWidth}%;'";
				$ulClass = 'InputfieldRadiosColumns';
			} else {
				// don't bother setting a width, we will let them float where they want instead
				$ulClass = 'InputfieldRadiosFloated';
			}
			$out = "<ul class='$ulClass pw-clearfix ui-helper-clearfix'>";

		} else {
			$out = "<ul class='InputfieldRadiosStacked'>"; 
		}

		foreach($options as $key => $value) {
			
			$checked = '';

			$id = $sanitizer->name($key); 
			if(!strlen(trim($id, '_'))) $id = trim(base64_encode($key), '=/.');
			$id = $this->id . '_' . $id;
			$attrs = $this->getOptionAttributes($key);
			
			$inputClass = trim($this->attr('class'));
			if(isset($attrs['input.class'])) $inputClass .= ' ' . $attrs['input.class'];
			
			if($this->isOptionSelected($key)) $checked = " checked='checked'";
			$disabled = empty($attrs['disabled']) ? "" : " disabled='disabled'";
			
			unset($attrs['selected'], $attrs['checked'], $attrs['disabled'], $attrs['input.class']); 
			
			$textClass = $settings['noSelectLabels'] ? 'pw-no-select' : '';
			if($disabled) $textClass .= ' ui-state-disabled';
			
			$attrs = $this->getOptionAttributesString($attrs);
			if($attrs) $attrs = ' ' . $attrs;
			
			$label = $settings['wbr'] ? str_replace(' ', ' !wbr!', $value) : $value;
			if($entityEncodeLabels) $label = $this->entityEncode($label, Inputfield::textFormatBasic);
			if($settings['wbr']) $label = str_replace('!wbr!', '<wbr>', $label);

			$inputName = $sanitizer->entities($this->attr('name'));
			$inputValue = $sanitizer->entities($key);
			$inputClass = trim($sanitizer->entities($inputClass));

			$out .= 
				"<li$liAttr><label$attrs>" . 
				"<input$checked$disabled " . 
				"type='radio' " . 
				"name='$inputName' " . 
				"id='$id' " .
				"class='$inputClass' " . 
				"value='$inputValue' />" . 
				"<span class='$textClass'>$label</span>" . 
				"</label></li>";
		}

		$out .=	"</ul>";

		return $out; 
	}

	public function set($key, $value) {
		if($key == 'optionColumns') {
			$value = (int) $value;
			if($value < 0) $value = 0;
			if($value > 10) $value = 10;
		}
		return parent::set($key, $value); 
	}
	
	/**
	 * Get CSS width and unit for option width
	 *
	 * @param string|int $optionWidth
	 * @param array $options
	 * @return string
	 *
	 */
	public function getOptionWidthCSS($optionWidth, array &$options) {
		if(!$optionWidth) return '';
		/** @var InputfieldCheckboxes $f */
		$f = $this->wire()->modules->getModule('InputfieldCheckboxes', array('noInit' => true));
		return $f->getOptionWidthCSS($optionWidth, $options);
	}

	public function ___getConfigInputfields() {
		$inputfields = parent::___getConfigInputfields(); 
		/** @var InputfieldCheckboxes $module */
		$module = $this->wire()->modules->getModule('InputfieldCheckboxes', array('noInit' => true));
		$fs = $module->___getConfigInputfields();
		foreach(array('optionWidth', 'optionColumns') as $name) {
			$f = $fs->getChildByName($name);
			$f->val($this->getSetting($name));
			if($f->val()) $f->collapsed = Inputfield::collapsedNo;	
			$inputfields->add($f);
		}
		return $inputfields; 
	}

}
