/**
 * nav
 * 导航菜单组件
 */

layui.define('component', function(exports) {
  'use strict';

  var $ = layui.$;
  var device = layui.device();
  var SUPER_MOD_NAME = 'element'; // 所属的超级模块名，确保向下兼容

  // 创建组件
  var component = layui.component({
    name: 'nav', // 组件名

    // 默认配置
    config: {
      elem: '.layui-nav'
    },

    CONST: {
      NAV_ELEM: '.layui-nav',
      NAV_ITEM: 'layui-nav-item',
      NAV_BAR: 'layui-nav-bar',
      NAV_TREE: 'layui-nav-tree',
      NAV_CHILD: 'layui-nav-child',
      NAV_CHILD_C: 'layui-nav-child-c',
      NAV_MORE: 'layui-nav-more',
      NAV_DOWN: 'layui-icon-down',
      NAV_ANIM: 'layui-anim layui-anim-upbit',
    },

    // 渲染
    render: function() {
      var that = this;
      var options = that.config;

      var TIME = 200;
      var timer = {};
      var timerMore = {};
      var timeEnd = {};
      var NAV_TITLE = 'layui-nav-title';

      // 滑块跟随
      var follow = function(bar, nav, index) {
        var othis = $(this);
        var child = othis.find('.'+ CONST.NAV_CHILD);

        // 是否垂直导航菜单
        if (nav.hasClass(CONST.NAV_TREE)) {
          // 无子菜单时跟随
          if (!child[0]) {
            var thisA = othis.children('.'+ NAV_TITLE);
            bar.css({
              top: othis.offset().top - nav.offset().top + nav.scrollTop(),
              height: (thisA[0] ? thisA : othis).outerHeight(),
              opacity: 1
            });
          }
        } else {
          child.addClass(CONST.NAV_ANIM);

          // 若居中对齐
          if (child.hasClass(CONST.NAV_CHILD_C)) {
            child.css({
              left: -(child.outerWidth() - othis.width()) / 2
            });
          }

          // 滑块定位
          if (child[0]) { // 若有子菜单，则滑块消失
            bar.css({
              left: bar.position().left + bar.width() / 2,
              width: 0,
              opacity: 0
            });
          } else { // bar 跟随
            bar.css({
              left: othis.position().left + parseFloat(othis.css('marginLeft')),
              top: othis.position().top + othis.height() - bar.height()
            });
          }

          // 渐显滑块并适配宽度
          timer[index] = setTimeout(function() {
            bar.css({
              width: child[0] ? 0 : othis.width(),
              opacity: child[0] ? 0 : 1
            });
          }, device.ie && device.ie < 10 ? 0 : TIME);

          // 显示子菜单
          clearTimeout(timeEnd[index]);
          if (child.css('display') === 'block') {
            clearTimeout(timerMore[index]);
          }
          timerMore[index] = setTimeout(function(){
            child.addClass(CONST.CLASS_SHOW);
            othis.find('.'+ CONST.NAV_MORE).addClass(CONST.NAV_MORE +'d');
          }, 300);
        }
      };

      // 遍历导航
      options.elem.each(function(index) {
        var othis = $(this);
        var bar = $('<span class="'+ CONST.NAV_BAR +'"></span>');
        var itemElem = othis.find('.'+ CONST.NAV_ITEM);

        // hover 滑动效果
        var hasBarElem = othis.find('.'+CONST.NAV_BAR);
        if (hasBarElem[0]) hasBarElem.remove();
        othis.append(bar);
        ( othis.hasClass(CONST.NAV_TREE)
          ? itemElem.find('dd,>.'+ CONST.NAV_TITLE)
          : itemElem
        ).off('mouseenter.lay_nav').on('mouseenter.lay_nav', function() {
          follow.call(this, bar, othis, index);
        }).off('mouseleave.lay_nav').on('mouseleave.lay_nav', function() { // 鼠标移出
          // 是否为垂直导航
          if (othis.hasClass(CONST.NAV_TREE)) {
            bar.css({
              height: 0,
              opacity: 0
            });
          } else {
            // 隐藏子菜单
            clearTimeout(timerMore[index]);
            timerMore[index] = setTimeout(function(){
              othis.find('.'+ CONST.NAV_CHILD).removeClass(CONST.CLASS_SHOW);
              othis.find('.'+ CONST.NAV_MORE).removeClass(CONST.NAV_MORE +'d');
            }, 300);
          }
        });

        // 鼠标离开当前菜单时
        othis.off('mouseleave.lay_nav').on('mouseleave.lay_nav', function() {
          clearTimeout(timer[index])
          timeEnd[index] = setTimeout(function() {
            if (!othis.hasClass(CONST.NAV_TREE)) {
              bar.css({
                width: 0,
                left: bar.position().left + bar.width() / 2,
                opacity: 0
              });
            }
          }, TIME);
        });

        // 展开子菜单
        itemElem.find('a').each(function() {
          var thisA = $(this);
          var child = thisA.siblings('.'+ CONST.NAV_CHILD);
          var clickEventName = 'click.lay_nav_click';

          // 输出小箭头
          if (child[0] && !thisA.children('.'+ CONST.NAV_MORE)[0]) {
            thisA.append('<i class="layui-icon '+ CONST.NAV_DOWN +' '+ CONST.NAV_MORE +'"></i>');
          }

          // 点击菜单
          thisA.off(clickEventName, events.clickThis).on(clickEventName, events.clickThis);
        });
      });
    }
  });

  var events = {
    // 点击当前菜单 - a 标签触发
    clickThis: function() {
      var othis = $(this);
      var parents = othis.closest(CONST.NAV_ELEM);
      var filter = parents.attr('lay-filter');
      var parent = othis.parent() ;
      var child = othis.siblings('.'+ CONST.NAV_CHILD);
      var unselect = typeof parent.attr('lay-unselect') === 'string'; // 是否禁用选中

      // 满足点击选中的条件
      if (!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect) {
        if (!child[0]) {
          parents.find('.'+ CONST.CLASS_THIS).removeClass(CONST.CLASS_THIS);
          parent.addClass(CONST.CLASS_THIS);
        }
      }

      // 若为垂直菜单
      if (parents.hasClass(CONST.NAV_TREE)) {
        var NAV_ITEMED = CONST.NAV_ITEM + 'ed'; // 用于标注展开状态
        var needExpand = !parent.hasClass(NAV_ITEMED); // 是否执行展开
        var ANIM_MS = 200; // 动画过渡毫秒数

        // 动画执行完成后的操作
        var complete = function() {
          $(this).css({
            "display": "" // 剔除动画生成的 style display，以适配外部样式的状态重置
          });
          // 避免导航滑块错位
          parents.children('.'+ CONST.NAV_BAR).css({
            opacity: 0
          })
        };

        // 是否正处于动画中的状态
        if (child.is(':animated')) return;

        // 剔除可能存在的 CSS3 动画类
        child.removeClass(CONST.NAV_ANIM);

        // 若有子菜单，则对其执行展开或收缩
        if (child[0]) {
          if (needExpand) {
            // 先执行 slideDown 动画，再标注展开状态样式，避免元素 `block` 状态导致动画无效
            child.slideDown(ANIM_MS, complete);
            parent.addClass(NAV_ITEMED);
          } else {
            // 先取消展开状态样式，再将元素临时显示，避免 `none` 状态导致 slideUp 动画无效
            parent.removeClass(NAV_ITEMED);
            child.show().slideUp(ANIM_MS, complete);
          }

          // 手风琴 --- 收缩兄弟展开项
          if (typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all') {
            var parentSibs = parent.siblings('.'+ NAV_ITEMED);
            parentSibs.removeClass(NAV_ITEMED);
            parentSibs.children('.'+ CONST.NAV_CHILD).show().stop().slideUp(ANIM_MS, complete);
          }
        }
      }

      layui.event.call(this, SUPER_MOD_NAME, 'nav('+ filter +')', othis);
    }
  };

  var CONST = component.CONST;

  // export
  exports(CONST.MOD_NAME, component);
});
