/*
 * 特别声明：本技术材料受《中华人民共和国著作权法》、《计算机软件保护条例》等法律、法规、行政
 * 规章以及有关国际条约的保护，赞同科技享有知识产权、保留一切权利并视其为技术秘密。未经本公司书
 * 面许可，任何人不得擅自（包括但不限于：以非法的方式复制、传播、展示、镜像、上载、下载）使用，
 * 不得向第三方泄露、透露、披露。否则，本公司将依法追究侵权者的法律责任。特此声明！
 *
 * Special Declaration: These technical material reserved as the technical secrets by AGREE
 * TECHNOLOGY have been protected by the "Copyright Law" "ordinances on Protection of Computer
 * Software" and other relevant administrative regulations and international treaties. Without
 * the written permission of the Company, no person may use (including but not limited to the
 * illegal copy, distribute, display, image, upload, and download) and disclose the above
 * technical documents to any third party. Otherwise, any infringer shall afford the legal
 * liability to the company.
 */
import {EventHub} from "event/EventHub";
import {Event as AdoreEvent} from "event/Event";
import {MessageType} from "event/MessageType";
/// <reference path="../typings/jquery.d.ts" />
export class TabUtil {
    private static $tab_min_width: number = 60;
    private static movingIconWidth: number = 70; //两个移动图标占用的宽度
    private static movingLeftIconWidth: number = 40;
    private static totalWidthPrefix: number = 30;

    public static handleTabLeftMoveClick(tabFolderId: string) {
        let tabs = $("#" + tabFolderId);
        let indexs = this.getBlockIndexs(tabs);
        let blockBegin = indexs[0], blockEnd = indexs[1];
        if (blockBegin <= 0) {
            return;
        }
        let lis = tabs.find("li.adore_tab");
        let count = this.tabLeftMove(tabs, lis, blockBegin);
        if (count <= 1) {
            this.tabLeftMove(tabs, lis, blockBegin - 1);
        }
        this.resetMovingIcon(tabs, lis);
        this.resetIndicator(tabs, lis);
    }

    public static handleTabRightMoveClick(tabFolderId: string) {
        let tabs = $("#" + tabFolderId);
        let indexs = this.getBlockIndexs(tabs);
        let blockBegin = indexs[0], blockEnd = indexs[1];
        let lis = tabs.find("li.adore_tab");
        if (this.isEndRight(tabs, lis)) {
            return;
        }
        let count = this.tabRightMove(tabs, lis, blockEnd);
        if (count <= 1) {
            this.tabRightMove(tabs, lis, blockEnd + 1);
        }
        this.resetMovingIcon(tabs, lis);
        this.resetIndicator(tabs, lis);
    }

    public static isEndRight(tabs: JQuery, lis: JQuery) {
        let indexs = this.getBlockIndexs(tabs);
        let endRight = false;
        if (indexs[1] === lis.length - 1) {
            let w = $(lis[indexs[1]]).width();
            this.resetAndGetRealWidth(tabs);
            let realW = $(lis[indexs[1]]).width();
            $(lis[indexs[1]]).width(w + "px");
            if (w === realW) {
                endRight = true;
            }
        }
        if (indexs[0] === indexs[1]) {
            endRight = true;
        }
        return endRight;
    }

    public static resetMovingIcon(tabs: JQuery, lis: JQuery) {
        if (tabs.find("li.tab_left_move").css("display") === "none") {
            return;
        }
        let indexs = this.getBlockIndexs(tabs);
        let endRight = this.isEndRight(tabs, lis);
        let arrowRight = tabs.find("li.tab_right_move").find("div");
        let arrowLeft = tabs.find("li.tab_left_move").find("div");
        arrowLeft.removeClass("arrow_not_active").removeClass("arrow_active");
        arrowRight.removeClass("arrow_not_active").removeClass("arrow_active");
        if (endRight) {
            //已到最右
            arrowRight.addClass("arrow_not_active");
        } else {
            arrowRight.addClass("arrow_active");
        }
        if (indexs[0] === 0) {
            //已到最左
            arrowLeft.addClass("arrow_not_active");
        } else {
            arrowLeft.addClass("arrow_active");
        }
    }

