'use strict';

exports.__esModule = true;

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

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

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);

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

/**
 * Tab is supplemental, non-clickable component used to help bring attention to an item or object.
 * @param props
 * @returns {XML}
 * @constructor
 */
var TabList = function (_React$Component) {
  (0, _inherits3.default)(TabList, _React$Component);

  function TabList() {
    var _temp, _this, _ret;

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

    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, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.determineInitialFocus = function () {
      var children = _this.props.children;
      var focus = _this.context.focus;

      var childrenList = _react2.default.Children.toArray(children);

      if (focus > childrenList.length - 1 || focus < 0) {
        throw new Error('focusIndex ' + focus + ' is out of bound.');
      }

      var focusIndex = !childrenList[focus].props.disabled ? focus : null;

      _this.setFocus(focusIndex);
      _this.context.onActivate(focusIndex);
    }, _this.setFocus = function (index) {
      // Update state with selected index
      return _this.context.onFocus(index);
    }, _this.handleClick = function (event, index, disabled) {
      if (disabled) {
        event.preventDefault();
        event.stopPropagation();
      }
      _this.setFocus(index);
      return _this.context.onActivate(index);
    }, _this.getIncludesFirstCharacter = function (str, char) {
      return str.charAt(0).toLowerCase().includes(char);
    }, _this.setFocusByFirstCharacter = function (char, currentIdx, length) {
      var children = _this.props.children;


      var newIndex = _react2.default.Children.toArray(children).reduce(function (agg, child, idx, arr) {
        var index = currentIdx + idx + 1 > length ? Math.abs(currentIdx + idx - length) : currentIdx + idx + 1;
        var label = arr[index].props.role === 'menuItem' ? arr[index].props.label : arr[index].props.heading;

        return !agg.length && !arr[index].props.disabled && _this.getIncludesFirstCharacter(label, char) ? agg.concat(index) : agg;
      }, []);

      _this.setFocus(newIndex[0]);
    }, _this.handleListKeyPress = function (e, idx, length, disabled) {
      if (disabled) {
        e.preventDefault();
        e.stopPropagation();
      }

      var newIndex = void 0,
          clickEvent = void 0;
      var tgt = e.currentTarget;
      var char = e.key;
      var flag = false;

      var getNewIndex = function getNewIndex(currentIndex, change) {
        var getPossibleIndex = function getPossibleIndex() {
          if (currentIndex + change < 0) {
            return length;
          } else if (currentIndex + change > length) {
            return 0;
          }

          return currentIndex + change;
        };
        var possibleIndex = getPossibleIndex();
        return _react2.default.Children.toArray(_this.props.children)[possibleIndex].props.disabled ? getNewIndex(possibleIndex, change) : possibleIndex;
      };

      var isPrintableCharacter = function isPrintableCharacter(str) {
        return str.length === 1 && str.match(/\S/);
      };
      switch (e.which) {
        case 32:
        case 13:
          try {
            clickEvent = new MouseEvent('click', {
              view: window,
              bubbles: true,
              cancelable: true
            });
          } catch (err) {
            if (document.createEvent) {
              // DOM Level 3 for IE 9+
              clickEvent = document.createEvent('MouseEvents');
              clickEvent.initEvent('click', true, true);
            }
          }
          tgt.dispatchEvent(clickEvent);

          flag = true;
          break;

        case 38:
        case 37:
          // console.log('leftarrow');
          newIndex = getNewIndex(idx, -1);
          _this.setFocus(newIndex);
          flag = true;
          break;

        case 39:
        case 40:
          newIndex = getNewIndex(idx, 1);
          _this.setFocus(newIndex);
          flag = true;
          break;

        case 33:
        case 36:
          _this.setFocus(0);
          flag = true;
          break;

        case 34:
        case 35:
          _this.setFocus(length);
          flag = true;
          break;
        default:
          if (isPrintableCharacter(char)) {
            _this.setFocusByFirstCharacter(char, idx, length);
            flag = true;
          }
          break;
      }

      if (flag) {
        e.stopPropagation();
        e.preventDefault();
      }
    }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
  }

  TabList.prototype.componentDidMount = function componentDidMount() {
    this.determineInitialFocus();
  };

  TabList.prototype.render = function render() {
    var _this2 = this;

    var _props = this.props,
        children = _props.children,
        role = _props.role;
    var _context = this.context,
        activeIndex = _context.activeIndex,
        focus = _context.focus;


    var setTabs = function setTabs() {
      return _react2.default.Children.map(children, function (child, idx) {
        var arrLength = children.length - 1;
        var disabled = child.props.disabled;
        return _react2.default.cloneElement(child, {
          active: activeIndex === idx,
          focus: focus === idx,
          onPress: function onPress(e) {
            return _this2.handleClick(e, idx, disabled);
          },
          onKeyDown: function onKeyDown(e) {
            return _this2.handleListKeyPress(e, idx, arrLength, disabled);
          },
          refName: 'navLink'
        });
      });
    };

    return _react2.default.createElement(
      'ul',
      {
        className: 'cui-tab__list',
        role: role
      },
      setTabs()
    );
  };

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

TabList.displayName = 'TabList';
exports.default = TabList;


TabList.contextTypes = {
  /**
   * optional active prop type
   */
  onFocus: _propTypes2.default.func,
  /**
   * optional active prop type
   */
  focus: _propTypes2.default.number,
  /**
   * optional active prop type
   */
  activeIndex: _propTypes2.default.number,
  /**
   * optional active prop type
   */
  onActivate: _propTypes2.default.func
};

TabList.defaultProps = {
  role: 'tablist'
};
module.exports = exports['default'];