'use strict';

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

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

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

var _propTypes2 = _interopRequireDefault(_propTypes);

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

var _DragGroupContainer = require('./styles/DragGroupContainer');

var _DragGroupContainer2 = _interopRequireDefault(_DragGroupContainer);

var _DragGroupItemsContainer = require('./styles/DragGroupItemsContainer');

var _DragGroupItemsContainer2 = _interopRequireDefault(_DragGroupItemsContainer);

var _DragGroupDropArea = require('./DragGroupDropArea');

var _DragGroupDropArea2 = _interopRequireDefault(_DragGroupDropArea);

var _DragGroupSeparator = require('./styles/DragGroupSeparator');

var _DragGroupSeparator2 = _interopRequireDefault(_DragGroupSeparator);

var _DragGroupTitle = require('./styles/DragGroupTitle');

var _DragGroupTitle2 = _interopRequireDefault(_DragGroupTitle);

var _ExpandToggle = require('../../behaviors/ExpandToggle');

var _ExpandToggle2 = _interopRequireDefault(_ExpandToggle);

var _DragGroupItem = require('./DragGroupItem');

var _DragGroupItem2 = _interopRequireDefault(_DragGroupItem);

var _DragContainer = require('../DragContainer');

var _DragContainer2 = _interopRequireDefault(_DragContainer);

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

/**
 * A group of items which can be dragged into other `DragGroups` depending
 * on `itemType`. The ordering of items within a group is arbitrary and non-editable.
 *
 * > **Note:** You must include [BandwidthProvider](/#!/BandwidthProvider)
 * at or near the root of your application to use drag and drop functionality.
 */
var DragGroup = function (_React$Component) {
  (0, _inherits3.default)(DragGroup, _React$Component);

  function DragGroup() {
    var _ref,
        _this2 = this;

    var _temp, _this, _ret;

    (0, _classCallCheck3.default)(this, DragGroup);

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

    return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = DragGroup.__proto__ || (0, _getPrototypeOf2.default)(DragGroup)).call.apply(_ref, [this].concat(args))), _this), _this.calcOverrideExpanded = function () {
      var _this$props = _this.props,
          allowDrag = _this$props.allowDrag,
          canDrop = _this$props.canDrop,
          collapsible = _this$props.collapsible;

      if (!collapsible || !allowDrag || canDrop) {
        return true;
      }

      return null;
    }, _this.shimChild = function (child, index) {
      var _this$props2 = _this.props,
          itemType = _this$props2.itemType,
          allowDrag = _this$props2.allowDrag,
          groupId = _this$props2.groupId;


      return _react2.default.cloneElement(child, {
        itemType: itemType,
        canDrag: allowDrag,
        groupId: groupId
      });
    }, _this.renderTitle = function (expanded) {
      return _this.props.allowDrag ? _react2.default.createElement(
        _this2.props.Title,
        { expanded: expanded, onDelete: _this.props.onRemoved },
        _this.props.name
      ) : null;
    }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
  }

  (0, _createClass3.default)(DragGroup, [{
    key: 'renderInterspersedSeparators',
    value: function renderInterspersedSeparators() {
      var _this3 = this;

      var _props = this.props,
          children = _props.children,
          Separator = _props.Separator,
          onSplit = _props.onSplit,
          separatorContent = _props.separatorContent;

      var childArray = _react2.default.Children.toArray(children);
      return childArray.reduce(function (withSeparators, child, idx) {
        return [].concat((0, _toConsumableArray3.default)(withSeparators), [_react2.default.createElement(
          Separator,
          {
            onClick: function onClick() {
              return onSplit(idx);
            },
            key: 'separator' + (child.key || idx)
          },
          separatorContent
        ), _this3.shimChild(child, idx)]);
      }, []).slice(1); // removing first separator
    }
  }, {
    key: 'render',
    value: function render() {
      var _props2 = this.props,
          Container = _props2.Container,
          ItemsContainer = _props2.ItemsContainer,
          ExpandContentContainer = _props2.ExpandContentContainer,
          DropArea = _props2.DropArea,
          itemType = _props2.itemType,
          groupId = _props2.groupId,
          canDrop = _props2.canDrop;


      return _react2.default.createElement(
        Container,
        null,
        _react2.default.createElement(
          _ExpandToggle2.default,
          {
            startExpanded: true,
            toggleContent: this.renderTitle,
            isExpanded: this.calcOverrideExpanded(),
            springConfig: { stiffness: 200, damping: 20 }
          },
          _react2.default.createElement(
            DropArea,
            { itemType: itemType, groupId: groupId },
            _react2.default.createElement(
              ItemsContainer,
              null,
              this.renderInterspersedSeparators()
            )
          )
        )
      );
    }
  }]);
  return DragGroup;
}(_react2.default.Component);

