content: 'use strict' /* @flow */
  
  import React from 'react'
  import ReactCSS from 'reactcss'
  import shallowCompare from 'react-addons-shallow-compare'
  
  export class EditableInput extends ReactCSS.Component {
    shouldComponentUpdate = shallowCompare.bind(this, this, arguments[0], arguments[1]);
  
    constructor(props: any) {
      super()
  
      this.state = {
        value: String(props.value).toUpperCase(),
        blurValue: String(props.value).toUpperCase(),
      }
    }
  
    classes(): any {
      return {
        'user-override': {
          wrap: this.props.style && this.props.style.wrap ? this.props.style.wrap : {},
          input: this.props.style && this.props.style.input ? this.props.style.input : {},
          label: this.props.style && this.props.style.label ? this.props.style.label : {},
        },
        'dragLabel-true': {
          label: {
            cursor: 'ew-resize',
          },
        },
      }
    }
  
    styles(): any {
      return this.css({
        'user-override': true,
      })
    }
  
    componentWillReceiveProps(nextProps: any) {
      var input = this.refs.input
      if (nextProps.value !== this.state.value) {
        if (input === document.activeElement) {
          this.setState({ blurValue: String(nextProps.value).toUpperCase() })
        } else {
          this.setState({ value: String(nextProps.value).toUpperCase() })
        }
      }
    }
  
    componentWillUnmount() {
      this.unbindEventListeners()
    }
  
    handleBlur = () => {
      if (this.state.blurValue) {
        this.setState({ value: this.state.blurValue, blurValue: null })
      }
    }
  
    handleChange = (e: any) => {
      if (this.props.label !== null) {
        var obj = {}
        obj[this.props.label] = e.target.value
        this.props.onChange(obj)
      } else {
        this.props.onChange(e.target.value)
      }
  
      this.setState({ value: e.target.value })
    }
  
    handleKeyDown = (e: any) => {
      var number = Number(e.target.value)
      if (number) {
        var amount = this.props.arrowOffset || 1
  
        // Up
        if (e.keyCode === 38) {
          if (this.props.label !== null) {
            var obj = {}
            obj[this.props.label] = number + amount
            this.props.onChange(obj)
          } else {
            this.props.onChange(number + amount)
          }
  
          this.setState({ value: number + amount })
        }
  
        // Down
        if (e.keyCode === 40) {
          if (this.props.label !== null) {
            var obj = {}
            obj[this.props.label] = number - amount
            this.props.onChange(obj)
          } else {
            this.props.onChange(number - amount)
          }
  
          this.setState({ value: number - amount })
        }
  
      }
    }
  
    handleDrag = (e: any) => {
      if (this.props.dragLabel) {
        var newValue = Math.round(this.props.value + e.movementX)
        if (newValue >= 0 && newValue <= this.props.dragMax) {
          var obj = {}
          obj[this.props.label] = newValue
          this.props.onChange(obj)
        }
      }
    }
  
    handleMouseDown = (e: any) => {
      if (this.props.dragLabel) {
        e.preventDefault()
        this.handleDrag(e)
        window.addEventListener('mousemove', this.handleDrag)
        window.addEventListener('mouseup', this.handleMouseUp)
      }
    }
  
    handleMouseUp = () => {
      this.unbindEventListeners()
    }
  
    unbindEventListeners = () => {
      window.removeEventListener('mousemove', this.handleChange)
      window.removeEventListener('mouseup', this.handleMouseUp)
    }
  
    render(): any {
      var label
      if (this.props.label) {
        label = <span is="label" ref="label" onMouseDown={ this.handleMouseDown }>{ this.props.label }</span>
      }
  
      return (
        <div is="wrap" ref="container">
          <input is="input" ref="input" value={ this.state.value } onKeyDown={ this.handleKeyDown } onChange={ this.handleChange } onBlur={ this.handleBlur }/>
          { label }
        </div>
      )
    }
  }
  
  export default EditableInput
  