/*
 * 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.ContentBrowserTabContentView = class ContentBrowserTabContentView extends WI.TabContentView
{
    constructor(tabInfo, {navigationSidebarPanelConstructor, detailsSidebarPanelConstructors, disableBackForward, flexibleNavigationItem} = {})
    {
        super(tabInfo, {navigationSidebarPanelConstructor, detailsSidebarPanelConstructors});

        const contentBrowserElement = null;
        const disableFindBanner = false;
        this._contentBrowser = new WI.ContentBrowser(contentBrowserElement, this, disableBackForward, disableFindBanner, flexibleNavigationItem);

        this._ignoreNavigationSidebarPanelCollapsedEvent = false;
        this._ignoreDetailsSidebarPanelCollapsedEvent = false;
        this._ignoreDetailsSidebarPanelSelectedEvent = false;

        this._lastSelectedDetailsSidebarPanelSetting = new WI.Setting(this._identifier + "-last-selected-details-sidebar-panel", null);

        this._contentBrowser.addEventListener(WI.ContentBrowser.Event.CurrentRepresentedObjectsDidChange, this._contentBrowserCurrentRepresentedObjectsDidChange, this);
        this._contentBrowser.addEventListener(WI.ContentBrowser.Event.CurrentContentViewDidChange, this._contentBrowserCurrentContentViewDidChange, this);

        // If any content views were shown during sidebar construction, contentBrowserTreeElementForRepresentedObject() would have returned null.
        // Explicitly update the path for the navigation bar to prevent it from showing up as blank.
        this._contentBrowser.updateHierarchicalPathForCurrentContentView();

        if (this._navigationSidebarPanelConstructor) {
            let showToolTip = WI.UIString("Show the navigation sidebar (%s)").format(WI.navigationSidebarKeyboardShortcut.displayName);
            let hideToolTip = WI.UIString("Hide the navigation sidebar (%s)").format(WI.navigationSidebarKeyboardShortcut.displayName);
            let image = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "Images/ToggleRightSidebar.svg" : "Images/ToggleLeftSidebar.svg";

            this._showNavigationSidebarItem = new WI.ActivateButtonNavigationItem("toggle-navigation-sidebar", showToolTip, hideToolTip, image, 16, 16);
            this._showNavigationSidebarItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.toggleNavigationSidebar, WI);
            this._showNavigationSidebarItem.activated = !WI.navigationSidebar.collapsed;
            this._showNavigationSidebarItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;

            this._contentBrowser.navigationBar.insertNavigationItem(this._showNavigationSidebarItem, 0);
            this._contentBrowser.navigationBar.insertNavigationItem(new WI.DividerNavigationItem, 1);

            WI.navigationSidebar.addEventListener(WI.Sidebar.Event.CollapsedStateDidChange, this._navigationSidebarCollapsedStateDidChange, this);
        }

        if (this._detailsSidebarPanelConstructors.length) {
            let showToolTip = WI.UIString("Show the details sidebar (%s)").format(WI.detailsSidebarKeyboardShortcut.displayName);
            let hideToolTip = WI.UIString("Hide the details sidebar (%s)").format(WI.detailsSidebarKeyboardShortcut.displayName);
            let image = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "Images/ToggleLeftSidebar.svg" : "Images/ToggleRightSidebar.svg";

            this._showDetailsSidebarItem = new WI.ActivateButtonNavigationItem("toggle-details-sidebar", showToolTip, hideToolTip, image, 16, 16);
            this._showDetailsSidebarItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.toggleDetailsSidebar, WI);
            this._showDetailsSidebarItem.activated = !WI.detailsSidebar.collapsed;
            this._showDetailsSidebarItem.enabled = false;
            this._showDetailsSidebarItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;

            this._contentBrowser.navigationBar.addNavigationItem(new WI.DividerNavigationItem);
            this._contentBrowser.navigationBar.addNavigationItem(this._showDetailsSidebarItem);

            WI.detailsSidebar.addEventListener(WI.Sidebar.Event.CollapsedStateDidChange, this._detailsSidebarCollapsedStateDidChange, this);
            WI.detailsSidebar.addEventListener(WI.Sidebar.Event.SidebarPanelSelected, this._detailsSidebarPanelSelected, this);
        }

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

        this.addSubview(this._contentBrowser);
    }

    // Public

    get contentBrowser()
    {
        return this._contentBrowser;
    }

    shown()
    {
        if (this.navigationSidebarPanel) {
            if (!this.navigationSidebarPanel.contentBrowser)
                this.navigationSidebarPanel.contentBrowser = this._contentBrowser;
        }

        super.shown();

        this._contentBrowser.shown();

        if (this.navigationSidebarPanel) {
            if (!this._contentBrowser.currentContentView)
                this.navigationSidebarPanel.showDefaultContentView();
        }
    }

    hidden()
    {
        super.hidden();

        this._contentBrowser.hidden();
    }

    closed()
    {
        super.closed();

        WI.navigationSidebar.removeEventListener(null, null, this);
        WI.detailsSidebar.removeEventListener(null, null, this);

        if (this.navigationSidebarPanel && typeof this.navigationSidebarPanel.closed === "function")
            this.navigationSidebarPanel.closed();

        this._contentBrowser.contentViewContainer.closeAllContentViews();
    }

    get managesDetailsSidebarPanels()
    {
        return true;
    }

    showNavigationSidebarPanel()
    {
        if (!this.visible)
            return;

        if (!this.navigationSidebarPanel)
            return;

        this._ignoreNavigationSidebarPanelCollapsedEvent = true;

        let currentRepresentedObjects = this._contentBrowser.currentRepresentedObjects;
        let shouldShowSidebar = currentRepresentedObjects.some((object) => this.navigationSidebarPanel.canShowRepresentedObject(object));

        if (shouldShowSidebar) {
            if (!this.navigationSidebarPanel.parentSidebar)
                WI.navigationSidebar.addSidebarPanel(this.navigationSidebarPanel);
            WI.navigationSidebar.selectedSidebarPanel = this.navigationSidebarPanel;
            WI.navigationSidebar.collapsed = this.navigationSidebarCollapsedSetting.value;
        } else {
            WI.navigationSidebar.collapsed = true;
            if (this.navigationSidebarPanel.parentSidebar)
                WI.navigationSidebar.removeSidebarPanel(this.navigationSidebarPanel);
        }

        this._ignoreNavigationSidebarPanelCollapsedEvent = false;

        this._showNavigationSidebarItem.enabled = !!this.navigationSidebarPanel.parentSidebar;
    }

    showDetailsSidebarPanels()
    {
        if (!this.visible)
            return;

        var currentRepresentedObjects = this._contentBrowser.currentRepresentedObjects;
        var wasSidebarEmpty = !WI.detailsSidebar.sidebarPanels.length;

        // Ignore any changes to the selected sidebar panel during this function so only user initiated
        // changes are recorded in _lastSelectedDetailsSidebarPanelSetting.
        this._ignoreDetailsSidebarPanelSelectedEvent = true;
        this._ignoreDetailsSidebarPanelCollapsedEvent = true;

        let hiddenSidebarPanels = 0;

        for (var i = 0; i < this.detailsSidebarPanels.length; ++i) {
            var sidebarPanel = this.detailsSidebarPanels[i];
            if (sidebarPanel.inspect(currentRepresentedObjects)) {
                if (WI.detailsSidebar.sidebarPanels.includes(sidebarPanel)) {
                    // Already showing the panel.
                    continue;
                }

                // The sidebar panel was not previously showing, so add the panel.
                let index = i - hiddenSidebarPanels;
                WI.detailsSidebar.insertSidebarPanel(sidebarPanel, index);

                if (this._lastSelectedDetailsSidebarPanelSetting.value === sidebarPanel.identifier) {
                    // Restore the sidebar panel selection if this sidebar panel was the last one selected by the user.
                    WI.detailsSidebar.selectedSidebarPanel = sidebarPanel;
                }
            } else {
                // The sidebar panel can't inspect the current represented objects, so remove the panel and hide the toolbar item.
                WI.detailsSidebar.removeSidebarPanel(sidebarPanel);
                hiddenSidebarPanels++;
            }
        }

        if (!WI.detailsSidebar.selectedSidebarPanel && WI.detailsSidebar.sidebarPanels.length)
            WI.detailsSidebar.selectedSidebarPanel = WI.detailsSidebar.sidebarPanels[0];

        if (!WI.detailsSidebar.sidebarPanels.length)
            WI.detailsSidebar.collapsed = true;
        else if (wasSidebarEmpty)
            WI.detailsSidebar.collapsed = this.detailsSidebarCollapsedSetting.value;

        this._ignoreDetailsSidebarPanelCollapsedEvent = false;
        this._ignoreDetailsSidebarPanelSelectedEvent = false;

        if (!this.detailsSidebarPanels.length)
            return;

        this._showDetailsSidebarItem.enabled = WI.detailsSidebar.sidebarPanels.length;
    }

    showRepresentedObject(representedObject, cookie)
    {
        if (this.navigationSidebarPanel)
            this.navigationSidebarPanel.cancelRestoringState();
        this.contentBrowser.showContentViewForRepresentedObject(representedObject, cookie);
    }

    // ContentBrowser Delegate

    contentBrowserTreeElementForRepresentedObject(contentBrowser, representedObject)
    {
        return this.treeElementForRepresentedObject(representedObject);
    }

    // Protected

    treeElementForRepresentedObject(representedObject)
    {
        // Can be overridden by subclasses.

        if (!this.navigationSidebarPanel)
            return null;

        return this.navigationSidebarPanel.treeElementForRepresentedObject(representedObject);
     }

    // Private

    _navigationSidebarCollapsedStateDidChange(event)
    {
        if (!this.visible)
            return;

        this._showNavigationSidebarItem.activated = !WI.navigationSidebar.collapsed;

        if (this._ignoreNavigationSidebarPanelCollapsedEvent)
            return;

        this.navigationSidebarCollapsedSetting.value = WI.navigationSidebar.collapsed;
    }

    _detailsSidebarCollapsedStateDidChange(event)
    {
        if (!this.visible)
            return;

        this._showDetailsSidebarItem.activated = !WI.detailsSidebar.collapsed;
        this._showDetailsSidebarItem.enabled = WI.detailsSidebar.sidebarPanels.length;

        if (this._ignoreDetailsSidebarPanelCollapsedEvent)
            return;

        this.detailsSidebarCollapsedSetting.value = WI.detailsSidebar.collapsed;
    }

    _detailsSidebarPanelSelected(event)
    {
        if (!this.visible)
            return;

        this._showDetailsSidebarItem.activated = !WI.detailsSidebar.collapsed;
        this._showDetailsSidebarItem.enabled = WI.detailsSidebar.sidebarPanels.length;

        if (!WI.detailsSidebar.selectedSidebarPanel || this._ignoreDetailsSidebarPanelSelectedEvent)
            return;

        this._lastSelectedDetailsSidebarPanelSetting.value = WI.detailsSidebar.selectedSidebarPanel.identifier;
    }

    _contentBrowserCurrentContentViewDidChange(event)
    {
        let currentContentView = this._contentBrowser.currentContentView;
        if (!currentContentView)
            return;

        this._revealAndSelectRepresentedObject(currentContentView.representedObject);
    }

    _revealAndSelectRepresentedObject(representedObject)
    {
        if (this.navigationSidebarPanel) {
            // If a tree outline is processing a selection currently then we can assume the selection does not
            // need to be changed. This is needed to allow breakpoint and call frame tree elements to be selected
            // without jumping back to selecting the resource tree element.
            for (let contentTreeOutline of this.navigationSidebarPanel.contentTreeOutlines) {
                if (contentTreeOutline.processingSelectionChange)
                    return;
            }
        }

        let treeElement = this.treeElementForRepresentedObject(representedObject);

        if (treeElement)
            treeElement.revealAndSelect();
        else if (this.navigationSidebarPanel && this.navigationSidebarPanel.contentTreeOutline.selectedTreeElement)
            this.navigationSidebarPanel.contentTreeOutline.selectedTreeElement.deselect(true);
    }

    _contentBrowserCurrentRepresentedObjectsDidChange()
    {
        if (this.managesNavigationSidebarPanel)
            this.showNavigationSidebarPanel();
        this.showDetailsSidebarPanels();
    }
};