DragGroup.Item = _DragGroupItem2.default;
DragGroup.Container = _DragContainer2.default;
DragGroup.propTypes = {
  /**
   * Text to render inside the clickable separators which allow
   * new groups to be created.
   */
  separatorContent: _propTypes2.default.node,

  /**
   * Override the outer container visual component
   * Defaults DragGroupContainer
   */
  Container: _propTypes2.default.func,
  /**
   * Override the visual component which wraps the child items
   * Defaults DragGroupItemsContainer
   */
  ItemsContainer: _propTypes2.default.func,
  /**
   * Override the behavioral component which renders the drop area
   * Defaults DragGroupDropArea
   */
  DropArea: _propTypes2.default.func,
  /**
   * Overrides the behavioral component which renders a clickable separator
   * between items.
   * Defaults DragGroupSeparator
   */
  Separator: _propTypes2.default.func,
  /**
   * Overrides the visual component which renders the toggle-enabled title
   * of a group.
   * Defaults DragGroupTitle
   */
  Title: _propTypes2.default.func,

  // The following are provided by DragGroups;
  // they cannot be required, but can be expected.

  /**
   * Provides a name for the group, rendered in the title
   */
  name: _propTypes2.default.string,
  /**
   * The type of items which can be dropped in this group.
   */
  itemType: _propTypes2.default.string,
  /**
   * A unique identifier for this group.
   */
  groupId: _propTypes2.default.any.isRequired,
  /**
   * Provided by parent DragGroups
   * The number of groups in the list
   */
  groupCount: _propTypes2.default.number,
  /**
   * Whether to allow items to be dragged out of this group or not
   */
  allowDrag: _propTypes2.default.bool,
  /**
   * Whether to allow this group to collapse.
   */
  collapsible: _propTypes2.default.bool,
  /**
   * A callback to call when a user inserts a group. Called with (groupId, itemSplitIndex).
   */
  onSplit: _propTypes2.default.func,
  /**
   * Provided by parent DragGroups
   * A callback to call when an item has been dropped on this group
   */
  onItemDropped: _propTypes2.default.func,
  /**
   * A callback to call when this group is removed
   */
  onRemoved: _propTypes2.default.func
};
DragGroup.defaultProps = {
  separatorContent: 'Click here to add a group',

  name: 'Group',

  allowDrag: true,
  collapsible: true,

  Container: _DragGroupContainer2.default,
  ItemsContainer: _DragGroupItemsContainer2.default,
  DropArea: _DragGroupDropArea2.default,
  Separator: _DragGroupSeparator2.default,
  Title: _DragGroupTitle2.default,

  itemType: null,
  groupId: null,
  groupCount: null,
  onSplit: function onSplit() {
    return null;
  },
  onItemDropped: function onItemDropped() {
    return null;
  },
  onRemoved: function onRemoved() {
    return null;
  }
};


var dropSource = {
  drop: function drop(props) {
    return {
      type: 'items',
      groupId: null
    };
  }
};

var collect = function collect(connect, monitor) {
  return {
    canDrop: monitor.canDrop()
  };
};

exports.default = (0, _reactDnd.DropTarget)(function (props) {
  return props.itemType;
}, dropSource, collect)(DragGroup);