content: import React from 'react';
  import {BaseMixin, ElementaryMixin, Tools} from './../common/common.js';
  
  import Backdrop from './../bricks/backdrop.js';
  
  import TextInput from './internal/text-input.js';
  import Time from './time.js';
  
  import TextInputMixin from './mixins/text-input-mixin.js'
  
  import './timepicker.less';
  
  const FORMAT_AM = 'AM';
  const FORMAT_PM = 'PM';
  const FORMAT_12 = '12';
  const FORMAT_24 = '24';
  export const Timepicker = React.createClass({
  
    //@@viewOn:mixins
    mixins: [
      BaseMixin,
      ElementaryMixin,
      TextInputMixin
    ],
    //@@viewOff:mixins
  
    //@@viewOn:statics
    statics: {
      tagName: 'UU5.Forms.Timepicker',
      classNames: {
        main: 'uu5-forms-timepicker',
        open: 'uu5-forms-timepicker-open',
        menu: 'uu5-forms-input-menu'
      }
    },
    //@@viewOff:statics
  
    //@@viewOn:propTypes
    propTypes: {
      value: React.PropTypes.string,
      buttonHidden: React.PropTypes.bool,
      glyphiconOpened: React.PropTypes.string,
      glyphiconClosed: React.PropTypes.string,
      format: React.PropTypes.oneOf([FORMAT_24, FORMAT_12]),
      nanMessage: React.PropTypes.any
    },
    //@@viewOff:propTypes
  
    //@@viewOn:getDefaultProps
    getDefaultProps() {
      return {
        value: '',
        isButtonHidden: false,
        glyphiconOpened: 'uu-glyphicon-clock',
        glyphiconClosed: 'uu-glyphicon-clock',
        format: FORMAT_24,
        nanMessage: 'Please insert a valid date.'
      };
    },
    //@@viewOff:getDefaultProps
  
    //@@viewOn:standardComponentLifeCycle
    getInitialState() {
      return {
        opened: false
      };
    },
  
    componentWillMount(){
      if (typeof this.props.onValidate === 'function') {
        let result = this._isValidTimeResult({ value: this._formatTime(this._parseTime(this.state.value), true) });
        if (result) {
          if (typeof result === 'object') {
            if (result.feedback) {
              this.setFeedback(result.feedback, result.message, this._formatTime(this._parseTime(result.value), true));
            } else {
              this._validateOnChange({
                value: this._formatTime(this._parseTime(this.state.value), true),
                event: null,
                component: this
              })
            }
          }
        }
      } else  {
        this.setState({ value: this._formatTime(this._parseTime(this.state.value), true) });
      }
      return this;
    },
  
    componentWillReceiveProps(nextProps) {
      if (nextProps.controlled) {
        let result = this._isValidTimeResult({ value: nextProps.value });
        if (result) {
          if (typeof result === 'object') {
            if (result.feedback) {
              this.setFeedback(result.feedback, result.message, result.value);
            } else {
              this.setFeedback(nextProps.feedback, nextProps.message, nextProps.value)
            }
          }
        }
      }
      return this;
    },
    //@@viewOff:standardComponentLifeCycle
  
    //@@viewOn:interface
  
    open (setStateCallback) {
      this.setState({ opened: true }, setStateCallback);
      return this;
    },
  
    toggle (setStateCallback) {
      this.setState((state) => ({ opened: !state.opened }), setStateCallback);
      return this;
    },
    //@@viewOff:interface
  
    //@@viewOn:overridingMethods
    setValue_(value, setStateCallback){
      if (this._checkRequired({ value: value })) {
        if (typeof this.props.onValidate === 'function') {
          this._validateOnChange({ value: value, event: null, component: this });
        } else {
          this.props.required ? this.setSuccess(null, value, setStateCallback) : this.setInitial(null, value, setStateCallback);
        }
      }
      return this;
    },
  
    isOpened_(){
      return this.state.opened;
    },
  
    close_ (setStateCallback) {
      this.setState({ opened: false }, setStateCallback);
      return this;
    },
    //@@viewOff:overridingMethods
  
    //@@viewOn:componentSpecificHelpers
    _onChange(e){
      let opt = { value: e.target.value, event: e, component: this };
  
      if (opt.value === '' || this._parseTime(opt.value)) {
        if (!this.isDisabled() && !this.isReadOnly()) {
          if (typeof this.props.onChange === 'function') {
            this.props.onChange(opt);
          } else {
            if (this.props.validateOnChange) {
              this._validateOnChange(opt);
            } else {
              if (opt.value === '') {
                this.setState({ value: opt.value });
              } else if (this._checkRequired({ value: opt.value })) {
                opt.required = this.props.required;
                let result = this.getChangeFeedback(opt);
  
                if (!result.value ||
                  (this.props.format === FORMAT_12 && result.value.match(/^\d{1,2}:?\d{0,2} ?[PpAa]?\.?[Mm]?\.?$/)) ||
                  (this.props.format === FORMAT_24 && result.value.match(/^\d{1,2}:?\d{0,2}$/))) {
                  this.setFeedback(result.feedback, result.message, result.value);
                }
              }
            }
          }
        }
      }
  
      return this;
    },
  
    _onBlur(e){
      let opt = { value: e.target.value, event: e, component: this };
      if (typeof this.props.onBlur === 'function') {
        this.props.onBlur(opt);
      } else {
        if (this._checkRequired({ value: opt.value }) && !this.props.validateOnChange) {
          opt.required = this.props.required;
          let blurResult = this.getBlurFeedback(opt);
          let result = this._isValidTimeResult(blurResult);
          this.setFeedback(result.feedback, result.message, this._formatTime(this._parseTime(blurResult.value), true));
        }
      }
      return this;
    },
  
    _isValidTimeResult(opt){
      let result = opt;
      let time = this._parseTime(opt.value);
      if (!time && opt.value) {
        result.feedback = 'error';
        result.message = this.props.nanMessage;
      }
      return result;
    },
  
    _validateOnChange(opt){
      let result = typeof this.props.onValidate === 'function' ? this.props.onValidate(opt) : null;
      if (result) {
        if (typeof result === 'object') {
          if (result.feedback) {
            this.setFeedback(result.feedback, result.message, result.value);
          } else {
            this.setState({ value: opt.value });
          }
        } else {
          this.showError('validateError', null, { context: { event: e, func: this.props.onValidate, result: result } });
        }
      } else if (this.props.required && this.state.value) {
        this.setSuccess(null, this.state.value)
      }
      return this;
    },
  
    _getFeedbackIcon(){
      let icon = this.props.required ? this.props.successGlyphicon : null;
      switch (this.getFeedback()) {
        case 'success':
          icon = this.props.successGlyphicon;
          break;
        case 'warning':
          icon = this.props.warningGlyphicon;
          break;
        case 'error':
          icon = this.props.errorGlyphicon;
          break;
      }
      return icon;
    },
  
    _onTimeChange(opt) {
      this.setState({ value: this._formatTime(opt.value, true) });
      return this;
    },
  
    _getTimeProps(value) {
      return {
        className: this.getClassName().menu,
        value: value,
        ref_: this._refCalendar,
        hidden: !this.isOpened(),
        onChange: this._onTimeChange,
        format: this.props.format,
        controlled: true
      };
    },
  
    _formatTime(value, fill0) {
      let time = '';
      if (value) {
        if (fill0) {
          time = Tools.rjust(value.hours, 2, '0') + ':' + Tools.rjust(value.minutes, 2, '0');
        } else {
          time = value.hours + ':' + value.minutes;
        }
        if (this.props.format === FORMAT_12) {
          time += ' ' + (value.dayPart || FORMAT_AM);
        }
      }
      return time;
    },
  
    _parseTime (stringTime) {
      stringTime = stringTime.trim();
      let value = null;
  
      if (typeof stringTime === 'string' && stringTime !== '') {
        value = {
          hours: 0,
          minutes: 0
        };
  
        if (stringTime.indexOf(':') !== -1) {
          let dateArray = stringTime.split(':');
          value.hours = parseInt(dateArray[0].trim()) || 0;
          value.minutes = parseInt(dateArray[1].trim()) || 0;
        } else {
          value.hours = parseInt(stringTime) || 0;
        }
  
        if (value.hours < 0 || value.hours > 23 || value.minutes < 0 || value.minutes > 59) {
          value = null;
        } else if (this.props.format === FORMAT_12) {
          if (value.hours > 12) {
            value.hours -= 12;
          } else if (value.hours == 0) {
            value.hours = 12;
          }
  
          if (stringTime.match(/[Pp]\.?([Mm]\.?)?/)) {
            value.dayPart = FORMAT_PM;
          } else {
            value.dayPart = FORMAT_AM;
          }
        }
      }
      return value;
    },
  
    _getTextInputAttrs() {
      let props = {};
      if (!this.isReadOnly() && !this.isDisabled()) {
        props.onClick = () => {
          this.open();
        };
      }
      return props;
    },
  
    _getMainAttrs(){
      let attrs = this._getInputAttrs();
      if (this.isOpened()) {
        attrs.className += ' ' + this.getClassName().open;
      }
      return attrs;
    },
    //@@viewOff:componentSpecificHelpers
  
    //@@viewOn:render
    render() {
      let inputId = this.getId() + '-input';
      let buttons = !this.isReadOnly() && !this.props.buttonHidden ?
        [{
          glyphicon: this.isOpened() ? this.props.glyphiconOpened : this.props.glyphiconClosed,
          disabled: this.isDisabled(),
          onClick: () => this.toggle(),
          pressed: this.isOpened(),
          colorSchema: 'default'
        }]
        : null;
  
      let value = this._parseTime(this.state.value);
  
      return (
        <div {...this._getMainAttrs()}>
          {this.getLabel(inputId)}
          {this.getInputWrapper([
              <TextInput
                id={inputId}
                name={this.props.name || inputId}
                value={this.state.value || ''}
                placeholder={this.props.placeholder}
                type='text'
                onChange={this._onChange}
                onBlur={this._onBlur}
                onFocus={this.onFocus}
                mainAttrs={this._getTextInputAttrs() || this.props.inputAttrs}
                disabled={this.isDisabled() || this.isLoading()}
                readonly={this.isReadOnly()}
                glyphicon={this._getFeedbackIcon()}
                loading={this.isLoading()}
              />,
  
              <Time {...this._getTimeProps(value)} />,
              <Backdrop {...this._getBackdropProps()} />
            ],
            buttons)}
  
        </div>
      );
    }
    //@@viewOn:render
  });
  
  export default Timepicker;
  