'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.EuiSelectionBrush = undefined;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactVis = require('react-vis');

var _chart_utils = require('./utils/chart_utils');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var HORIZONTAL = _chart_utils.ORIENTATION.HORIZONTAL,
    VERTICAL = _chart_utils.ORIENTATION.VERTICAL,
    BOTH = _chart_utils.ORIENTATION.BOTH;


var DEFAULT_AREAS = {
  areaSize: 0,
  drawArea: {
    x0: 0,
    x1: 0,
    y0: 0,
    y1: 0
  },
  rectArea: {
    x: 0,
    y: 0,
    width: 0,
    height: 0
  }
};

var EuiSelectionBrush = exports.EuiSelectionBrush = function (_AbstractSeries) {
  _inherits(EuiSelectionBrush, _AbstractSeries);

  function EuiSelectionBrush() {
    var _ref;

    var _temp, _this, _ret;

    _classCallCheck(this, EuiSelectionBrush);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = EuiSelectionBrush.__proto__ || Object.getPrototypeOf(EuiSelectionBrush)).call.apply(_ref, [this].concat(args))), _this), _this.state = _extends({
      drawing: false
    }, DEFAULT_AREAS), _this._startDrawing = function (e) {
      var onBrushStart = _this.props.onBrushStart;
      var _e$nativeEvent = e.nativeEvent,
          offsetX = _e$nativeEvent.offsetX,
          offsetY = _e$nativeEvent.offsetY;

      var drawAndRectAreas = _this._getDrawArea(offsetX, offsetY, true);
      _this.setState(function () {
        return _extends({
          drawing: true
        }, drawAndRectAreas);
      });

      if (onBrushStart) {
        onBrushStart(drawAndRectAreas);
      }
    }, _this._brushing = function (e) {
      var onBrushing = _this.props.onBrushing;
      var drawing = _this.state.drawing;
      var _e$nativeEvent2 = e.nativeEvent,
          offsetX = _e$nativeEvent2.offsetX,
          offsetY = _e$nativeEvent2.offsetY;

      if (drawing) {
        var drawAndRectAreas = _this._getDrawArea(offsetX, offsetY);
        _this.setState(function () {
          return _extends({}, drawAndRectAreas);
        });

        if (onBrushing) {
          onBrushing(drawAndRectAreas);
        }
      } else {
        _this.setState(function () {
          return _extends({
            drawing: false
          }, DEFAULT_AREAS);
        });
      }
    }, _this._stopDrawing = function () {
      // Quickly short-circuit if the user isn't drawing in our component
      var drawing = _this.state.drawing;

      if (!drawing) {
        return;
      }

      // Clear the draw area
      _this.setState(function () {
        return _extends({
          drawing: false
        }, DEFAULT_AREAS);
      });

      // Don't invoke the callback if the selected area was < 25 square px.
      // This is a click not a select
      var areaSize = _this.state.areaSize;

      if (areaSize < 25) {
        return;
      }
      var drawArea = _this.state.drawArea;
      var x0 = drawArea.x0,
          y0 = drawArea.y0,
          x1 = drawArea.x1,
          y1 = drawArea.y1;
      var _this$props = _this.props,
          xType = _this$props.xType,
          yType = _this$props.yType,
          onBrushEnd = _this$props.onBrushEnd;

      var xScale = _reactVis.ScaleUtils.getAttributeScale(_this.props, 'x');
      var yScale = _reactVis.ScaleUtils.getAttributeScale(_this.props, 'y');

      var xValues = _this._getScaledValue(xScale, xType, x0, x1);
      var yValues = _this._getScaledValue(yScale, yType, y0, y1);

      // Compute the corresponding domain drawn
      var domainArea = {
        startX: xValues[0],
        endX: xValues[1],
        startY: yValues[1],
        endY: yValues[0]
      };

      if (onBrushEnd) {
        onBrushEnd({
          domainArea: domainArea,
          drawArea: drawArea
        });
      }
    }, _temp), _possibleConstructorReturn(_this, _ret);
  }

  _createClass(EuiSelectionBrush, [{
    key: 'onParentMouseDown',
    value: function onParentMouseDown(e) {
      this._startDrawing(e);
    }
  }, {
    key: 'onParentMouseMove',
    value: function onParentMouseMove(e) {
      this._brushing(e);
    }
  }, {
    key: 'onParentMouseUp',
    value: function onParentMouseUp() {
      this._stopDrawing();
    }
  }, {
    key: 'onParentMouseLeave',
    value: function onParentMouseLeave() {
      this._stopDrawing();
    }
  }, {
    key: '_getDrawArea',
    value: function _getDrawArea(offsetX, offsetY, isStartingPoint) {
      var _props = this.props,
          orientation = _props.orientation,
          marginTop = _props.marginTop,
          marginLeft = _props.marginLeft,
          innerHeight = _props.innerHeight,
          innerWidth = _props.innerWidth;

      var yLocation = offsetY - marginTop;
      var xLocation = offsetX - marginLeft;
      var x0 = void 0;
      var y0 = void 0;
      if (isStartingPoint) {
        x0 = orientation === VERTICAL ? 0 : xLocation;
        y0 = orientation === HORIZONTAL ? 0 : yLocation;
      } else {
        x0 = this.state.drawArea.x0;
        y0 = this.state.drawArea.y0;
      }
      var x1 = orientation === VERTICAL ? innerWidth : xLocation;
      var y1 = orientation === HORIZONTAL ? innerHeight : yLocation;
      var areaSize = Math.abs(x0 - x1) * Math.abs(y0 - y1);
      return {
        areaSize: areaSize,
        drawArea: {
          x0: x0,
          x1: x1,
          y0: y0,
          y1: y1
        },
        rectArea: {
          x: x0 < x1 ? x0 : x1,
          y: y0 < y1 ? y0 : y1,
          width: x0 < x1 ? x1 - x0 : x0 - x1,
          height: y0 < y1 ? y1 - y0 : y0 - y1
        }
      };
    }
  }, {
    key: '_getScaledValue',
    value: function _getScaledValue(scale, scaleType, value0, value1) {
      switch (scaleType) {
        case _chart_utils.SCALE.ORDINAL:
          return [0, 0];
        default:
          return [scale.invert(value0 < value1 ? value0 : value1), scale.invert(value0 < value1 ? value1 : value0)];
          break;

      }
    }
  }, {
    key: 'render',
    value: function render() {
      var _props2 = this.props,
          marginLeft = _props2.marginLeft,
          marginTop = _props2.marginTop,
          color = _props2.color,
          opacity = _props2.opacity;
      var _state$rectArea = this.state.rectArea,
          x = _state$rectArea.x,
          y = _state$rectArea.y,
          width = _state$rectArea.width,
          height = _state$rectArea.height;

      return _react2.default.createElement(
        'g',
        {
          transform: 'translate(' + marginLeft + ', ' + marginTop + ')',
          style: {
            pointerEvents: 'none'
          }
        },
        _react2.default.createElement('rect', {
          opacity: opacity,
          fill: color,
          x: x,
          y: y,
          width: width,
          height: height
        })
      );
    }
  }]);

  return EuiSelectionBrush;
}(_reactVis.AbstractSeries);