    public static tabLeftMove(tabs: JQuery, lis: JQuery, blockBegin: number) {
        lis.removeClass("tab_visible").addClass("tab_not_visible");
        let canUseWidth = tabs.width() - this.movingIconWidth - this.totalWidthPrefix;//可使用的宽度
        let usedWidth = 0;//已使用宽度
        let i: number;
        this.resetAndGetRealWidth(tabs);
        //显示
        for (i = blockBegin; i >= 0 && usedWidth < canUseWidth; i--) {
            $(lis[i]).addClass("tab_visible").removeClass("tab_not_visible");
            usedWidth += $(lis[i]).width();
        }
        for (i = blockBegin + 1; i < lis.length && usedWidth < canUseWidth; i++) {
            $(lis[i]).addClass("tab_visible").removeClass("tab_not_visible");
            usedWidth += $(lis[i]).width();
        }
        let tempIndexs = this.getBlockIndexs(tabs);
        let end = tempIndexs[1];
        if (usedWidth > canUseWidth) {
            $(lis[end]).width($(lis[end]).width() - (usedWidth - canUseWidth) + "px");
        }
        return tempIndexs[1] - tempIndexs[0] + 1;
    }


    public static tabRightMove(tabs: JQuery, lis: JQuery, blockEnd: number) {
        lis.removeClass("tab_visible").addClass("tab_not_visible");
        let canUseWidth = tabs.width() - this.movingIconWidth - this.totalWidthPrefix; //可使用的宽度
        let usedWidth = 0;//已使用宽度
        let i: number;
        this.resetAndGetRealWidth(tabs);
        //显示
        for (i = blockEnd; i < lis.length && usedWidth < canUseWidth; i++) {
            $(lis[i]).addClass("tab_visible").removeClass("tab_not_visible");
            usedWidth += $(lis[i]).width();
        }
        for (i = blockEnd - 1; i >= 0 && usedWidth < canUseWidth; i--) {
            $(lis[i]).addClass("tab_visible").removeClass("tab_not_visible");
            usedWidth += $(lis[i]).width();
        }
        let tempIndexs = this.getBlockIndexs(tabs);
        let end = tempIndexs[1], begin = tempIndexs[0];
        if (usedWidth > canUseWidth) {
            //已经移动到最后一个了
            if (end === lis.length - 1 && end != begin) {
                $(lis[begin]).removeClass("tab_visible").addClass("tab_not_visible");
            } else {
                $(lis[end]).width($(lis[end]).width() - (usedWidth - canUseWidth) + "px");
            }
        }
        tempIndexs = this.getBlockIndexs(tabs);
        return tempIndexs[1] - tempIndexs[0] + 1;
    }

    public static getBlockIndexs(tabs: JQuery) {
        let tabList = tabs.find("li.adore_tab");
        let blockBegin = 0, blockEnd = 0, i: number;
        for (i = 0; i < tabList.length; i++) {
            if ($(tabList[i]).css("display") === "block") {
                blockBegin = i;
                break;
            }
        }
        for (i = tabList.length - 1; i >= 0; i--) {
            if ($(tabList[i]).css("display") === "block") {
                blockEnd = i;
                break;
            }
        }
        return [blockBegin, blockEnd];
    }

    public static getPreTabIndex(tabs: JQuery) {
        let preIndex = 0;
        let activeHref = tabs.find("a.active").attr("href");
        let tabList = tabs.find("li.adore_tab");
        let tmpHref: any;
        //找到之前tab的下标
        for (let i = 0; i < tabList.length; i++) {
            tmpHref = $(tabList[i]).find("a").attr("href");
            if (activeHref === tmpHref) {
                preIndex = i;
                break;
            }
        }
        let blockIndexs = this.getBlockIndexs(tabs);
        if (preIndex < blockIndexs[0]) {
            return -1; //左边
        }
        if (preIndex > blockIndexs[1]) {
            return -2; //右边
        }
        return preIndex - blockIndexs[0];
    }

    public static handleTabClick(e: BaseJQueryEventObject, currentTab: JQuery, tabFolderId: string) {
        let tabs = $("#" + tabFolderId);

        let tabList = tabs.find("li.tab_visible");
        let currentIndex = 0;
        let currentHref = currentTab.attr("href");
        //找到当前tab的下标
        let tmpHref: any;
        for (let i = 0; i < tabList.length; i++) {
            tmpHref = $(tabList[i]).find("a").attr("href");
            if (currentHref === tmpHref) {
                currentIndex = i;
                break;
            }
        }
        // 找到之前tab的下标
        let lis = tabs.find("li.adore_tab");
        let preIndex = this.getPreTabIndex(tabs);
        //设置之前的tab内容不可见
        let activeHref = tabs.find("a.active").attr("href");
        $(activeHref).removeClass("tab_control_visible").addClass("tab_control_not_visible");
        // 消除之前的active
        tabs.find("a.active").removeClass("active");
        // 为currentTab添加active
        currentTab.addClass("active");
        $(currentHref).removeClass("tab_control_not_visible").addClass("tab_control_visible");

        let $tab_width = $(tabList[currentIndex]).width();
        let $indivatorLeft = this.getIndicatorLeftWidth(tabs, lis);
        let $indicator = tabs.find("div.my_indicator");
        // Update indicator
        if (preIndex === -2 || preIndex === -1) {
            $indicator.width(this.$tab_min_width + "px");
        }
        $indicator.velocity({ "left": $indivatorLeft, "width": $tab_width + "px" }, {
            duration: 300,
            queue: false,
            easing: 'easeOutQuad'
        });

    }

