<!DOCTYPE html>
<html>

  <head>
    <link data-require="bootstrap-css@3.3.1" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script data-require="react@*" data-semver="0.12.2" src="//cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js"></script>
    <script data-require="react-bootstrap@0.13.0" data-semver="0.13.0" src="//github.com/react-bootstrap/react-bootstrap/releases/download/v0.13.0/react-bootstrap.js"></script>
    <script src="https://rawgit.com/rsamec/react-binding/master/dist/react-binding.min.js"></script>
    <script src="https://rawgit.com/flesler/hashmap/master/hashmap.js"></script>
    <script src="https://rawgit.com/rsamec/business-rules-engine/master/dist/business-rules-engine.js"></script>
    <script data-require="underscore.js@1.6.0" data-semver="1.6.0" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
    <script data-require="moment.js@2.8.3" data-semver="2.8.3" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
    <div id="content"></div>
    <script src="script.js"></script>
  </body>

</html>
var Binder = Binder.default;

var dateConverter = function () {
  this.parse = function (input, dateFormat) {
    if (!!!input) return undefined;
    if (input.length < 8) return undefined;
    var date = moment(input, dateFormat);
    if (date.isValid()) return date.toDate();
    return undefined;
  }
  this.format = function (input, dateFormat) {
    if (!!!input) return undefined;
    return moment(input).format(dateFormat);
  }
}
var ExampleForm = React.createClass({
  
  getInitialState: function () {
    var rulesDef = {
      "Duration": {
        "type": "object",
        "properties": {
          "From": {
            "title": "From",
            "required": "true",
            "date": "true"
          },
          "To": {
            "title": "From",
            "required": "true",
            "date": "true"
          }
        }
      }
    };


    return {
      data: {},
      rules: new FormSchema.JsonSchemaRuleFactory(rulesDef).CreateRule("Main"),
      datePickerFormat: 'DD.MM.YYYY'
    };
  },
  validationResult: function () {
    if (this.state.rules === undefined) return {Errors: {}};
    return Utils.CompositeDotObject.Transform(this.state.rules.Validate(this.state.data)).Main;
  },
  duration: function () {
    var dur = this.state.data.Duration;

    if (dur === undefined || dur.From === undefined || dur.To === undefined) return;
    return moment.duration(moment(dur.From).startOf('day').diff(moment(dur.To).startOf('day'))).humanize(); // 86400000
  },
  render: function () {
    var formats = ['DD.MM.YYYY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD'];
    var converter = new dateConverter();
    return (
      <div>
        <div className="row">
          <div className='col-md-2'>
            <DatePicker label="From" model={Binder.bindToState(this,"data", "Duration.From", converter, this.state.datePickerFormat)} error={this.validationResult().Duration.From}  />
            <DatePicker label="To" model={Binder.bindToState(this,"data", "Duration.To", converter, this.state.datePickerFormat)}  error={this.validationResult().Duration.To} />
            <label>Duration:{this.duration()}</label>

          </div>
          <div className='col-md-2'>
            <label>Format</label>
            <Typeahead  array={formats} placeholder="My Typeahead" model={Binder.bindToState(this,"datePickerFormat")} />
          </div>
        </div>
        <div className="row">
          <div className='col-md-4'>
            <PrettyJson json={this.state.data} />
          </div>
        </div>

      </div>
    );
  }
});

