/*
 * Copyright (C) 2013, 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.ContentBrowser = class ContentBrowser extends WI.View
{
    constructor(element, delegate, disableBackForward, disableFindBanner, flexibleNavigationItem, contentViewNavigationItemGroup)
    {
        super(element);

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

        this._navigationBar = new WI.NavigationBar;
        this.addSubview(this._navigationBar);

        this._contentViewContainer = new WI.ContentViewContainer;
        this._contentViewContainer.addEventListener(WI.ContentViewContainer.Event.CurrentContentViewDidChange, this._currentContentViewDidChange, this);
        this.addSubview(this._contentViewContainer);

        if (!disableBackForward) {
            let isRTL = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL;

            let goBack = () => { this.goBack(); };
            let goForward = () => { this.goForward(); };

            let backShortcutKey = isRTL ? WI.KeyboardShortcut.Key.Right : WI.KeyboardShortcut.Key.Left;
            let forwardShortcutKey = isRTL ? WI.KeyboardShortcut.Key.Left : WI.KeyboardShortcut.Key.Right;
            this._backKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Control, backShortcutKey, goBack, this.element);
            this._forwardKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Control, forwardShortcutKey, goForward, this.element);

            let leftArrow = "Images/BackForwardArrows.svg#left-arrow-mask";
            let rightArrow = "Images/BackForwardArrows.svg#right-arrow-mask";
            let backButtonImage = isRTL ? rightArrow : leftArrow;
            let forwardButtonImage = isRTL ? leftArrow : rightArrow;

            this._backNavigationItem = new WI.ButtonNavigationItem("back", WI.UIString("Back (%s)").format(this._backKeyboardShortcut.displayName), backButtonImage, 8, 13);
            this._backNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, goBack);
            this._backNavigationItem.enabled = false;

            this._forwardNavigationItem = new WI.ButtonNavigationItem("forward", WI.UIString("Forward (%s)").format(this._forwardKeyboardShortcut.displayName), forwardButtonImage, 8, 13);
            this._forwardNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, goForward);
            this._forwardNavigationItem.enabled = false;

            let navigationButtonsGroup = new WI.GroupNavigationItem([this._backNavigationItem, this._forwardNavigationItem]);
            this._navigationBar.addNavigationItem(navigationButtonsGroup);
        }

        if (!disableFindBanner) {
            this._findBanner = new WI.FindBanner(this);
            this._findBanner.addEventListener(WI.FindBanner.Event.DidShow, this._findBannerDidShow, this);
            this._findBanner.addEventListener(WI.FindBanner.Event.DidHide, this._findBannerDidHide, this);
        }

        this._hierarchicalPathNavigationItem = new WI.HierarchicalPathNavigationItem;
        this._hierarchicalPathNavigationItem.addEventListener(WI.HierarchicalPathNavigationItem.Event.PathComponentWasSelected, this._hierarchicalPathComponentWasSelected, this);
        this._navigationBar.addNavigationItem(this._hierarchicalPathNavigationItem);

        this._contentViewSelectionPathNavigationItem = new WI.HierarchicalPathNavigationItem;

        this._flexibleNavigationItem = flexibleNavigationItem || new WI.FlexibleSpaceNavigationItem;
        this._navigationBar.addNavigationItem(this._flexibleNavigationItem);

        this._currentContentViewNavigationItemsGroup = contentViewNavigationItemGroup || null;

        WI.ContentView.addEventListener(WI.ContentView.Event.SelectionPathComponentsDidChange, this._contentViewSelectionPathComponentDidChange, this);
        WI.ContentView.addEventListener(WI.ContentView.Event.SupplementalRepresentedObjectsDidChange, this._contentViewSupplementalRepresentedObjectsDidChange, this);
        WI.ContentView.addEventListener(WI.ContentView.Event.NumberOfSearchResultsDidChange, this._contentViewNumberOfSearchResultsDidChange, this);
        WI.ContentView.addEventListener(WI.ContentView.Event.NavigationItemsDidChange, this._contentViewNavigationItemsDidChange, this);

        this._delegate = delegate || null;

        this._currentContentViewNavigationItems = [];
    }

    // Public

    get navigationBar()
    {
        return this._navigationBar;
    }

    get contentViewContainer()
    {
        return this._contentViewContainer;
    }

    get delegate()
    {
        return this._delegate;
    }

    set delegate(newDelegate)
    {
        this._delegate = newDelegate || null;
    }

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

    get currentRepresentedObjects()
    {
        var representedObjects = [];

        var lastComponent = this._hierarchicalPathNavigationItem.lastComponent;
        if (lastComponent && lastComponent.representedObject)
            representedObjects.push(lastComponent.representedObject);

        lastComponent = this._contentViewSelectionPathNavigationItem.lastComponent;
        if (lastComponent && lastComponent.representedObject)
            representedObjects.push(lastComponent.representedObject);

        var currentContentView = this.currentContentView;
        if (currentContentView) {
            var supplementalRepresentedObjects = currentContentView.supplementalRepresentedObjects;
            if (supplementalRepresentedObjects && supplementalRepresentedObjects.length)
                representedObjects = representedObjects.concat(supplementalRepresentedObjects);
        }

        return representedObjects;
    }

    showContentViewForRepresentedObject(representedObject, cookie, extraArguments)
    {
        var contentView = this.contentViewForRepresentedObject(representedObject, false, extraArguments);
        return this._contentViewContainer.showContentView(contentView, cookie);
    }

    showContentView(contentView, cookie)
    {
        return this._contentViewContainer.showContentView(contentView, cookie);
    }

    contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments)
    {
        return this._contentViewContainer.contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments);
    }

    updateHierarchicalPathForCurrentContentView()
    {
        var currentContentView = this.currentContentView;
        this._updateHierarchicalPathNavigationItem(currentContentView ? currentContentView.representedObject : null);
    }

    canGoBack()
    {
        var currentContentView = this.currentContentView;
        if (currentContentView && currentContentView.canGoBack())
            return true;
        return this._contentViewContainer.canGoBack();
    }

    canGoForward()
    {
        var currentContentView = this.currentContentView;
        if (currentContentView && currentContentView.canGoForward())
            return true;
        return this._contentViewContainer.canGoForward();
    }

    goBack()
    {
        var currentContentView = this.currentContentView;
        if (currentContentView && currentContentView.canGoBack()) {
            currentContentView.goBack();
            this._updateBackForwardButtons();
            return;
        }

        this._contentViewContainer.goBack();

        // The _updateBackForwardButtons function is called by _currentContentViewDidChange,
        // so it does not need to be called here.
    }

    goForward()
    {
        var currentContentView = this.currentContentView;
        if (currentContentView && currentContentView.canGoForward()) {
            currentContentView.goForward();
            this._updateBackForwardButtons();
            return;
        }

        this._contentViewContainer.goForward();

        // The _updateBackForwardButtons function is called by _currentContentViewDidChange,
        // so it does not need to be called here.
    }

    showFindBanner()
    {
        if (!this._findBanner)
            return;

        var currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        if (currentContentView.supportsCustomFindBanner) {
            currentContentView.showCustomFindBanner();
            return;
        }

        this._findBanner.show();
    }

    shown()
    {
        this._updateContentViewSelectionPathNavigationItem(this.currentContentView);
        this.updateHierarchicalPathForCurrentContentView()

        this._contentViewContainer.shown();
    }

    hidden()
    {
        this._contentViewContainer.hidden();
    }

    // Global ContentBrowser KeyboardShortcut handlers

    handlePopulateFindShortcut()
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        let searchQuery = currentContentView.searchQueryWithSelection();
        if (!searchQuery)
            return;

        this._findBanner.searchQuery = searchQuery;

        currentContentView.performSearch(this._findBanner.searchQuery);
    }

    handleFindNextShortcut()
    {
        this.findBannerRevealNextResult(this._findBanner);
    }

    handleFindPreviousShortcut()
    {
        this.findBannerRevealPreviousResult(this._findBanner);
    }

    // FindBanner delegate

    findBannerPerformSearch(findBanner, query)
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.performSearch(query);
    }

    findBannerSearchCleared(findBanner)
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.searchCleared();
    }

    findBannerRevealPreviousResult(findBanner)
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.revealPreviousSearchResult(!findBanner.showing);
    }

    findBannerRevealNextResult(findBanner)
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.revealNextSearchResult(!findBanner.showing);
    }

    // Private

    _findBannerDidShow(event)
    {
        var currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.automaticallyRevealFirstSearchResult = true;
        if (this._findBanner.searchQuery !== "")
            currentContentView.performSearch(this._findBanner.searchQuery);
    }

    _findBannerDidHide(event)
    {
        var currentContentView = this.currentContentView;
        if (!currentContentView || !currentContentView.supportsSearch)
            return;

        currentContentView.automaticallyRevealFirstSearchResult = false;
        currentContentView.searchHidden();
    }

    _contentViewNumberOfSearchResultsDidChange(event)
    {
        if (!this._findBanner)
            return;

        if (event.target !== this.currentContentView)
            return;

        this._findBanner.numberOfResults = this.currentContentView.numberOfSearchResults;
    }

    _updateHierarchicalPathNavigationItem(representedObject)
    {
        if (!this.delegate || typeof this.delegate.contentBrowserTreeElementForRepresentedObject !== "function")
            return;

        var treeElement = representedObject ? this.delegate.contentBrowserTreeElementForRepresentedObject(this, representedObject) : null;
        var pathComponents = [];

        while (treeElement && !treeElement.root) {
            var pathComponent = new WI.GeneralTreeElementPathComponent(treeElement);
            pathComponents.unshift(pathComponent);
            treeElement = treeElement.parent;
        }

        this._hierarchicalPathNavigationItem.components = pathComponents;
    }

    _updateContentViewSelectionPathNavigationItem(contentView)
    {
        var selectionPathComponents = contentView ? contentView.selectionPathComponents || [] : [];
        this._contentViewSelectionPathNavigationItem.components = selectionPathComponents;

        if (this._currentContentViewNavigationItemsGroup)
            return;

        if (!selectionPathComponents.length) {
            this._hierarchicalPathNavigationItem.alwaysShowLastPathComponentSeparator = false;
            this._navigationBar.removeNavigationItem(this._contentViewSelectionPathNavigationItem);
            return;
        }

        // Insert the _contentViewSelectionPathNavigationItem after the _hierarchicalPathNavigationItem, if needed.
        if (!this._navigationBar.navigationItems.includes(this._contentViewSelectionPathNavigationItem)) {
            var hierarchicalPathItemIndex = this._navigationBar.navigationItems.indexOf(this._hierarchicalPathNavigationItem);
            console.assert(hierarchicalPathItemIndex !== -1);
            this._navigationBar.insertNavigationItem(this._contentViewSelectionPathNavigationItem, hierarchicalPathItemIndex + 1);
            this._hierarchicalPathNavigationItem.alwaysShowLastPathComponentSeparator = true;
        }
    }

    _updateBackForwardButtons()
    {
        if (!this._backNavigationItem || !this._forwardNavigationItem)
            return;

        this._backNavigationItem.enabled = this.canGoBack();
        this._forwardNavigationItem.enabled = this.canGoForward();
    }

    _updateContentViewNavigationItems(forceUpdate)
    {
        let currentContentView = this.currentContentView;
        if (!currentContentView) {
            this._removeAllNavigationItems();
            this._currentContentViewNavigationItems = [];
            if (this._currentContentViewNavigationItemsGroup)
                this._currentContentViewNavigationItems.push(this._contentViewSelectionPathNavigationItem);
            return;
        }

        // If the ContentView is a tombstone within our ContentViewContainer, don't steal its navigationItems.
        // Only the owning ContentBrowser should have the navigationItems.
        if (currentContentView.parentContainer !== this._contentViewContainer)
            return;

        if (!forceUpdate) {
            let previousItems = this._currentContentViewNavigationItems.filter((item) => !(item instanceof WI.DividerNavigationItem));
            let isUnchanged = Array.shallowEqual(previousItems, currentContentView.navigationItems);

            if (isUnchanged)
                return;
        }

        this._removeAllNavigationItems();

        let navigationBar = this.navigationBar;
        let insertionIndex = navigationBar.navigationItems.indexOf(this._flexibleNavigationItem) + 1;
        console.assert(insertionIndex >= 0);

        // Keep track of items we'll be adding to the navigation bar.
        let newNavigationItems = [];
        let shouldInsert = !this._currentContentViewNavigationItemsGroup;

        // Go through each of the items of the new content view and add a divider before them.
        currentContentView.navigationItems.forEach(function(navigationItem, index) {
            if (shouldInsert)
                navigationBar.insertNavigationItem(navigationItem, insertionIndex++);
            newNavigationItems.push(navigationItem);
        });

        if (this._currentContentViewNavigationItemsGroup)
            this._currentContentViewNavigationItemsGroup.navigationItems = [this._contentViewSelectionPathNavigationItem].concat(newNavigationItems);

        // Remember the navigation items we inserted so we can remove them
        // for the next content view.
        this._currentContentViewNavigationItems = newNavigationItems;
    }

    _removeAllNavigationItems()
    {
        if (this._currentContentViewNavigationItemsGroup)
            this._currentContentViewNavigationItemsGroup.navigationItems = [];
        else {
            for (let navigationItem of this._currentContentViewNavigationItems) {
                if (navigationItem.parentNavigationBar)
                    navigationItem.parentNavigationBar.removeNavigationItem(navigationItem);
            }
        }
    }

    _updateFindBanner(currentContentView)
    {
        if (!this._findBanner)
            return;

        if (!currentContentView) {
            this._findBanner.targetElement = null;
            this._findBanner.numberOfResults = null;
            return;
        }

        this._findBanner.targetElement = currentContentView.element;
        this._findBanner.numberOfResults = currentContentView.hasPerformedSearch ? currentContentView.numberOfSearchResults : null;

        if (currentContentView.supportsSearch && this._findBanner.searchQuery) {
            currentContentView.automaticallyRevealFirstSearchResult = this._findBanner.showing;
            currentContentView.performSearch(this._findBanner.searchQuery);
        }
    }

    _dispatchCurrentRepresentedObjectsDidChangeEvent()
    {
        this._dispatchCurrentRepresentedObjectsDidChangeEvent.cancelDebounce();

        this.dispatchEventToListeners(WI.ContentBrowser.Event.CurrentRepresentedObjectsDidChange);
    }

    _contentViewSelectionPathComponentDidChange(event)
    {
        if (event.target !== this.currentContentView)
            return;

        // If the ContentView is a tombstone within our ContentViewContainer, do nothing. Let the owning ContentBrowser react.
        if (event.target.parentContainer !== this._contentViewContainer)
            return;

        this._updateContentViewSelectionPathNavigationItem(event.target);
        this._updateBackForwardButtons();

        this._updateContentViewNavigationItems();

        this._navigationBar.needsLayout();

        this.soon._dispatchCurrentRepresentedObjectsDidChangeEvent();
    }

    _contentViewSupplementalRepresentedObjectsDidChange(event)
    {
        if (event.target !== this.currentContentView)
            return;

        // If the ContentView is a tombstone within our ContentViewContainer, do nothing. Let the owning ContentBrowser react.
        if (event.target.parentContainer !== this._contentViewContainer)
            return;

        this.soon._dispatchCurrentRepresentedObjectsDidChangeEvent();
    }

    _currentContentViewDidChange(event)
    {
        var currentContentView = this.currentContentView;

        this._updateHierarchicalPathNavigationItem(currentContentView ? currentContentView.representedObject : null);
        this._updateContentViewSelectionPathNavigationItem(currentContentView);
        this._updateBackForwardButtons();

        this._updateContentViewNavigationItems();
        this._updateFindBanner(currentContentView);

        this._navigationBar.needsLayout();

        this.dispatchEventToListeners(WI.ContentBrowser.Event.CurrentContentViewDidChange);

        this._dispatchCurrentRepresentedObjectsDidChangeEvent();
    }

    _contentViewNavigationItemsDidChange(event)
    {
        if (event.target !== this.currentContentView)
            return;

        // If the ContentView is a tombstone within our ContentViewContainer, do nothing. Let the owning ContentBrowser react.
        if (event.target.parentContainer !== this._contentViewContainer)
            return;

        const forceUpdate = true;
        this._updateContentViewNavigationItems(forceUpdate);
        this._navigationBar.needsLayout();
    }

    _hierarchicalPathComponentWasSelected(event)
    {
        console.assert(event.data.pathComponent instanceof WI.GeneralTreeElementPathComponent);

        var treeElement = event.data.pathComponent.generalTreeElement;
        var originalTreeElement = treeElement;

        // Some tree elements (like folders) are not viewable. Find the first descendant that is viewable.
        while (treeElement && !WI.ContentView.isViewable(treeElement.representedObject))
            treeElement = treeElement.traverseNextTreeElement(false, originalTreeElement, false);

        if (!treeElement)
            return;

        treeElement.revealAndSelect();
    }
};

WI.ContentBrowser.Event = {
    CurrentRepresentedObjectsDidChange: "content-browser-current-represented-objects-did-change",
    CurrentContentViewDidChange: "content-browser-current-content-view-did-change"
};