    // 设置签页的实际宽度并返回实际宽度
    public static resetAndGetRealWidth(tabs: JQuery) {
        let lis = tabs.find("li.adore_tab");
        //所有tab实际占的宽度
        let tabRealWidth = 0;
        for (let i = 0; i < lis.length; i++) {
            let a = $(lis[i]).find("a");
            let text = a.text();
            let fontSize: any = a.css("font-size");
            let letterSpacing: any = a.css("letter-spacing");
            fontSize = parseFloat(fontSize.replace("px", ""));
            letterSpacing = parseFloat(letterSpacing.replace("px", ""));
            let t = (fontSize + letterSpacing) * text.length + this.$tab_min_width / 2;
            t = t > this.$tab_min_width ? t : this.$tab_min_width; // 确保最小的tab宽度为40
            tabRealWidth += t;
            $(lis[i]).width(t + "px");
        }
        return tabRealWidth;
    }

    public static refreshTabs(tabs: JQuery) {
        let totalWidth = tabs.width() - this.totalWidthPrefix;
        let lis = tabs.find("li.adore_tab");
        let activeIndex = this.getActiveIndex(lis);
        lis.removeClass("tab_visible");
        lis.addClass("tab_not_visible");
        tabs.find("li.tab_left_move").css("display", "none");
        tabs.find("li.tab_right_move").css("display", "none");
        this.movingIconWidth = tabs.find("li.tab_left_move").width() + tabs.find("li.tab_right_move").width() + 10;
        let tabRealWidth = this.resetAndGetRealWidth(tabs);//所有签页的实际宽度
        tabs.find("li.adore_tab_space").css("display", "none");
        if (tabRealWidth > totalWidth) {
            //添加左移动图标
            tabs.find("li.tab_left_move").css("display", "block");
            //添加右移动图标
            tabs.find("li.tab_right_move").css("display", "block");
            this.tabRightMove(tabs, lis, activeIndex);
        } else {
            lis.removeClass("tab_not_visible").addClass("tab_visible");
            tabs.find("li.adore_tab_space").css("display", "block");
        }

        //添加indicator
        tabs.find("div.indicator").remove();
        tabs.find("div.my_indicator").remove();
        let indicator = $("<div></div>").addClass("my_indicator");
        indicator.appendTo(tabs);
        this.resetIndicator(tabs, lis);
        this.resetMovingIcon(tabs, lis);
    }

    public static getActiveIndex(lis: JQuery) {
        let activeIndex = 0;
        for (let i = 0; i < lis.length; i++) {
            if ($(lis[i]).find("a.active").length != 0) {
                activeIndex = i;
                break;
            }
        }
        return activeIndex;
    }

    public static resetIndicator(tabs: JQuery, lis: JQuery) {
        let indicatorLeft = this.getIndicatorLeftWidth(tabs, lis);
        let indicator = tabs.find("div.my_indicator");
        if (indicatorLeft === -1) {
            indicator.width(0);
            return;
        }
        let index = this.getActiveIndex(lis);
        indicator.width($(lis[index]).width() + "px");
        indicator.css("left", indicatorLeft + "px");
    }

    public static getIndicatorLeftWidth(tabs: JQuery, lis: JQuery) {
        let indexs = this.getBlockIndexs(tabs), activeIndex = this.getActiveIndex(lis), indicatorLeft = 0;
        if (activeIndex < indexs[0] || activeIndex > indexs[1]) {
            return -1;
        }
        if (tabs.find("li.tab_left_move").css("display") === "block") {
            indicatorLeft += this.movingLeftIconWidth;
        } else {
            indicatorLeft += this.totalWidthPrefix;
        }
        for (let i = indexs[0]; i < activeIndex; i++) {
            indicatorLeft += $(lis[i]).width();
        }
        return indicatorLeft;
    }

