/*
 * 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()
    {
        if (!this._backForwardList.length) {
            console.assert(this._currentIndex === -1);
            return;
        }

        var visibleContentView = this.currentContentView;

        // Hide and disassociate with all the content views.
        for (var i = 0; i < this._backForwardList.length; ++i) {
            var entry = this._backForwardList[i];
            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");
