<?php
namespace SabaiApps\Directories\Component\Form\Field;

use SabaiApps\Directories\Component\Form\Form;

/**
 * RadioField provides a single radio input.
 * Supports custom on_value and label, and required validation.
 */
class RadioField extends AbstractField {

	protected $_type = 'radio';

	/**
	 * Initializes the Radio field and sets the default on_value.
	 *
	 * @param string $name
	 * @param array  $data
	 * @param Form   $form
	 */
	public function formFieldInit( $name, array &$data, Form $form ) {
		if ( ! isset( $data['#on_value'] ) ) {
			$data['#on_value'] = 1;
		}
	}

	/**
	 * Handles value processing and validation for the Radio field on submit.
	 *
	 * @param mixed $value
	 * @param array $data
	 * @param Form  $form
	 */
	public function formFieldSubmit( &$value, array &$data, Form $form ) {
		// Is it a required field?
		if ( is_null( $value ) ) {
			if ( $form->isFieldRequired( $data ) ) {
				$form->setError( isset( $data['#required_error_message'] ) ? $data['#required_error_message'] : __( 'Selection required.', 'directories-pro' ), $data );
			}

			return;
		}

		if ( $value != $data['#on_value'] ) {
			$form->setError( __( 'Invalid option selected.', 'directories-pro' ), $data );
		}
	}

	/**
	 * Renders the Radio field as a single radio input.
	 *
	 * @param array $data
	 * @param Form  $form
	 */
	public function formFieldRender( array &$data, Form $form ) {
		$this->_render( $this->_renderInput( $data, $form ), $data, $form );
	}

	/**
	 * Returns the HTML for the radio input.
	 *
	 * @param array  $data
	 * @param Form   $form
	 * @param string $class
	 * @return string
	 */
	protected function _renderInput( array &$data, Form $form, $class = '' ) {
		$data['#id'] = $form->getFieldId( $data['#name'] );
		if ( isset( $data['#on_label'] ) ) {
			$label = $data['#on_label'];
		} else {
			// Use title as checkbox label
			$label = (string) $data['#title'];
			// Clear title to prevent duplicated label
			unset( $data['#title'] );
			$data['#option_no_escape'] = ! empty( $data['#title_no_escape'] );
		}
		if ( strlen( $label ) ) {
			if ( empty( $data['#option_no_escape'] ) ) {
				$label = $this->_application->H( $label );
			}
			if ( isset( $data['#count'] ) ) {
				$label .= ' ' . $this->_getCountBadge( $data['#count'] );
			}
		} else {
			$label = '&nbsp;'; // required to align radio button correctly, as of BS 4.1.1
		}
		if ( $this->_isChecked( $data ) ) {
			$data['#attributes']['checked'] = 'checked';
		}

		return sprintf(
			'<div class="drts-form-field-radio-option %9$smt-1 %2$s%8$s" data-value="%4$s">
    <div class="%9$sform-check">
        <input class="%7$s %9$sform-check-input" type="%1$s" name="%3$s" value="%4$s" id="%10$s-check"%5$s>
        <label class="%9$sform-check-label" for="%10$s-check">%6$s</label>
    </div>
</div>',
			$this->_type,
			$class,
			$this->_type == 'checkbox' ? $data['#name'] . '[]' : $data['#name'],
			$this->_application->H( $data['#on_value'] ),
			$this->_application->Attr( $data['#attributes'], 'class' ),
			$label,
			isset( $data['#attributes']['class'] ) ? $this->_application->H( $data['#attributes']['class'] ) : '',
			empty( $data['#disabled'] ) ? '' : ' ' . DRTS_BS_PREFIX . 'disabled',
			DRTS_BS_PREFIX,
			$data['#id']
		);
	}

	/**
	 * Checks if the radio input should be checked.
	 *
	 * @param array $data
	 * @return bool
	 */
	protected function _isChecked( array $data ) {
		$ret = false;
		if ( $this->_type === 'checkbox' ) {
			if ( isset( $data['#default_value'] ) ) {
				if ( is_array( $data['#default_value'] ) ) {
					// coming from request
					$ret = $data['#default_value'][0] == $data['#on_value'];
				} else {
					$ret = $data['#default_value'] == $data['#on_value'];
				}
			}
		} else {
			$ret = $data['#default_value'] == $data['#on_value'];
		}

		return $ret;
	}
}