var PrettyJson = React.createClass({
  replacer: function (match, pIndent, pKey, pVal, pEnd) {
    var key = '<span class=json-key>';
    var val = '<span class=json-value>';
    var str = '<span class=json-string>';
    var r = pIndent || '';
    if (pKey)
      r = r + key + pKey.replace(/[": ]/g, '') + '</span>: ';
    if (pVal)
      r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
    return r + (pEnd || '');
  },

  prettyPrint: function (obj) {
    var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
    return JSON.stringify(obj, null, 3)
      .replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
      .replace(/</g, '&lt;').replace(/>/g, '&gt;')
      .replace(jsonLine, this.replacer);

  },
  render: function () {
    return (<pre dangerouslySetInnerHTML={{__html: this.prettyPrint(this.props.json)}}></pre>);
  }
})

var DatePicker = React.createClass({
  getInitialState: function () {
    return {inputValue: undefined}
  },
  validationState: function(error) {
    return error.HasErrors?'error':'';
  },
  formatValue: function (e) {
    var valueModel = this.props.model;

    //setter - calls converter.parse
    valueModel.value = e.target.value;


    this.setState({
      typingFlag: false
    });
  },
  render: function () {

    var handleChange = function (e) {
      this.setState({
        inputValue: e.target.value,
        typingFlag: true
      });
    }.bind(this);

    var value = this.state.typingFlag ? this.state.inputValue : this.props.model.value;

    //format manually
    //var formatValue = function (e) {
    // var parsedValue = converter.parse(e.target.value);
    // valueModel.value = e.target.value;
    // this.setState({inputValue:converter.format(parsedValue)});
    //}.bind(this);


    return (
      <div style={{display: 'inline'}}>
        <label  style={{display: 'block'}}>{this.props.label}</label>
        <ReactBootstrap.Input type='text' onChange={handleChange} onBlur={this.formatValue} value={value}
        bsStyle={this.validationState(this.props.error)} help={this.props.error.ErrorMessage}/>
      </div>
    )
  }
});

var CheckBoxInput = React.createClass({
  render: function () {
    var valueModel = this.props.model;
    var handleChange = function (e) {
      valueModel.value = e.target.checked;
    }

    return (
      <label>
        <input type='checkbox' onChange={handleChange} checked={valueModel.value} />
        {this.props.label}
      </label>
    )
  }
});


/**
 * The MIT License (MIT)
 Inspired by 2015 Pritesh Gupta
 */
var Typeahead = React.createClass({
  getInitialState: function () {
    return {value: '', index: -1, selected: true};
  },
  handleClick: function (e) {
    this.props.model.value = e.target.innerHTML;
    //debugger;
    this.setState({selected: true});
  },

  selectItem: function (e) {
    if (this.state.selected) return;

    if (e.keyCode === 40 && this.state.index < this.items.length - 1) {
      this.setState({index: ++this.state.index});
    }
    else if (e.keyCode === 38 && this.state.index > 0) {
      this.setState({index: --this.state.index});
    }
    else if (e.keyCode === 13) {
      this.props.model.value = this.items[this.state.index].key;
      this.setState({selected: true, index: 0});
    }
  },
  handleFocus: function (e) {
    this.setState({selected: false});
  },
  //componentWillReceiveProps: function(nextProps) {
  //  this.setState({value: nextProps.value || '', index: -1, selected: true});
  //},
  render: function () {
    this.items = [];

    var valueModel = this.props.model;
    var handleChange = function (e) {
      valueModel.value = e.target.value;
      this.setState({selected: false, index: 0});
    }.bind(this);

    var searchResult = this.state.selected || (
        <div className="list-group typeahead">
          {this.items}
        </div>
      );
    var value = valueModel.value;
    this.state.selected || this.props.array.filter(function (el) {
      el = el.toLowerCase();
      var val = value.toLowerCase();

      return el.indexOf(val) > -1 || el.replace('-', ' ').indexOf(val) > -1;
    }.bind(this)).every(function (el, idx) {
      if (!value && idx > 9) return;
      var className = this.state.index === idx ? 'list-group-item active' : 'list-group-item';

      return this.items.push(<a key={el} className={className} onClick={this.handleClick}>{el}</a>);
    }, this);


    return (
      <div className="field-group">
        <input type="text" id={this.props.id} required className="form-control" value={valueModel.value} placeholder={this.props.placeholder}
          onChange={handleChange} onKeyDown={this.selectItem} onFocus={this.handleFocus} />
          {searchResult}
      </div>
    );
  }
});

React.render(
  <ExampleForm />,
  document.getElementById('content')
);
/* Styles go here */

.error{
    color: darkred;
}