<?php

namespace Internetgalerie\IgDatapoolFe\ViewHelpers\Form;

use TYPO3\CMS\Extbase\Reflection\ObjectAccess;

/**
 * This view helper generates a <select> dropdown list for the use with a form.
 *
 * = Basic usage =
 *
 * The most straightforward way is to supply an associative array as the "options" parameter.
 * The array key is used as option key, and the value is used as human-readable name.
 *
 * <code title="Basic usage">
 * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" />
 * </code>
 *
 * = Pre-select a value =
 *
 * To pre-select a value, set "value" to the option key which should be selected.
 * <code title="Default value">
 * <f:form.select name="paymentOptions" options="{payPal: 'PayPal International Services', visa: 'VISA Card'}" value="visa" />
 * </code>
 * Generates a dropdown box like above, except that "VISA Card" is selected.
 *
 * If the select box is a multi-select box (multiple="true"), then "value" can be an array as well.
 *
 * = Usage on domain objects =
 *
 * If you want to output domain objects, you can just pass them as array into the "options" parameter.
 * To define what domain object value should be used as option key, use the "optionValueField" variable. Same goes for optionLabelField.
 * If neither is given, the Identifier (UID/uid) and the __toString() method are tried as fallbacks.
 *
 * If the optionValueField variable is set, the getter named after that value is used to retrieve the option key.
 * If the optionLabelField variable is set, the getter named after that value is used to retrieve the option value.
 *
 * If the prependOptionLabel variable is set, an option item is added in first position, bearing an empty string or -
 * If provided, the value of the prependOptionValue variable as value.
 *
 * <code title="Domain objects">
 * <f:form.select name="users" options="{userArray}" optionValueField="id" optionLabelField="firstName" />
 * </code>
 * In the above example, the userArray is an array of "User" domain objects, with no array key specified.
 *
 * So, in the above example, the method $user->getId() is called to retrieve the key, and $user->getFirstName() to retrieve the displayed value of each entry.
 *
 * The "value" property now expects a domain object, and tests for object equivalence.
 *
 * @api
 * @author     Markus Baumgartner <mb@stylesheep.ch>, Internetgalerie AG
 * @package    IgDatapoolFE
 * @subpackage ViewHelpers
 */
class SelectViewHelper extends \Internetgalerie\IgCoreViewhelpers\ViewHelpers\Form\SelectViewHelper implements FieldInterface
{
    use FormFieldTrait;


    /**
     * Initialize arguments.
     *
     * @return void
     * @api
     */
    public function initializeArguments(): void
    {
        parent::initializeArguments();
        //$this->overrideArgument('options', 'mixed', 'Associative array with internal IDs as key, and the values are displayed in the select box', false);
        $this->registerArgument('default', 'mixed', 'Default Value');
        $this->registerArgument('optionClass', 'mixed', 'class option->any getter');
    }

    /**
     * Render one option tag
     *
     * @param  string  $value      value attribute of the option tag (will be escaped)
     * @param  string  $label      content of the option tag (will be escaped)
     * @param  boolean $isSelected specifies wheter or not to add selected attribute
     * @return string the rendered option tag
     */
    protected function renderOptionTag(string $value, string $label, bool $isSelected): string
    {
        $output = '<option value="' . htmlspecialchars($value) . '"';
        if ($isSelected) {
            $output .= ' selected="selected"';
        }
        if ($this->hasArgument('optionClass')) {
            $class = ObjectAccess::getPropertyPath($this->extraValues[$value], $this->arguments['optionClass']);
            $property = $this->arguments['property'];
            $output .= ' class="dp-option-'.$property .'-'. $class .  '"';
            //. ($this->extraValues[$value])
        }

        //set options for recursiveness
        /*
        $spacer = isset($this->recursiveness[$value]) ? str_repeat('&nbsp;&nbsp;&nbsp;', intval($this->recursiveness[$value])) : '';
        if (strpos($value, '__') === 0) {
            $output .= ' disabled="disabled"';
        }
        $output .= '>' . $spacer . htmlspecialchars($label) . '</option>';
        */
        $output .= '>' . htmlspecialchars($label) . '</option>';
        return $output;
    }
}
