/*
 * 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.ContentViewContainer = class ContentViewContainer extends WI.View
{
    constructor()
    {
        super();

        this.element.classList.add("content-view-container");

        this._backForwardList = [];
        this._currentIndex = -1;
    }

    // Public

    get currentIndex()
    {
        return this._currentIndex;
    }

    get backForwardList()
    {
        return this._backForwardList;
    }

    get currentContentView()
    {
        if (this._currentIndex < 0 || this._currentIndex > this._backForwardList.length - 1)
            return null;
        return this._backForwardList[this._currentIndex].contentView;
    }

    get currentBackForwardEntry()
    {
        if (this._currentIndex < 0 || this._currentIndex > this._backForwardList.length - 1)
            return null;
        return this._backForwardList[this._currentIndex];
    }

    contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments)
    {
        return WI.ContentView.contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments);
    }

    showContentViewForRepresentedObject(representedObject, extraArguments)
    {
        var contentView = this.contentViewForRepresentedObject(representedObject, false, extraArguments);
        if (!contentView)
            return null;

        this.showContentView(contentView);

        return contentView;
    }

    showContentView(contentView, cookie)
    {
        console.assert(contentView instanceof WI.ContentView);
        if (!(contentView instanceof WI.ContentView))
            return null;

        // No change.
        if (contentView === this.currentContentView && !cookie)
            return contentView;

        // ContentViews can be shared between containers. If this content view is
        // not owned by us, it may need to be transferred to this container.
        if (contentView.parentContainer !== this)
            this._takeOwnershipOfContentView(contentView);

        let currentEntry = this.currentBackForwardEntry;

        // Try to find the last entry with the same content view so we can copy it
        // to preserve the last scroll positions. The supplied cookie (if any) could
        // still change the scroll position afterwards, but in most cases the cookie
        // is undefined, so we want to show with a state last used.
        let provisionalEntry = null;
        for (let i = this._backForwardList.length - 1; i >= 0; --i) {
            if (this._backForwardList[i].contentView === contentView) {
                provisionalEntry = this._backForwardList[i].makeCopy(cookie);
                break;
            }
        }

        if (!provisionalEntry)
            provisionalEntry = new WI.BackForwardEntry(contentView, cookie);

        // Don't do anything if we would have added an identical back/forward list entry.
        if (provisionalEntry.isEqual(currentEntry)) {
            const shouldCallShown = false;
            currentEntry.prepareToShow(shouldCallShown);
            return currentEntry.contentView;
        }

        // Showing a content view will truncate the back/forward list after the current index and insert the content view
        // at the end of the list. Finally, the current index will be updated to point to the end of the back/forward list.

        // Increment the current index to where we will insert the content view.
        let newIndex = this._currentIndex + 1;

        // Insert the content view at the new index. This will remove any content views greater than or equal to the index.
        let removedEntries = this._backForwardList.splice(newIndex, this._backForwardList.length - newIndex, provisionalEntry);

        console.assert(newIndex === this._backForwardList.length - 1);
        console.assert(this._backForwardList[newIndex] === provisionalEntry);

        // Disassociate with the removed content views.
        for (let i = 0; i < removedEntries.length; ++i) {
            // Skip disassociation if this content view is still in the back/forward list.
            let shouldDissociateContentView = !this._backForwardList.some((existingEntry) => existingEntry.contentView === removedEntries[i].contentView);
            if (shouldDissociateContentView)
                this._disassociateFromContentView(removedEntries[i].contentView, removedEntries[i].tombstone);
        }

        // Associate with the new content view.
        contentView._parentContainer = this;

        this.showBackForwardEntryForIndex(newIndex);

        return contentView;
    }

    showBackForwardEntryForIndex(index)
    {
        console.assert(index >= 0 && index <= this._backForwardList.length - 1);
        if (index < 0 || index > this._backForwardList.length - 1)
            return;

        if (this._currentIndex === index)
            return;

        var previousEntry = this.currentBackForwardEntry;
        this._currentIndex = index;
        var currentEntry = this.currentBackForwardEntry;
        console.assert(currentEntry);

        var isNewContentView = !previousEntry || !currentEntry.contentView.visible;
        if (isNewContentView) {
            // Hide the currently visible content view.
            if (previousEntry)
                this._hideEntry(previousEntry);
            this._showEntry(currentEntry, true);
        } else
            this._showEntry(currentEntry, false);

        this.dispatchEventToListeners(WI.ContentViewContainer.Event.CurrentContentViewDidChange);
    }

    replaceContentView(oldContentView, newContentView)
    {
        console.assert(oldContentView instanceof WI.ContentView);
        if (!(oldContentView instanceof WI.ContentView))
            return;

        console.assert(newContentView instanceof WI.ContentView);
        if (!(newContentView instanceof WI.ContentView))
            return;

        console.assert(oldContentView.parentContainer === this);
        if (oldContentView.parentContainer !== this)
            return;

        console.assert(!newContentView.parentContainer || newContentView.parentContainer === this);
        if (newContentView.parentContainer && newContentView.parentContainer !== this)
            return;

        var currentlyShowing = this.currentContentView === oldContentView;
        if (currentlyShowing)
            this._hideEntry(this.currentBackForwardEntry);

        // Disassociate with the old content view.
        this._disassociateFromContentView(oldContentView, false);

        // Associate with the new content view.
        newContentView._parentContainer = this;

        // Replace all occurrences of oldContentView with newContentView in the back/forward list.
        for (var i = 0; i < this._backForwardList.length; ++i) {
            if (this._backForwardList[i].contentView === oldContentView) {
                console.assert(!this._backForwardList[i].tombstone);
                let currentCookie = this._backForwardList[i].cookie;
                this._backForwardList[i] = new WI.BackForwardEntry(newContentView, currentCookie);
            }
        }

        this._removeIdenticalAdjacentBackForwardEntries();

        // Re-show the current entry, because its content view instance was replaced.
        if (currentlyShowing) {
            this._showEntry(this.currentBackForwardEntry, true);
            this.dispatchEventToListeners(WI.ContentViewContainer.Event.CurrentContentViewDidChange);
        }
    }

    closeContentView(contentViewToClose)
    {
        if (!this._backForwardList.length) {
            console.assert(this._currentIndex === -1);
            return;
        }

        // Do a check to see if all the content views are instances of this prototype.
        // If they all are we can use the quicker closeAllContentViews method.
        var allSameContentView = true;
        for (var i = this._backForwardList.length - 1; i >= 0; --i) {
            if (this._backForwardList[i].contentView !== contentViewToClose) {
                allSameContentView = false;
                break;
            }
        }

        if (allSameContentView) {
            this.closeAllContentViews();
            return;
        }

        var visibleContentView = this.currentContentView;
        var backForwardListDidChange = false;
        // Hide and disassociate with all the content views that are the same as contentViewToClose.
        for (var i = this._backForwardList.length - 1; i >= 0; --i) {
            var entry = this._backForwardList[i];
            if (entry.contentView !== contentViewToClose)
                continue;

            if (entry.contentView === visibleContentView)
                this._hideEntry(entry);

            if (this._currentIndex >= i) {
                // Decrement the currentIndex since we will remove an item in the back/forward array
                // that is the current index or comes before it.
                --this._currentIndex;
            }

            this._disassociateFromContentView(entry.contentView, entry.tombstone);

            // Remove the item from the back/forward list.
            this._backForwardList.splice(i, 1);
            backForwardListDidChange = true;
        }

        if (backForwardListDidChange)
            this._removeIdenticalAdjacentBackForwardEntries();

        var currentEntry = this.currentBackForwardEntry;
        console.assert(currentEntry || (!currentEntry && this._currentIndex === -1));

        if (currentEntry && currentEntry.contentView !== visibleContentView || backForwardListDidChange) {
            this._showEntry(currentEntry, true);
            this.dispatchEventToListeners(WI.ContentViewContainer.Event.CurrentContentViewDidChange);
        }
    }

    closeAllContentViews(filter)
    {
        console.assert(!filter || typeof filter === "function");

        if (!this._backForwardList.length) {
            console.assert(this._currentIndex === -1);
            return;
        }

        var visibleContentView = this.currentContentView;

        // Hide and disassociate with all the content views.
        for (let i = 0; i < this._backForwardList.length; ++i) {
            let entry = this._backForwardList[i];
            if (filter && !filter(entry.contentView))
                continue;

            if (entry.contentView === visibleContentView)
                this._hideEntry(entry);

            this._disassociateFromContentView(entry.contentView, entry.tombstone);
        }

        this._backForwardList = [];
        this._currentIndex = -1;

        this.dispatchEventToListeners(WI.ContentViewContainer.Event.CurrentContentViewDidChange);
    }

    canGoBack()
    {
        return this._currentIndex > 0;
    }

    canGoForward()
    {
        return this._currentIndex < this._backForwardList.length - 1;
    }

    goBack()
    {
        if (!this.canGoBack())
            return;
        this.showBackForwardEntryForIndex(this._currentIndex - 1);
    }

    goForward()
    {
        if (!this.canGoForward())
            return;
        this.showBackForwardEntryForIndex(this._currentIndex + 1);
    }

    shown()
    {
        var currentEntry = this.currentBackForwardEntry;
        if (!currentEntry)
            return;

        this._showEntry(currentEntry, true);
    }

    hidden()
    {
        var currentEntry = this.currentBackForwardEntry;
        if (!currentEntry)
            return;

        this._hideEntry(currentEntry);
    }

    // Private

    _takeOwnershipOfContentView(contentView)
    {
        console.assert(contentView.parentContainer !== this, "We already have ownership of the ContentView");
        if (contentView.parentContainer === this)
            return;

        if (contentView.parentContainer)
            contentView.parentContainer._placeTombstonesForContentView(contentView);

        contentView._parentContainer = this;

        this._clearTombstonesForContentView(contentView);

        // These contentView navigation items need to move to the new content browser.
        contentView.dispatchEventToListeners(WI.ContentView.Event.NavigationItemsDidChange);
    }

    _placeTombstonesForContentView(contentView)
    {
        console.assert(contentView.parentContainer === this);

        // Ensure another ContentViewContainer doesn't close this ContentView while we still have it.
        let tombstoneContentViewContainers = this._tombstoneContentViewContainersForContentView(contentView);
        console.assert(!tombstoneContentViewContainers.includes(this));

        let visibleContentView = this.currentContentView;

        for (let entry of this._backForwardList) {
            if (entry.contentView !== contentView)
                continue;

            if (entry.contentView === visibleContentView) {
                this._hideEntry(entry);
                visibleContentView = null;
            }

            console.assert(!entry.tombstone);
            entry.tombstone = true;

            tombstoneContentViewContainers.push(this);
        }
    }

    _clearTombstonesForContentView(contentView)
    {
        console.assert(contentView.parentContainer === this);

        let tombstoneContentViewContainers = this._tombstoneContentViewContainersForContentView(contentView);
        tombstoneContentViewContainers.removeAll(this);

        for (let entry of this._backForwardList) {
            if (entry.contentView !== contentView)
                continue;

            console.assert(entry.tombstone);
            entry.tombstone = false;
        }
    }

    _disassociateFromContentView(contentView, isTombstone)
    {
        // Just remove one of our tombstone back references.
        // There may be other back/forward entries that need a reference.
        if (isTombstone) {
            let tombstoneContentViewContainers = this._tombstoneContentViewContainersForContentView(contentView);
            tombstoneContentViewContainers.remove(this);
            return;
        }

        console.assert(!contentView.visible);

        if (!contentView._parentContainer)
            return;

        contentView._parentContainer = null;

        // If another ContentViewContainer has tombstones for this, just transfer
        // ownership to that ContentViewContainer and avoid closing the ContentView.
        // We don't care who we transfer this to, so just use the first.
        let tombstoneContentViewContainers = this._tombstoneContentViewContainersForContentView(contentView);
        if (tombstoneContentViewContainers && tombstoneContentViewContainers.length) {
            tombstoneContentViewContainers[0]._takeOwnershipOfContentView(contentView);
            return;
        }

        contentView.closed();

        if (contentView.representedObject)
            WI.ContentView.closedContentViewForRepresentedObject(contentView.representedObject);
    }

    _showEntry(entry, shouldCallShown)
    {
        console.assert(entry instanceof WI.BackForwardEntry);

        // We may be showing a tombstone from a BackForward list or when re-showing a container
        // that had previously had the content view transferred away from it.
        // Take over the ContentView.
        if (entry.tombstone) {
            this._takeOwnershipOfContentView(entry.contentView);
            console.assert(!entry.tombstone);
        }

        if (!this.subviews.includes(entry.contentView))
            this.addSubview(entry.contentView);

        entry.prepareToShow(shouldCallShown);
    }

    _hideEntry(entry)
    {
        console.assert(entry instanceof WI.BackForwardEntry);

        // If this was a tombstone, the content view should already have been
        // hidden when we placed the tombstone.
        if (entry.tombstone)
            return;

        entry.prepareToHide();
        if (this.subviews.includes(entry.contentView))
            this.removeSubview(entry.contentView);
    }

    _tombstoneContentViewContainersForContentView(contentView)
    {
        let tombstoneContentViewContainers = contentView[WI.ContentViewContainer.TombstoneContentViewContainersSymbol];
        if (!tombstoneContentViewContainers)
            tombstoneContentViewContainers = contentView[WI.ContentViewContainer.TombstoneContentViewContainersSymbol] = [];
        return tombstoneContentViewContainers;
    }

    _removeIdenticalAdjacentBackForwardEntries()
    {
        if (this._backForwardList.length < 2)
            return;

        let previousEntry;
        for (let i = this._backForwardList.length - 1; i >= 0; --i) {
            let entry = this._backForwardList[i];
            if (!entry.isEqual(previousEntry)) {
                previousEntry = entry;
                continue;
            }

           if (this._currentIndex >= i) {
                // Decrement the currentIndex since we will remove an item in the back/forward array
                // that is the current index or comes before it.
                --this._currentIndex;
            }

            this._backForwardList.splice(i, 1);
        }
    }
};

WI.ContentViewContainer.Event = {
    CurrentContentViewDidChange: "content-view-container-current-content-view-did-change"
};

WI.ContentViewContainer.TombstoneContentViewContainersSymbol = Symbol("content-view-container-tombstone-content-view-containers");
