import React, { Component } from "react"
import PropTypes from "prop-types"
import { connect } from "react-redux"
import { update as updateOptions } from "../../ducks/options"
import { Key } from "../../utils"
import classnames from 'classnames'

const stopPropagation = e => {
    if (e.keyCode !== Key.ESC) {
        e.stopPropagation()
    }
}

BooleanOption.PropTypes = {
    value: PropTypes.bool.isRequired,
    onChange: PropTypes.func.isRequired,
}
function BooleanOption({ value, onChange, ...props }) {
    return (
        <div className="checkbox">
            <label>
                <input type="checkbox"
                       checked={value}
                       onChange={e => onChange(e.target.checked)}
                       {...props}
                />
                Enable
            </label>
        </div>
    )
}

StringOption.PropTypes = {
    value: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
}
function StringOption({ value, onChange, ...props }) {
    return (
        <input type="text"
               value={value || ""}
               onChange={e => onChange(e.target.value)}
               {...props}
        />
    )
}
function Optional(Component) {
    return function ({ onChange, ...props }) {
        return <Component
            onChange={x => onChange(x ? x : null)}
            {...props}
        />
    }
}

NumberOption.PropTypes = {
    value: PropTypes.number.isRequired,
    onChange: PropTypes.func.isRequired,
}
function NumberOption({ value, onChange, ...props }) {
    return (
        <input type="number"
               value={value}
               onChange={(e) => onChange(parseInt(e.target.value))}
               {...props}
        />
    )
}

ChoicesOption.PropTypes = {
    value: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
}
export function ChoicesOption({ value, onChange, choices, ...props }) {
    return (
        <select
            onChange={(e) => onChange(e.target.value)}
            value={value}
            {...props}
        >
            { choices.map(
                choice => (
                    <option key={choice} value={choice}>{choice}</option>
                )
            )}
        </select>
    )
}

StringSequenceOption.PropTypes = {
    value: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
}
function StringSequenceOption({ value, onChange, ...props }) {
    const height = Math.max(value.length, 1)
    return <textarea
        rows={height}
        value={value.join('\n')}
        onChange={e => onChange(e.target.value.split("\n"))}
        {...props}
    />
}

export const Options = {
    "bool": BooleanOption,
    "str": StringOption,
    "int": NumberOption,
    "optional str": Optional(StringOption),
    "sequence of str": StringSequenceOption,
}

function PureOption({ choices, type, value, onChange, name, error }) {
    let Opt, props = {}
    if (choices) {
        Opt = ChoicesOption;
        props.choices = choices
    } else {
        Opt = Options[type]
    }
    if (Opt !== BooleanOption) {
        props.className = "form-control"
    }

    return <div className={classnames({'has-error':error})}>
                <Opt
                    name={name}
                    value={value}
                    onChange={onChange}
                    onKeyDown={stopPropagation}
                    {...props}
                />
            </div>
}
export default connect(
    (state, { name }) => ({
        ...state.options[name],
        ...state.ui.optionsEditor[name]
    }),
    (dispatch, { name }) => ({
        onChange: value => dispatch(updateOptions(name, value))
    })
)(PureOption)
'n20' href='#n20'>20</a>
<a id='n21' href='#n21'>21</a>
<a id='n22' href='#n22'>22</a>
<a id='n23' href='#n23'>23</a>
<a id='n24' href='#n24'>24</a>
<a id='n25' href='#n25'>25</a>
<a id='n26' href='#n26'>26</a>
<a id='n27' href='#n27'>27</a>
<a id='n28' href='#n28'>28</a>
<a id='n29' href='#n29'>29</a>
<a id='n30' href='#n30'>30</a>
<a id='n31' href='#n31'>31</a>
<a id='n32' href='#n32'>32</a>
<a id='n33' href='#n33'>33</a>
<a id='n34' href='#n34'>34</a>
<a id='n35' href='#n35'>35</a>
<a id='n36' href='#n36'>36</a>
<a id='n37' href='#n37'>37</a>
<a id='n38' href='#n38'>38</a>
<a id='n39' href='#n39'>39</a>
<a id='n40' href='#n40'>40</a>
<a id='n41' href='#n41'>41</a>
<a id='n42' href='#n42'>42</a>
<a id='n43' href='#n43'>43</a>
<a id='n44' href='#n44'>44</a>
<a id='n45' href='#n45'>45</a>
<a id='n46' href='#n46'>46</a>
<a id='n47' href='#n47'>47</a>
<a id='n48' href='#n48'>48</a>
<a id='n49' href='#n49'>49</a>
<a id='n50' href='#n50'>50</a>
<a id='n51' href='#n51'>51</a>
<a id='n52' href='#n52'>52</a>
<a id='n53' href='#n53'>53</a>
<a id='n54' href='#n54'>54</a>
<a id='n55' href='#n55'>55</a>
<a id='n56' href='#n56'>56</a>
<a id='n57' href='#n57'>57</a>
<a id='n58' href='#n58'>58</a>
<a id='n59' href='#n59'>59</a>
<a id='n60' href='#n60'>60</a>
<a id='n61' href='#n61'>61</a>
<a id='n62' href='#n62'>62</a>
<a id='n63' href='#n63'>63</a>
<a id='n64' href='#n64'>64</a>
<a id='n65' href='#n65'>65</a>
<a id='n66' href='#n66'>66</a>
<a id='n67' href='#n67'>67</a>
<a id='n68' href='#n68'>68</a>
<a id='n69' href='#n69'>69</a>
<a id='n70' href='#n70'>70</a>
<a id='n71' href='#n71'>71</a>
<a id='n72' href='#n72'>72</a>
<a id='n73' href='#n73'>73</a>
<a id='n74' href='#n74'>74</a>
<a id='n75' href='#n75'>75</a>
<a id='n76' href='#n76'>76</a>
<a id='n77' href='#n77'>77</a>
<a id='n78' href='#n78'>78</a>
<a id='n79' href='#n79'>79</a>
<a id='n80' href='#n80'>80</a>
<a id='n81' href='#n81'>81</a>
<a id='n82' href='#n82'>82</a>
<a id='n83' href='#n83'>83</a>
<a id='n84' href='#n84'>84</a>
<a id='n85' href='#n85'>85</a>
<a id='n86' href='#n86'>86</a>
<a id='n87' href='#n87'>87</a>
</pre></td>
<td class='lines'><pre><code>