'use strict';

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

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _update = require('react/lib/update');

var _update2 = _interopRequireDefault(_update);

var _SortableItem = require('./SortableItem');

var _SortableItem2 = _interopRequireDefault(_SortableItem);

var _reactDnd = require('react-dnd');

var _reactDndHtml5Backend = require('react-dnd-html5-backend');

var _reactDndHtml5Backend2 = _interopRequireDefault(_reactDndHtml5Backend);

var _CustomDragLayer = require('./CustomDragLayer');

var _CustomDragLayer2 = _interopRequireDefault(_CustomDragLayer);

var _style = require('./style.scss');

var _style2 = _interopRequireDefault(_style);

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 SortableList = function (_React$Component) {
  _inherits(SortableList, _React$Component);

  function SortableList(props) {
    _classCallCheck(this, SortableList);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SortableList).call(this, props));

    _this.state = {
      items: _this.props.items,
      dragging: false,
      width: 0,
      left: 0
    };

    _this.handleResize = function () {
      _this.setState({ width: _this._sortableList.getBoundingClientRect().width, top: _this._sortableList.getBoundingClientRect().top });
    };

    _this.componentDidMount = function () {
      _this.handleResize();

      // Add event listener
      window.addEventListener('resize', _this.handleResize);
    };

    _this.componentWillUnmount = function () {
      // Remove event listener
      window.removeEventListener('resize', _this.handleResize);
    };

    _this.componentWillReceiveProps = function (nextProps) {
      _this.setState({ items: nextProps.items });
    };

    _this.moveSortableItem = function (dragIndex, hoverIndex) {
      var items = _this.state.items;

      var dragSortableItem = items[dragIndex];

      _this.setState((0, _update2.default)(_this.state, {
        items: {
          $splice: [[dragIndex, 1], [hoverIndex, 0, dragSortableItem]]
        }
      }), function () {
        if (this.props.changeCallback) {
          this.props.changeCallback({
            target: {
              name: this.props.name,
              value: this.state.items
            }
          });
        }
      });
    };

    _this.toggleSortableItem = function (index) {
      var items = _this.state.items;
      items[index].active = !items[index].active;

      _this.setState((0, _update2.default)(_this.state, {
        items: { $set: items }
      }), function () {
        if (this.props.changeCallback) {
          this.props.changeCallback({
            target: {
              name: this.props.name,
              value: this.state.items
            }
          });
        }
      });
    };

    _this.onDragStart = function () {
      _this.setState({ dragging: true }, function () {
        if (this.props.onDragStart) {
          this.props.onDragStart();
        }
      });
    };

    _this.onDragStop = function () {
      _this.setState({ dragging: false }, function () {
        if (this.props.onDragStop) {
          this.props.onDragStop();
        }
      });
    };

    _this.render = function () {
      var items = _this.state.items;


      return _react2.default.createElement(
        'div',
        { className: _style2.default['sortable-list-container'], ref: function ref(c) {
            return _this._sortableList = c;
          } },
        _react2.default.createElement(
          'div',
          { className: _style2.default['sortable-list'] },
          items.map(function (item, i) {
            return _react2.default.createElement(_SortableItem2.default, { key: item.value,
              index: i,
              value: item.value,
              text: item.text,
              active: item.active,
              moveSortableItem: _this.moveSortableItem,
              toggleSortableItem: _this.toggleSortableItem,
              getDimensions: _this.handleResize,
              onDragStart: _this.onDragStart,
              onDragStop: _this.onDragStop,
              count: items.length });
          })
        ),
        _this.state.dragging ? _react2.default.createElement(_CustomDragLayer2.default, { dimensions: { width: _this.state.width, top: _this.state.top }, count: _this.state.items.length }) : null
      );
    };

    return _this;
  }

  return SortableList;
}(_react2.default.Component);

SortableList.propTypes = {
  /**
   * Items to display in the list.
   */
  items: _react2.default.PropTypes.array.isRequired,
  /**
   * Name of the SortableList.
   */
  name: _react2.default.PropTypes.string,
  /**
   * A callback function to be called when the order of the items changes or when an item is toggled.
   */
  changeCallback: _react2.default.PropTypes.func,
  /**
   * A callback function to be called when dragging starts.
   */
  onDragStart: _react2.default.PropTypes.func,
  /**
   * A callback function to be called when dragging stops.
   */
  onDragStop: _react2.default.PropTypes.func,
  /**
   * Optional styles to add to the SortableList component.
   */
  optClass: _react2.default.PropTypes.string
};
exports.default = (0, _reactDnd.DragDropContext)(_reactDndHtml5Backend2.default)(SortableList);