/**
 * 下拉菜单模块
 * date:2019-07-12   License By http://easyweb.vip
 */
layui.define(['jquery'], function (exports) {
    var $ = layui.jquery;
    var openClass = 'dropdown-open';
    var disableClass = 'dropdown-disabled';
    var noScrollClass = 'dropdown-no-scroll';
    var shadeClass = 'dropdown-menu-shade';
    var dropdownClass = 'dropdown-menu';
    var dropNavClass = 'dropdown-menu-nav';
    var hoverClass = 'dropdown-hover';
    var fixedClass = 'fixed';
    var noShadeClass = 'no-shade';
    var animClass = 'layui-anim layui-anim-upbit';
    var dropDirect = ['bottom-left', 'bottom-right', 'bottom-center', 'top-left', 'top-right', 'top-center', 'left-top', 'left-bottom', 'left-center', 'right-top', 'right-bottom', 'right-center'];
    layui.link(layui.cache.base + 'dropdown/dropdown.css');

    var dropdown = {
        // 绑定事件
        init: function () {
            // 点击触发
            $(document).off('click.dropdown').on('click.dropdown', '.' + dropdownClass + '>*:first-child', function (event) {
                var $drop = $(this).parent();
                if (!$drop.hasClass(hoverClass)) {
                    if ($drop.hasClass(openClass)) {
                        $drop.removeClass(openClass);
                    } else {
                        dropdown.show($(this).parent().find('.' + dropNavClass));
                    }
                }
                event.stopPropagation();
            });
            // 点击任何位置关闭所有
            $(document).off('click.dropHide').on('click.dropHide', function (event) {
                dropdown.hideAll();
            });
            // 点击下拉菜单内容部分不关闭
            $(document).off('click.dropNav').on('click.dropNav', '.' + dropNavClass, function (event) {
                event.stopPropagation();
            });
            // hover触发
            var timer, lastDrop;
            $(document).off('mouseenter.dropdown').on('mouseenter.dropdown', '.' + dropdownClass + '.' + hoverClass, function (event) {
                if (lastDrop && lastDrop == event.currentTarget) {
                    clearTimeout(timer);
                }
                dropdown.show($(this).find('.' + dropNavClass));
            });
            $(document).off('mouseleave.dropdown').on('mouseleave.dropdown', '.' + dropdownClass + '.' + hoverClass, function (event) {
                lastDrop = event.currentTarget;
                timer = setTimeout(function () {
                    $(event.currentTarget).removeClass(openClass);
                }, 300);
            });
            // 分离式绑定
            $(document).off('click.dropStand').on('click.dropStand', '[data-dropdown]', function (event) {
                dropdown.showFixed($(this));
                event.stopPropagation();
            });
        },
        // 点击菜单关闭
        openClickNavClose: function () {
            $(document).off('click.dropNavA').on('click.dropNavA', '.' + dropNavClass + '>li>a', function (event) {
                dropdown.hideAll();
                $(this).parentsUntil('.' + dropdownClass).parent().removeClass(openClass);
                event.stopPropagation();
            });
        },
        // 关闭所有
        hideAll: function () {
            $('.' + dropdownClass).removeClass(openClass);
            // 隐藏分离式菜单
            $('.' + dropNavClass + '.' + fixedClass).addClass('layui-hide');  // 隐藏分离式菜单
            $('.' + shadeClass).remove();  // 移除遮罩层
            $('body').removeClass(noScrollClass);  // 移除禁止页面滚动
            $('.dropdown-fixParent').removeClass('dropdown-fixParent');
            $('[data-dropdown]').removeClass(openClass);
        },
        // 展开非分离式下拉菜单
        show: function ($dropNav) {
            if ($dropNav && $dropNav.length > 0 && !$dropNav.hasClass(disableClass)) {
                $dropNav.addClass(animClass);
                var position;  // 获取位置
                for (var i = 0; i < dropDirect.length; i++) {
                    if ($dropNav.hasClass('dropdown-' + dropDirect[i])) {
                        position = dropDirect[i];
                        break;
                    }
                }
                if (!position) {  // 没有设置位置添加默认位置
                    $dropNav.addClass('dropdown-' + dropDirect[0]);
                    position = dropDirect[0];
                }
                dropdown.forCenter($dropNav, position);
                $dropNav.parent('.' + dropdownClass).addClass(openClass);
                return position;
            }
            return false;
        },
        // 展开分离式菜单
        showFixed: function ($trigger) {
            var $dropNav = $($trigger.data('dropdown')), position;
            if (!$dropNav.hasClass('layui-hide')) {
                dropdown.hideAll();  // 已经展开则隐藏
                return;
            }
            position = dropdown.show($dropNav);  // 获取弹出位置
            if (position) {
                $dropNav.addClass(fixedClass);  // 设置为固定定位
                $dropNav.removeClass('layui-hide');  // 显示下拉菜单
                var topLeft = dropdown.getTopLeft($trigger, $dropNav, position);  // 计算坐标
                topLeft = dropdown.checkPosition($dropNav, $trigger, position, topLeft); // 是否溢出屏幕
                $dropNav.css(topLeft);  // 设置坐标
                $('body').addClass(noScrollClass); // 禁止页面滚动
                var hideShade = ($trigger.attr('no-shade') == 'true');  // 是否隐藏遮罩层
                $('body').append('<div class="' + (hideShade ? (shadeClass + ' ' + noShadeClass) : shadeClass) + ' layui-anim layui-anim-fadein"></div>');  // 添加遮罩层
                // 重置父元素z-index
                $trigger.parentsUntil('body').each(function () {
                    var zIndex = $(this).css('z-index');
                    if (/[0-9]+/.test(zIndex)) {
                        $(this).addClass('dropdown-fixParent');
                    }
                });
                $trigger.addClass(openClass);
            }
        },
        // 解决绝对定位因动画导致平移失效
        forCenter: function ($dropNav, position) {
            if (!$dropNav.hasClass(fixedClass)) {
                var wTrigger = $dropNav.parent().outerWidth(), hTrigger = $dropNav.parent().outerHeight();
                var wDrop = $dropNav.outerWidth(), hDrop = $dropNav.outerHeight();
                var pParts = position.split('-'), dropSide = pParts[0], dropPosition = pParts[1];  // 显示方向
                if ((dropSide == 'top' || dropSide == 'bottom') && dropPosition == 'center') {
                    $dropNav.css('left', (wTrigger - wDrop) / 2);
                }
                if ((dropSide == 'left' || dropSide == 'right') && dropPosition == 'center') {
                    $dropNav.css('top', (hTrigger - hDrop) / 2);
                }
            }
        },
        // 计算固定定位坐标
        getTopLeft: function ($trigger, $dropdown, position) {
            var widthTrigger = $trigger.outerWidth();
            var heightTrigger = $trigger.outerHeight();
            var widthDropdown = $dropdown.outerWidth();
            var heightDropdown = $dropdown.outerHeight();
            var topTrigger = $trigger.offset().top - $(document).scrollTop();
            var leftTrigger = $trigger.offset().left;
            var rightTrigger = leftTrigger + widthTrigger;
            var top = 0, left = 0;
            var positionParts = position.split('-');
            var anchorSide = positionParts[0];  // 箭头位置
            var anchorPosition = positionParts[1];  // 箭头方向
            if (anchorSide == 'top' || anchorSide == 'bottom') {
                heightDropdown += 8; // 加上margin距离
                switch (anchorPosition) {
                    case 'left':
                        left = leftTrigger;
                        break;
                    case 'center':
                        left = leftTrigger - widthDropdown / 2 + widthTrigger / 2;
                        break;
                    case 'right':
                        left = rightTrigger - widthDropdown;
                }
            }
            if (anchorSide == 'left' || anchorSide == 'right') {
                widthDropdown += 8;  // 加上margin距离
                switch (anchorPosition) {
                    case 'top':
                        top = topTrigger + heightTrigger - heightDropdown;
                        break;
                    case 'center':
                        top = topTrigger - heightDropdown / 2 + heightTrigger / 2;
                        break;
                    case 'bottom':
                        top = topTrigger;
                }
            }
            switch (anchorSide) {
                case 'top':
                    top = topTrigger - heightDropdown;
                    break;
                case 'right':
                    left = leftTrigger + widthTrigger;
                    break;
                case 'bottom':
                    top = topTrigger + heightTrigger;
                    break;
                case 'left':
                    left = leftTrigger - widthDropdown;
            }
            return {top: top, left: left, right: 'auto', bottom: 'auto'};
        },
        // 检查是否溢出屏幕
        checkPosition: function ($dropNav, $trigger, position, topLeft) {
            var aps = position.split('-');
            if ('bottom' == aps[0]) {
                if ((topLeft.top + $dropNav.outerHeight()) > dropdown.getPageHeight()) {
                    topLeft = dropdown.getTopLeft($trigger, $dropNav, 'top-' + aps[1]);
                    $dropNav.removeClass('dropdown-' + position);
                    $dropNav.addClass('dropdown-top-' + aps[1]);
                }
            } else if ('top' == aps[0]) {
                if (topLeft.top < 0) {
                    topLeft = dropdown.getTopLeft($trigger, $dropNav, 'bottom-' + aps[1]);
                    $dropNav.removeClass('dropdown-' + position);
                    $dropNav.addClass('dropdown-bottom-' + aps[1]);
                }
            }
            return topLeft;
        },
        // 获取浏览器高度
        getPageHeight: function () {
            return document.documentElement.clientHeight || document.body.clientHeight;
        },
        // 获取浏览器宽度
        getPageWidth: function () {
            return document.documentElement.clientWidth || document.body.clientWidth;
        }
    };

    dropdown.init();
    exports('dropdown', dropdown);
});
