/*
 * 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 = [];

        this._dispatchCurrentRepresentedObjectsDidChangeDebouncer = new Debouncer(() => {
            this.dispatchEventToListeners(WI.ContentBrowser.Event.CurrentRepresentedObjectsDidChange);
        });
    }

    // 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);
        }
    }

    _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._dispatchCurrentRepresentedObjectsDidChangeDebouncer.delayForTime(0);
    }

    _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._dispatchCurrentRepresentedObjectsDidChangeDebouncer.delayForTime(0);
    }

    _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._dispatchCurrentRepresentedObjectsDidChangeDebouncer.force();
    }

    _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"
};
