'use strict';

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

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

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

var _propTypes2 = _interopRequireDefault(_propTypes);

var _createReactClass = require('create-react-class');

var _createReactClass2 = _interopRequireDefault(_createReactClass);

var _SubPopupMenu = require('./SubPopupMenu');

var _SubPopupMenu2 = _interopRequireDefault(_SubPopupMenu);

var _KeyCode = require('rc-util/lib/KeyCode');

var _KeyCode2 = _interopRequireDefault(_KeyCode);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _util = require('./util');

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

var guid = 0;

/* eslint react/no-is-mounted:0 */

var SubMenu = (0, _createReactClass2["default"])({
  displayName: 'SubMenu',

  propTypes: {
    parentMenu: _propTypes2["default"].object,
    title: _propTypes2["default"].node,
    children: _propTypes2["default"].any,
    selectedKeys: _propTypes2["default"].array,
    openKeys: _propTypes2["default"].array,
    onClick: _propTypes2["default"].func,
    onOpenChange: _propTypes2["default"].func,
    rootPrefixCls: _propTypes2["default"].string,
    eventKey: _propTypes2["default"].string,
    multiple: _propTypes2["default"].bool,
    active: _propTypes2["default"].bool,
    onSelect: _propTypes2["default"].func,
    closeSubMenuOnMouseLeave: _propTypes2["default"].bool,
    openSubMenuOnMouseEnter: _propTypes2["default"].bool,
    onDeselect: _propTypes2["default"].func,
    onDestroy: _propTypes2["default"].func,
    onItemHover: _propTypes2["default"].func,
    onMouseEnter: _propTypes2["default"].func,
    onMouseLeave: _propTypes2["default"].func,
    onTitleMouseEnter: _propTypes2["default"].func,
    onTitleMouseLeave: _propTypes2["default"].func,
    onTitleClick: _propTypes2["default"].func
  },

  mixins: [require('./SubMenuStateMixin')],

  getDefaultProps: function getDefaultProps() {
    return {
      onMouseEnter: _util.noop,
      onMouseLeave: _util.noop,
      onTitleMouseEnter: _util.noop,
      onTitleMouseLeave: _util.noop,
      onTitleClick: _util.noop,
      title: ''
    };
  },
  getInitialState: function getInitialState() {
    this.isSubMenu = 1;
    return {
      defaultActiveFirst: false
    };
  },
  componentWillUnmount: function componentWillUnmount() {
    var _props = this.props,
        onDestroy = _props.onDestroy,
        eventKey = _props.eventKey,
        parentMenu = _props.parentMenu;

    if (onDestroy) {
      onDestroy(eventKey);
    }
    if (parentMenu.subMenuInstance === this) {
      this.clearSubMenuTimers();
    }
  },
  onDestroy: function onDestroy(key) {
    this.props.onDestroy(key);
  },
  onKeyDown: function onKeyDown(e) {
    var keyCode = e.keyCode;
    var menu = this.menuInstance;
    var isOpen = this.isOpen();

    if (keyCode === _KeyCode2["default"].ENTER) {
      this.onTitleClick(e);
      this.setState({
        defaultActiveFirst: true
      });
      return true;
    }

    if (keyCode === _KeyCode2["default"].RIGHT) {
      if (isOpen) {
        menu.onKeyDown(e);
      } else {
        this.triggerOpenChange(true);
        this.setState({
          defaultActiveFirst: true
        });
      }
      return true;
    }
    if (keyCode === _KeyCode2["default"].LEFT) {
      var handled = void 0;
      if (isOpen) {
        handled = menu.onKeyDown(e);
      } else {
        return undefined;
      }
      if (!handled) {
        this.triggerOpenChange(false);
        handled = true;
      }
      return handled;
    }

    if (isOpen && (keyCode === _KeyCode2["default"].UP || keyCode === _KeyCode2["default"].DOWN)) {
      return menu.onKeyDown(e);
    }
  },
  onOpenChange: function onOpenChange(e) {
    this.props.onOpenChange(e);
  },
  onMouseEnter: function onMouseEnter(e) {
    var props = this.props;
    this.clearSubMenuLeaveTimer(props.parentMenu.subMenuInstance !== this);
    props.onMouseEnter({
      key: props.eventKey,
      domEvent: e
    });
  },
  onTitleMouseEnter: function onTitleMouseEnter(domEvent) {
    var props = this.props;
    var parentMenu = props.parentMenu,
        key = props.eventKey;

    var item = this;
    this.clearSubMenuTitleLeaveTimer(parentMenu.subMenuInstance !== item);
    if (parentMenu.menuItemInstance) {
      parentMenu.menuItemInstance.clearMenuItemMouseLeaveTimer(true);
    }
    var openChanges = [];
    if (props.openSubMenuOnMouseEnter) {
      openChanges.push({
        key: key,
        item: item,
        trigger: 'mouseenter',
        open: true
      });
    }
    props.onItemHover({
      key: key,
      item: item,
      hover: true,
      trigger: 'mouseenter',
      openChanges: openChanges
    });
    this.setState({
      defaultActiveFirst: false
    });
    props.onTitleMouseEnter({
      key: key,
      domEvent: domEvent
    });
  },
  onTitleMouseLeave: function onTitleMouseLeave(e) {
    var _this = this;

    var props = this.props;
    var parentMenu = props.parentMenu,
        eventKey = props.eventKey;

    parentMenu.subMenuInstance = this;
    parentMenu.subMenuTitleLeaveFn = function () {
      // leave whole sub tree
      // still active
      if (props.mode === 'inline' && props.active) {
        props.onItemHover({
          key: eventKey,
          item: _this,
          hover: false,
          trigger: 'mouseleave'
        });
      }
      props.onTitleMouseLeave({
        key: props.eventKey,
        domEvent: e
      });
    };
    parentMenu.subMenuTitleLeaveTimer = setTimeout(parentMenu.subMenuTitleLeaveFn, 100);
  },
  onMouseLeave: function onMouseLeave(e) {
    var _this2 = this;

    var props = this.props;
    var parentMenu = props.parentMenu,
        eventKey = props.eventKey;

    parentMenu.subMenuInstance = this;
    parentMenu.subMenuLeaveFn = function () {
      // leave whole sub tree
      // still active
      if (props.mode !== 'inline') {
        var isOpen = _this2.isOpen();
        if (isOpen && props.closeSubMenuOnMouseLeave && props.active) {
          props.onItemHover({
            key: eventKey,
            item: _this2,
            hover: false,
            trigger: 'mouseleave',
            openChanges: [{
              key: eventKey,
              item: _this2,
              trigger: 'mouseleave',
              open: false
            }]
          });
        } else {
          if (props.active) {
            props.onItemHover({
              key: eventKey,
              item: _this2,
              hover: false,
              trigger: 'mouseleave'
            });
          }
          if (isOpen && props.closeSubMenuOnMouseLeave) {
            _this2.triggerOpenChange(false);
          }
        }
      }
      // trigger mouseleave
      props.onMouseLeave({
        key: eventKey,
        domEvent: e
      });
    };
    // prevent popup menu and submenu gap
    parentMenu.subMenuLeaveTimer = setTimeout(parentMenu.subMenuLeaveFn, 100);
  },
  onTitleClick: function onTitleClick(e) {
    var props = this.props;

    props.onTitleClick({
      key: props.eventKey,
      domEvent: e
    });
    if (props.openSubMenuOnMouseEnter) {
      return;
    }
    this.triggerOpenChange(!this.isOpen(), 'click');
    this.setState({
      defaultActiveFirst: false
    });
  },
  onSubMenuClick: function onSubMenuClick(info) {
    this.props.onClick(this.addKeyPath(info));
  },
  onSelect: function onSelect(info) {
    this.props.onSelect(info);
  },
  onDeselect: function onDeselect(info) {
    this.props.onDeselect(info);
  },
  getPrefixCls: function getPrefixCls() {
    return this.props.rootPrefixCls + '-submenu';
  },
  getActiveClassName: function getActiveClassName() {
    return this.getPrefixCls() + '-active';
  },
  getDisabledClassName: function getDisabledClassName() {
    return this.getPrefixCls() + '-disabled';
  },
  getSelectedClassName: function getSelectedClassName() {
    return this.getPrefixCls() + '-selected';
  },
  getOpenClassName: function getOpenClassName() {
    return this.props.rootPrefixCls + '-submenu-open';
  },
  saveMenuInstance: function saveMenuInstance(c) {
    this.menuInstance = c;
  },
  addKeyPath: function addKeyPath(info) {
    return (0, _extends3["default"])({}, info, {
      keyPath: (info.keyPath || []).concat(this.props.eventKey)
    });
  },
  triggerOpenChange: function triggerOpenChange(open, type) {
    var key = this.props.eventKey;
    this.onOpenChange({
      key: key,
      item: this,
      trigger: type,
      open: open
    });
  },
  clearSubMenuTimers: function clearSubMenuTimers() {
    var callFn = void 0;
    this.clearSubMenuLeaveTimer(callFn);
    this.clearSubMenuTitleLeaveTimer(callFn);
  },
  clearSubMenuTitleLeaveTimer: function clearSubMenuTitleLeaveTimer() {
    var callFn = void 0;
    var parentMenu = this.props.parentMenu;
    if (parentMenu.subMenuTitleLeaveTimer) {
      clearTimeout(parentMenu.subMenuTitleLeaveTimer);
      parentMenu.subMenuTitleLeaveTimer = null;
      if (callFn && parentMenu.subMenuTitleLeaveFn) {
        parentMenu.subMenuTitleLeaveFn();
      }
      parentMenu.subMenuTitleLeaveFn = null;
    }
  },
  clearSubMenuLeaveTimer: function clearSubMenuLeaveTimer() {
    var callFn = void 0;
    var parentMenu = this.props.parentMenu;
    if (parentMenu.subMenuLeaveTimer) {
      clearTimeout(parentMenu.subMenuLeaveTimer);
      parentMenu.subMenuLeaveTimer = null;
      if (callFn && parentMenu.subMenuLeaveFn) {
        parentMenu.subMenuLeaveFn();
      }
      parentMenu.subMenuLeaveFn = null;
    }
  },
  isChildrenSelected: function isChildrenSelected() {
    var ret = { find: false };
    (0, _util.loopMenuItemRecusively)(this.props.children, this.props.selectedKeys, ret);
    return ret.find;
  },
  isOpen: function isOpen() {
    return this.props.openKeys.indexOf(this.props.eventKey) !== -1;
  },
  renderChildren: function renderChildren(children) {
    var props = this.props;
    var baseProps = {
      mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
      visible: this.isOpen(),
      level: props.level + 1,
      inlineIndent: props.inlineIndent,
      focusable: false,
      onClick: this.onSubMenuClick,
      onSelect: this.onSelect,
      onDeselect: this.onDeselect,
      onDestroy: this.onDestroy,
      selectedKeys: props.selectedKeys,
      eventKey: props.eventKey + '-menu-',
      openKeys: props.openKeys,
      openTransitionName: props.openTransitionName,
      openAnimation: props.openAnimation,
      onOpenChange: this.onOpenChange,
      closeSubMenuOnMouseLeave: props.closeSubMenuOnMouseLeave,
      defaultActiveFirst: this.state.defaultActiveFirst,
      multiple: props.multiple,
      prefixCls: props.rootPrefixCls,
      id: this._menuId,
      ref: this.saveMenuInstance
    };
    return _react2["default"].createElement(
      _SubPopupMenu2["default"],
      baseProps,
      children
    );
  },
  render: function render() {
    var _classes;

    var isOpen = this.isOpen();
    this.haveOpen = this.haveOpen || isOpen;
    var props = this.props;
    var prefixCls = this.getPrefixCls();
    var classes = (_classes = {}, (0, _defineProperty3["default"])(_classes, props.className, !!props.className), (0, _defineProperty3["default"])(_classes, prefixCls + '-' + props.mode, 1), _classes);

    classes[this.getOpenClassName()] = isOpen;
    classes[this.getActiveClassName()] = props.active;
    classes[this.getDisabledClassName()] = props.disabled;
    classes[this.getSelectedClassName()] = this.isChildrenSelected();

    if (!this._menuId) {
      if (props.eventKey) {
        this._menuId = props.eventKey + '$Menu';
      } else {
        this._menuId = '$__$' + ++guid + '$Menu';
      }
    }

    classes[prefixCls] = true;
    classes[prefixCls + '-' + props.mode] = 1;
    var titleClickEvents = {};
    var mouseEvents = {};
    var titleMouseEvents = {};
    if (!props.disabled) {
      titleClickEvents = {
        onClick: this.onTitleClick
      };
      mouseEvents = {
        onMouseLeave: this.onMouseLeave,
        onMouseEnter: this.onMouseEnter
      };
      // only works in title, not outer li
      titleMouseEvents = {
        onMouseEnter: this.onTitleMouseEnter,
        onMouseLeave: this.onTitleMouseLeave
      };
    }
    var style = {};
    if (props.mode === 'inline') {
      style.paddingLeft = props.inlineIndent * props.level;
    }
    return _react2["default"].createElement(
      'li',
      (0, _extends3["default"])({ className: (0, _classnames2["default"])(classes) }, mouseEvents),
      _react2["default"].createElement(
        'div',
        (0, _extends3["default"])({
          style: style,
          className: prefixCls + '-title'
        }, titleMouseEvents, titleClickEvents, {
          'aria-expanded': isOpen,
          'aria-owns': this._menuId,
          'aria-haspopup': 'true',
          title: typeof props.title === 'string' ? props.title : undefined
        }),
        props.title
      ),
      this.renderChildren(props.children)
    );
  }
});

SubMenu.isSubMenu = 1;

exports["default"] = SubMenu;
module.exports = exports['default'];