EuiSelectionBrush.displayName = 'EuiSelectionBrush';

EuiSelectionBrush.propTypes = {
  /** Specify the brush orientation */
  orientation: _propTypes2.default.oneOf([HORIZONTAL, VERTICAL, BOTH]),
  /** Callback on brush start event. */
  onBrushStart: _propTypes2.default.func,
  /** Callback on every mouse move event. */
  onBrushing: _propTypes2.default.func,
  /** Callback on brush end event. */
  onBrushEnd: _propTypes2.default.func.isRequired,
  /** The color of the brush rectangle */
  color: _propTypes2.default.string,
  /** The opacity of the brush rectangle*/
  opacity: _propTypes2.default.number
};

EuiSelectionBrush.defaultProps = {
  orientation: HORIZONTAL,
  color: 'black',
  opacity: 0.2
};
EuiSelectionBrush.__docgenInfo = [{
  'description': '',
  'displayName': 'EuiSelectionBrush',
  'methods': [{
    'name': 'onParentMouseDown',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'e',
      'type': null
    }],
    'returns': null
  }, {
    'name': 'onParentMouseMove',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'e',
      'type': null
    }],
    'returns': null
  }, {
    'name': 'onParentMouseUp',
    'docblock': null,
    'modifiers': [],
    'params': [],
    'returns': null
  }, {
    'name': 'onParentMouseLeave',
    'docblock': null,
    'modifiers': [],
    'params': [],
    'returns': null
  }, {
    'name': '_getDrawArea',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'offsetX',
      'type': null
    }, {
      'name': 'offsetY',
      'type': null
    }, {
      'name': 'isStartingPoint',
      'type': null
    }],
    'returns': null
  }, {
    'name': '_getScaledValue',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'scale',
      'type': null
    }, {
      'name': 'scaleType',
      'type': null
    }, {
      'name': 'value0',
      'type': null
    }, {
      'name': 'value1',
      'type': null
    }],
    'returns': null
  }, {
    'name': '_startDrawing',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'e',
      'type': null
    }],
    'returns': null
  }, {
    'name': '_brushing',
    'docblock': null,
    'modifiers': [],
    'params': [{
      'name': 'e',
      'type': null
    }],
    'returns': null
  }, {
    'name': '_stopDrawing',
    'docblock': null,
    'modifiers': [],
    'params': [],
    'returns': null
  }],
  'props': {
    'orientation': {
      'type': {
        'name': 'enum',
        'value': [{
          'value': 'ORIENTATION.HORIZONTAL',
          'computed': true
        }, {
          'value': 'ORIENTATION.VERTICAL',
          'computed': true
        }, {
          'value': 'ORIENTATION.BOTH',
          'computed': true
        }]
      },
      'required': false,
      'description': 'Specify the brush orientation',
      'defaultValue': {
        'value': 'ORIENTATION.HORIZONTAL',
        'computed': true
      }
    },
    'onBrushStart': {
      'type': {
        'name': 'func'
      },
      'required': false,
      'description': 'Callback on brush start event.'
    },
    'onBrushing': {
      'type': {
        'name': 'func'
      },
      'required': false,
      'description': 'Callback on every mouse move event.'
    },
    'onBrushEnd': {
      'type': {
        'name': 'func'
      },
      'required': true,
      'description': 'Callback on brush end event.'
    },
    'color': {
      'type': {
        'name': 'string'
      },
      'required': false,
      'description': 'The color of the brush rectangle',
      'defaultValue': {
        'value': '\'black\'',
        'computed': false
      }
    },
    'opacity': {
      'type': {
        'name': 'number'
      },
      'required': false,
      'description': 'The opacity of the brush rectangle',
      'defaultValue': {
        'value': '0.2',
        'computed': false
      }
    }
  }
}];