    private static init(tabs: JQuery) {
        tabs.each(function () {

            // For each set of tabs, we want to keep track of
            // which tab is active and its associated content
            let $this = $(this);

            // 获取TabFolder的id
            let tabsId = $this.attr("id");
            let ownId = tabsId;
            if (ownId) {
                ownId = ownId.substring(0, ownId.length - 5);
            }

            $this.width('100%');
            let $active: JQuery, $content: JQuery, $links = $this.find('li.adore_tab a'),
                $tabs_width = $this.width(),
                $tab_width = $this.find('li').first().outerWidth(),
                $index = 0;

            // If the location.hash matches one of the links, use that as the active tab.
            $active = $($links.filter('[href="' + location.hash + '"]'));

            // If no match is found, use the first link or any with class 'active' as the initial active tab.
            if ($active.length === 0) {
                $active = $(this).find('li.adore_tab a.active').first();
            }
            if ($active.length === 0) {
                $active = $(this).find('li.adore_tab a').first();
            }

            $active.addClass('active');
            $index = $links.index($active);
            if ($index < 0) {
                $index = 0;
            }

            $content = $(($active[0] as HTMLAnchorElement).hash);

            // append indicator then set indicator width to tab width
            $this.append("<div class=\"indicator\"></div>");
            let $indicator = $this.find('.indicator');
            if ($this.is(":visible")) {
                $indicator.css({ "right": $tabs_width - (($index + 1) * $tab_width) });
                $indicator.css({ "left": $index * $tab_width });
            }

            let resizeListener = tabs.data("resize_listener");
            if (!resizeListener) {
                resizeListener = function () {
                    $tabs_width = $this.width();
                    $tab_width = $this.find('li').first().outerWidth();
                    if ($index < 0) {
                        $index = 0;
                    }
                    if ($tab_width !== 0 && $tabs_width !== 0) {
                        $indicator.css({ "right": $tabs_width - (($index + 1) * $tab_width) });
                        $indicator.css({ "left": $index * $tab_width });
                    }
                };
                tabs.data("resize_listener", resizeListener);
                $(window).on("resize", resizeListener);
            }

            // Hide the remaining content
            $links.not($active).each(function () {
                $(this.hash).removeClass("tab_control_visible").addClass("tab_control_not_visible");
            });

            let clickListener = $this.data("click_listener");
            if (!clickListener) {
                clickListener = function (e: Event) {
                    if ($(this).parent().hasClass('disabled')) {
                        e.preventDefault();
                        return;
                    }

                    $tabs_width = $this.width();
                    $tab_width = $this.find('li').first().outerWidth();

                    // Make the old tab inactive.
                    $active.removeClass('active');
                    //$content.hide();
                    $content.removeClass("tab_control_visible").addClass("tab_control_not_visible");

                    // Update the variables with the new link and content
                    $active = $(this);
                    $content = $(this.hash);
                    $links = $this.find('li.adore_tab a');

                    // Make the tab active.
                    $active.addClass('active');
                    let $prev_index = $index;
                    $index = $links.index($(this));
                    if ($index < 0) {
                        $index = 0;
                    }
                    // Change url to current tab
                    // window.location.hash = $active.attr('href');

                    //$content.show();
                    $content.removeClass("tab_control_not_visible").addClass("tab_control_visible");
                    // Update indicator
                    if (($index - $prev_index) >= 0) {
                        $indicator.velocity({ "right": $tabs_width - (($index + 1) * $tab_width) }, {
                            duration: 300,
                            queue: false,
                            easing: 'easeOutQuad'
                        });
                        $indicator.velocity({ "left": $index * $tab_width }, {
                            duration: 300,
                            queue: false,
                            easing: 'easeOutQuad',
                            delay: 90
                        });

                    }
                    else {
                        $indicator.velocity({ "left": $index * $tab_width }, {
                            duration: 300,
                            queue: false,
                            easing: 'easeOutQuad'
                        });
                        $indicator.velocity({ "right": $tabs_width - (($index + 1) * $tab_width) }, {
                            duration: 300,
                            queue: false,
                            easing: 'easeOutQuad',
                            delay: 90
                        });
                    }
                    
                    if ($index !== $prev_index) {
                        EventHub.dispatchEvent(MessageType.WIDGET, {
                            id: ownId,
                            selectedIndex: $index + "",
                            evtType: AdoreEvent.ON_CHANGE
                        });//
                    }
                    // Prevent the anchor's default click action
                    e.preventDefault();
                };

                $this.data("click_listener", clickListener);
                // Bind the click event handler
                $this.on('click', 'a', clickListener);
            }
        });
    }

    public static tabsSwitch(tabs: JQuery) {
        this.init(tabs);
    }
}