/*
 * Copyright (C) 2013 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.
 */

WebInspector.ContentViewContainer = function(element)
{
    // FIXME: Convert this to a WebInspector.Object subclass, and call super().
    // WebInspector.Object.call(this);

    this._element = element || document.createElement("div");
    this._element.classList.add(WebInspector.ContentViewContainer.StyleClassName);

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

WebInspector.ContentViewContainer.StyleClassName = "content-view-container";

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

WebInspector.ContentViewContainer.prototype = {
    constructor: WebInspector.ContentViewContainer,

    // Public

    get element()
    {
        return this._element;
    },

    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];
    },

    updateLayout: function()
    {
        var currentContentView = this.currentContentView;
        if (currentContentView)
            currentContentView.updateLayout();
    },

    contentViewForRepresentedObject: function(representedObject, onlyExisting)
    {
        console.assert(representedObject);
        if (!representedObject)
            return null;

        // Iterate over all the known content views for the representedObject (if any) and find one that doesn't
        // have a parent container or has this container as its parent.
        var contentView = null;
        for (var i = 0; representedObject.__contentViews && i < representedObject.__contentViews.length; ++i) {
            var currentContentView = representedObject.__contentViews[i];
            if (!currentContentView._parentContainer || currentContentView._parentContainer === this) {
                contentView = currentContentView;
                break;
            }
        }

        console.assert(!contentView || contentView instanceof WebInspector.ContentView);
        if (contentView instanceof WebInspector.ContentView)
            return contentView;

        // Return early to avoid creating a new content view when onlyExisting is true.
        if (onlyExisting)
            return null;

        try {
            // No existing content view found, make a new one.
            contentView = new WebInspector.ContentView(representedObject);
        } catch (e) {
            console.error(e);
            return null;
        }

        // Remember this content view for future calls.
        if (!representedObject.__contentViews)
            representedObject.__contentViews = [];
        representedObject.__contentViews.push(contentView);

        return contentView;
    },

    showContentViewForRepresentedObject: function(representedObject)
    {
        var contentView = this.contentViewForRepresentedObject(representedObject);
        if (!contentView)
            return null;

        this.showContentView(contentView);

        return contentView;
    },

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

        // Don't allow showing a content view that is already associated with another container.
        // Showing a content view that is already associated with this container is allowed.
        console.assert(!contentView.parentContainer || contentView.parentContainer === this);
        if (contentView.parentContainer && contentView.parentContainer !== this)
            return null;

        var currentEntry = this.currentBackForwardEntry;
        var provisionalEntry = new WebInspector.BackForwardEntry(contentView, cookie);
        // Don't do anything if we would have added an identical back/forward list entry.
        if (currentEntry && currentEntry.contentView === contentView && Object.shallowEqual(provisionalEntry.cookie, currentEntry.cookie)) {
            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.
        var 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.
        var 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 (var i = 0; i < removedEntries.length; ++i) {
            // Skip disassociation if this content view is still in the back/forward list.
            var shouldDissociateContentView = this._backForwardList.some(function(existingEntry) {
                return existingEntry.contentView === removedEntries[i].contentView;
            });
            if (shouldDissociateContentView)
                this._disassociateFromContentView(removedEntries[i]);
        }

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

        this.showBackForwardEntryForIndex(newIndex);

        return contentView;
    },

    showBackForwardEntryForIndex: function(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(WebInspector.ContentViewContainer.Event.CurrentContentViewDidChange);
    },

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

        console.assert(newContentView instanceof WebInspector.ContentView);
        if (!(newContentView instanceof WebInspector.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);

        // 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)
                this._backForwardList[i].contentView = newContentView;
        }

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

    closeAllContentViewsOfPrototype: function(constructor)
    {
        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 allSamePrototype = true;
        for (var i = this._backForwardList.length - 1; i >= 0; --i) {
            if (!(this._backForwardList[i].contentView instanceof constructor)) {
                allSamePrototype = false;
                break;
            }
        }

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

        var oldCurrentContentView = this.currentContentView;

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

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

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

            this._disassociateFromContentView(entry.contentView);

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

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

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

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

        // Hide and disassociate with all the content views.
        for (var i = 0; i < this._backForwardList.length; ++i) {
            var entry = this._backForwardList[i];
            if (i === this._currentIndex)
                this._hideEntry(entry);
            this._disassociateFromContentView(entry.contentView);
        }

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

        this.dispatchEventToListeners(WebInspector.ContentViewContainer.Event.CurrentContentViewDidChange);
    },

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

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

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

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

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

        this._showEntry(currentEntry, true);
    },

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

        this._hideEntry(currentEntry);
    },

    // Private

    _addContentViewElement: function(contentView)
    {
        if (contentView.element.parentNode !== this._element)
            this._element.appendChild(contentView.element);
    },

    _removeContentViewElement: function(contentView)
    {
        if (contentView.element.parentNode)
            contentView.element.parentNode.removeChild(contentView.element);
    },

    _disassociateFromContentView: function(contentView)
    {
        console.assert(!contentView.visible);

        contentView._parentContainer = null;

        var representedObject = contentView.representedObject;
        if (!representedObject || !representedObject.__contentViews)
            return;

        representedObject.__contentViews.remove(contentView);

        contentView.closed();
    },

    _showEntry: function(entry, shouldCallShown)
    {
        console.assert(entry instanceof WebInspector.BackForwardEntry);

        this._addContentViewElement(entry.contentView);
        entry.prepareToShow(shouldCallShown);
    },

    _hideEntry: function(entry)
    {
        console.assert(entry instanceof WebInspector.BackForwardEntry);

        entry.prepareToHide();
        this._removeContentViewElement(entry.contentView);
    }
};

WebInspector.ContentViewContainer.prototype.__proto__ = WebInspector.Object.prototype;
