/*
 * Copyright (C) 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.TabBrowser = class TabBrowser extends WI.View
{
    constructor(element, tabBar, navigationSidebar, detailsSidebar)
    {
        console.assert(tabBar, "Must provide a TabBar.");

        super(element);

        this.element.classList.add("tab-browser");

        this._tabBar = tabBar;
        this._navigationSidebar = navigationSidebar || null;
        this._detailsSidebar = detailsSidebar || null;

        if (this._navigationSidebar) {
            this._navigationSidebar.addEventListener(WI.Sidebar.Event.CollapsedStateDidChange, this._sidebarCollapsedStateDidChange, this);
            this._navigationSidebar.addEventListener(WI.Sidebar.Event.WidthDidChange, this._sidebarWidthDidChange, this);
        }

        if (this._detailsSidebar) {
            this._detailsSidebar.addEventListener(WI.Sidebar.Event.CollapsedStateDidChange, this._sidebarCollapsedStateDidChange, this);
            this._detailsSidebar.addEventListener(WI.Sidebar.Event.SidebarPanelSelected, this._sidebarPanelSelected, this);
            this._detailsSidebar.addEventListener(WI.Sidebar.Event.WidthDidChange, this._sidebarWidthDidChange, this);
        }

        this._contentViewContainer = new WI.ContentViewContainer;
        this.addSubview(this._contentViewContainer);

        let showNextTab = () => { this._showNextTab(); };
        let showPreviousTab = () => { this._showPreviousTab(); };

        let isRTL = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL;

        let nextKey1 = isRTL ? WI.KeyboardShortcut.Key.LeftCurlyBrace : WI.KeyboardShortcut.Key.RightCurlyBrace;
        let previousKey1 = isRTL ? WI.KeyboardShortcut.Key.RightCurlyBrace : WI.KeyboardShortcut.Key.LeftCurlyBrace;

        this._showNextTabKeyboardShortcut1 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, nextKey1, showNextTab);
        this._showPreviousTabKeyboardShortcut1 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, previousKey1, showPreviousTab);

        let nextModifier2 = isRTL ? WI.KeyboardShortcut.Modifier.Shift : 0;
        let previousModifier2 = isRTL ? 0 : WI.KeyboardShortcut.Modifier.Shift;

        this._showNextTabKeyboardShortcut2 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Control | nextModifier2, WI.KeyboardShortcut.Key.Tab, showNextTab);
        this._showPreviousTabKeyboardShortcut2 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Control | previousModifier2, WI.KeyboardShortcut.Key.Tab, showPreviousTab);

        let previousTabKey = isRTL ? WI.KeyboardShortcut.Key.Right : WI.KeyboardShortcut.Key.Left;
        let nextTabKey = isRTL ? WI.KeyboardShortcut.Key.Left : WI.KeyboardShortcut.Key.Right;
        this._previousTabKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, previousTabKey, this._showPreviousTabCheckingForEditableField.bind(this));
        this._previousTabKeyboardShortcut.implicitlyPreventsDefault = false;
        this._nextTabKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, nextTabKey, this._showNextTabCheckingForEditableField.bind(this));
        this._nextTabKeyboardShortcut.implicitlyPreventsDefault = false;

        this._tabBar.addEventListener(WI.TabBar.Event.TabBarItemSelected, this._tabBarItemSelected, this);
        this._tabBar.addEventListener(WI.TabBar.Event.TabBarItemAdded, this._tabBarItemAdded, this);
        this._tabBar.addEventListener(WI.TabBar.Event.TabBarItemRemoved, this._tabBarItemRemoved, this);

        this._recentTabContentViews = [];
        this._closedTabClasses = new Set;
    }

    // Public

    get tabBar()
    {
        return this._tabBar;
    }

    get navigationSidebar()
    {
        return this._navigationSidebar;
    }

    get detailsSidebar()
    {
        return this._detailsSidebar;
    }

    get selectedTabContentView()
    {
        return this._contentViewContainer.currentContentView;
    }

    bestTabContentViewForClass(constructor)
    {
        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);

        for (var tabContentView of this._recentTabContentViews) {
            if (tabContentView instanceof constructor)
                return tabContentView;
        }

        return null;
    }

    bestTabContentViewForRepresentedObject(representedObject, options = {})
    {
        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);

        let tabContentView = this._recentTabContentViews.find((tabContentView) => tabContentView.type === options.preferredTabType);
        if (tabContentView && tabContentView.canShowRepresentedObject(representedObject))
            return tabContentView;

        for (let tabContentView of this._recentTabContentViews) {
            if (options.ignoreSearchTab && tabContentView instanceof WI.SearchTabContentView)
                continue;
            if (options.ignoreNetworkTab && tabContentView instanceof WI.NetworkTabContentView)
                continue;

            if (tabContentView.canShowRepresentedObject(representedObject))
                return tabContentView;
        }

        return null;
    }

    addTabForContentView(tabContentView, options = {})
    {
        console.assert(tabContentView instanceof WI.TabContentView);
        if (!(tabContentView instanceof WI.TabContentView))
            return false;

        let tabBarItem = tabContentView.tabBarItem;

        console.assert(tabBarItem instanceof WI.TabBarItem);
        if (!(tabBarItem instanceof WI.TabBarItem))
            return false;

        if (tabBarItem.representedObject !== tabContentView)
            tabBarItem.representedObject = tabContentView;

        if (tabBarItem.parentTabBar === this._tabBar)
            return true;

        // Add the tab after the first tab content view, since the first
        // tab content view is the currently selected one.
        if (this._recentTabContentViews.length && this.selectedTabContentView)
            this._recentTabContentViews.splice(1, 0, tabContentView);
        else
            this._recentTabContentViews.push(tabContentView);

        if (typeof options.insertionIndex === "number")
            this._tabBar.insertTabBarItem(tabBarItem, options.insertionIndex, options);
        else
            this._tabBar.addTabBarItem(tabBarItem, options);

        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);

        return true;
    }

    showTabForContentView(tabContentView, options = {})
    {
        if (!this.addTabForContentView(tabContentView, options))
            return false;

        this._tabBar.selectTabBarItem(tabContentView.tabBarItem, options);

        // FIXME: this is a workaround for <https://webkit.org/b/151876>.
        // Without this extra call, we might never lay out the child tab
        // if it has already marked itself as dirty in the same run loop
        // as it is attached. It will schedule a layout, but when the rAF
        // fires the parent will abort the layout because the counter is
        // out of sync.
        this.needsLayout();
        return true;
    }

    closeTabForContentView(tabContentView, options = {})
    {
        console.assert(tabContentView instanceof WI.TabContentView);
        if (!(tabContentView instanceof WI.TabContentView))
            return false;

        console.assert(tabContentView.tabBarItem instanceof WI.TabBarItem);
        if (!(tabContentView.tabBarItem instanceof WI.TabBarItem))
            return false;

        if (tabContentView.tabBarItem.parentTabBar !== this._tabBar)
            return false;

        this._tabBar.removeTabBarItem(tabContentView.tabBarItem, options);

        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);

        return true;
    }

    // Protected

    sizeDidChange()
    {
        super.sizeDidChange();

        for (let tabContentView of this._recentTabContentViews)
            tabContentView[WI.TabBrowser.NeedsResizeLayoutSymbol] = tabContentView !== this.selectedTabContentView;
    }

    // Private

    _tabBarItemSelected(event)
    {
        this._saveFocusedNodeForTabContentView(event.data.previousTabBarItem ? event.data.previousTabBarItem.representedObject : null);

        let tabContentView = this._tabBar.selectedTabBarItem ? this._tabBar.selectedTabBarItem.representedObject : null;

        if (tabContentView) {
            let shouldSaveTab = tabContentView.constructor.shouldSaveTab();
            if (shouldSaveTab) {
                this._recentTabContentViews.remove(tabContentView);
                this._recentTabContentViews.unshift(tabContentView);
            }

            this._contentViewContainer.showContentView(tabContentView);

            console.assert(this.selectedTabContentView);
            console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
            console.assert(this.selectedTabContentView === this._recentTabContentViews[0] || !shouldSaveTab);
        } else {
            this._contentViewContainer.closeAllContentViews();

            console.assert(!this.selectedTabContentView);
        }

        this._showNavigationSidebarPanelForTabContentView(tabContentView);
        this._showDetailsSidebarPanelsForTabContentView(tabContentView);

        // If the tab browser was resized prior to showing the tab, the new tab needs to perform a resize layout.
        if (tabContentView && tabContentView[WI.TabBrowser.NeedsResizeLayoutSymbol]) {
            tabContentView[WI.TabBrowser.NeedsResizeLayoutSymbol] = false;
            tabContentView.updateLayout(WI.View.LayoutReason.Resize);
        }

        let outgoingTab = event.data.previousTabBarItem ? event.data.previousTabBarItem.representedObject : null;
        let incomingTab = tabContentView;
        let initiator = event.data.initiatorHint || WI.TabBrowser.TabNavigationInitiator.Unknown;
        this.dispatchEventToListeners(WI.TabBrowser.Event.SelectedTabContentViewDidChange, {outgoingTab, incomingTab, initiator});

        this._restoreFocusedNodeForTabContentView(tabContentView);
    }

    _tabBarItemAdded(event)
    {
        let tabContentView = event.data.tabBarItem.representedObject;

        console.assert(tabContentView);
        if (!tabContentView)
            return;

        this._closedTabClasses.delete(tabContentView.constructor);
    }

    _tabBarItemRemoved(event)
    {
        let tabContentView = event.data.tabBarItem.representedObject;

        console.assert(tabContentView);
        if (!tabContentView)
            return;

        this._recentTabContentViews.remove(tabContentView);

        if (!tabContentView.constructor.tabInfo().isEphemeral)
            this._closedTabClasses.add(tabContentView.constructor);

        this._contentViewContainer.closeContentView(tabContentView);

        console.assert(this._recentTabContentViews.length === this._tabBar.saveableTabCount);
        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
    }

    _sidebarPanelSelected(event)
    {
        if (this._ignoreSidebarEvents)
            return;

        var tabContentView = this.selectedTabContentView;
        if (!tabContentView)
            return;

        console.assert(event.target === this._detailsSidebar);

        if (tabContentView.managesDetailsSidebarPanels)
            return;

        var selectedSidebarPanel = this._detailsSidebar.selectedSidebarPanel;
        tabContentView.detailsSidebarSelectedPanelSetting.value = selectedSidebarPanel ? selectedSidebarPanel.identifier : null;
    }

    _sidebarCollapsedStateDidChange(event)
    {
        if (this._ignoreSidebarEvents)
            return;

        var tabContentView = this.selectedTabContentView;
        if (!tabContentView)
            return;

        if (event.target === this._navigationSidebar && !tabContentView.managesNavigationSidebarPanel)
            tabContentView.navigationSidebarCollapsedSetting.value = this._navigationSidebar.collapsed;
        else if (event.target === this._detailsSidebar && !tabContentView.managesDetailsSidebarPanels)
            tabContentView.detailsSidebarCollapsedSetting.value = this._detailsSidebar.collapsed;
    }

    _sidebarWidthDidChange(event)
    {
        if (this._ignoreSidebarEvents || !event.data)
            return;

        let tabContentView = this.selectedTabContentView;
        if (!tabContentView)
            return;

        switch (event.target) {
        case this._navigationSidebar:
            tabContentView.navigationSidebarWidthSetting.value = event.data.newWidth;
            break;

        case this._detailsSidebar:
            tabContentView.detailsSidebarWidthSetting.value = event.data.newWidth;
            break;
        }
    }

    _saveFocusedNodeForTabContentView(tabContentView)
    {
        if (!tabContentView)
            return;

        if (!WI.isContentAreaFocused())
            return;

        tabContentView[WI.TabBrowser.FocusedNodeSymbol] = document.activeElement;
    }

    _restoreFocusedNodeForTabContentView(tabContentView)
    {
        if (!tabContentView)
            return;

        let node = tabContentView[WI.TabBrowser.FocusedNodeSymbol];
        if (node && !WI.isContentAreaFocused())
            node.focus();

        tabContentView[WI.TabBrowser.FocusedNodeSymbol] = null;
    }

    _showNavigationSidebarPanelForTabContentView(tabContentView)
    {
        if (!this._navigationSidebar)
            return;

        this._ignoreSidebarEvents = true;

        this._navigationSidebar.removeSidebarPanel(0);

        console.assert(!this._navigationSidebar.sidebarPanels.length);

        if (!tabContentView) {
            this._ignoreSidebarEvents = false;
            return;
        }

        if (tabContentView.navigationSidebarWidthSetting.value)
            this._navigationSidebar.width = tabContentView.navigationSidebarWidthSetting.value;

        var navigationSidebarPanel = tabContentView.navigationSidebarPanel;
        if (!navigationSidebarPanel) {
            this._navigationSidebar.collapsed = true;
            this._ignoreSidebarEvents = false;
            return;
        }

        if (tabContentView.managesNavigationSidebarPanel) {
            tabContentView.showNavigationSidebarPanel();
            this._ignoreSidebarEvents = false;
            return;
        }

        this._navigationSidebar.addSidebarPanel(navigationSidebarPanel);
        this._navigationSidebar.selectedSidebarPanel = navigationSidebarPanel;

        this._navigationSidebar.collapsed = tabContentView.navigationSidebarCollapsedSetting.value;

        this._ignoreSidebarEvents = false;
    }

    _showDetailsSidebarPanelsForTabContentView(tabContentView)
    {
        if (!this._detailsSidebar)
            return;

        this._ignoreSidebarEvents = true;

        for (var i = this._detailsSidebar.sidebarPanels.length - 1; i >= 0; --i)
            this._detailsSidebar.removeSidebarPanel(i);

        console.assert(!this._detailsSidebar.sidebarPanels.length);

        if (!tabContentView) {
            this._ignoreSidebarEvents = false;
            return;
        }

        if (tabContentView.detailsSidebarWidthSetting.value)
            this._detailsSidebar.width = tabContentView.detailsSidebarWidthSetting.value;

        if (tabContentView.managesDetailsSidebarPanels) {
            tabContentView.showDetailsSidebarPanels();
            this._ignoreSidebarEvents = false;
            return;
        }

        var detailsSidebarPanels = tabContentView.detailsSidebarPanels;
        if (!detailsSidebarPanels) {
            this._detailsSidebar.collapsed = true;
            this._ignoreSidebarEvents = false;
            return;
        }

        for (var detailsSidebarPanel of detailsSidebarPanels)
            this._detailsSidebar.addSidebarPanel(detailsSidebarPanel);

        this._detailsSidebar.selectedSidebarPanel = tabContentView.detailsSidebarSelectedPanelSetting.value || detailsSidebarPanels[0];

        this._detailsSidebar.collapsed = tabContentView.detailsSidebarCollapsedSetting.value || !detailsSidebarPanels.length;

        this._ignoreSidebarEvents = false;
    }

    _showPreviousTab(event)
    {
        this._tabBar.selectPreviousTab();
    }

    _showNextTab(event)
    {
        this._tabBar.selectNextTab();
    }

    _showNextTabCheckingForEditableField(event)
    {
        if (WI.isEventTargetAnEditableField(event))
            return;

        this._showNextTab(event);

        event.preventDefault();
    }

    _showPreviousTabCheckingForEditableField(event)
    {
        if (WI.isEventTargetAnEditableField(event))
            return;

        this._showPreviousTab(event);

        event.preventDefault();
    }
};

WI.TabBrowser.NeedsResizeLayoutSymbol = Symbol("needs-resize-layout");
WI.TabBrowser.FocusedNodeSymbol = Symbol("focused-node");

WI.TabBrowser.TabNavigationInitiator = {
    // Initiated by clicking on the TabBar UI (switching, opening, closing).
    TabClick: "tab-browser-tab-navigation-initiator-tab-click",

    // Initiated by clicking a URL, symbol, go-to-arrow, or other link to a resource/source code location.
    LinkClick: "tab-browser-tab-navigation-initiator-link-click",

    // Initiated by clicking miscellaneous UI (i.e., Quick Console's chevron, New Tab Tab's buttons).
    ButtonClick: "tab-browser-tab-navigation-initiator-button-click",

    // Initiated by selecting a context menu item in Web Inspector (i.e., "Reveal in Network Tab").
    ContextMenu: "tab-browser-tab-navigation-initiator-context-menu",

    // Initiated by clicking a dashboard element.
    Dashboard: "tab-browser-tab-navigation-initiator-dashboard",

    // Initiated by automatically switching tabs when a breakpoint is hit.
    Breakpoint: "tab-browser-tab-navigation-initiator-breakpoint",

    // Initiated by inspecting a DOM element, database, or other object via Console API's inspect() or live node selection.
    Inspect: "tab-browser-tab-navigation-initiator-inspect",

    // Initiated by keyboard shortcut (tab switching, new tab, search bar).
    KeyboardShortcut: "tab-browser-tab-navigation-initiator-keyboard-shortcut",

    // Initiated from outside of Web Inspector (Develop Menu, _WKInspector SPI).
    FrontendAPI: "tab-browser-tab-navigation-initiator-frontend-api",

    // Uncategorized; these should be investigated and categorized as one of the above.
    Unknown: "tab-browser-tab-navigation-initiator-unknown"
}

WI.TabBrowser.Event = {
    SelectedTabContentViewDidChange: "tab-browser-selected-tab-content-view-did-change"
};
