/*
 * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDERS AND 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 THE
 * COPYRIGHT HOLDER OR 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.
 */

/**
 * @constructor
 * @extends {WebInspector.SidebarView}
 */
WebInspector.CSSNamedFlowCollectionsView = function()
{
    WebInspector.SidebarView.call(this, WebInspector.SidebarView.SidebarPosition.Start);
    this.registerRequiredCSS("cssNamedFlows.css");

    this._namedFlows = {};
    this._contentNodes = {};
    this._regionNodes = {};

    this.element.addStyleClass("css-named-flow-collections-view");
    this.element.addStyleClass("fill");

    this._statusElement = document.createElement("span");
    this._statusElement.textContent = WebInspector.UIString("CSS Named Flows");

    var sidebarHeader = this.firstElement().createChild("div", "tabbed-pane-header selected sidebar-header");
    var tab = sidebarHeader.createChild("div", "tabbed-pane-header-tab");
    tab.createChild("span", "tabbed-pane-header-tab-title").textContent = WebInspector.UIString("CSS Named Flows");

    this._sidebarContentElement = this.firstElement().createChild("div", "sidebar-content outline-disclosure");
    this._flowListElement = this._sidebarContentElement.createChild("ol");
    this._flowTree = new TreeOutline(this._flowListElement);

    this._emptyElement = document.createElement("div");
    this._emptyElement.addStyleClass("info");
    this._emptyElement.textContent = WebInspector.UIString("No CSS Named Flows");

    this._tabbedPane = new WebInspector.TabbedPane();
    this._tabbedPane.closeableTabs = true;
    this._tabbedPane.show(this.secondElement());
}

WebInspector.CSSNamedFlowCollectionsView.prototype = {
    showInDrawer: function()
    {
        WebInspector.showViewInDrawer(this._statusElement, this);
    },

    reset: function()
    {
        if (!this._document)
            return;

        WebInspector.cssModel.getNamedFlowCollectionAsync(this._document.id, this._resetNamedFlows.bind(this));
    },

    /**
     * @param {WebInspector.DOMDocument} document
     */
    _setDocument: function(document)
    {
        this._document = document;
        this.reset();
    },

    /**
     * @param {WebInspector.Event} event
     */
    _documentUpdated: function(event)
    {
        var document = /** @type {WebInspector.DOMDocument} */ (event.data);
        this._setDocument(document);
    },

    /**
     * @param {boolean} hasContent
     */
    _setSidebarHasContent: function(hasContent)
    {
        if (hasContent) {
            if (!this._emptyElement.parentNode)
                return;

            this._sidebarContentElement.removeChild(this._emptyElement);
            this._sidebarContentElement.appendChild(this._flowListElement);
        } else {
            if (!this._flowListElement.parentNode)
                return;

            this._sidebarContentElement.removeChild(this._flowListElement);
            this._sidebarContentElement.appendChild(this._emptyElement);
        }
    },

    /**
     * @param {WebInspector.NamedFlow} flow
     */
    _appendNamedFlow: function(flow)
    {
        var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
        var flowContainer = { flow: flow, flowHash: flowHash };

        for (var i = 0; i < flow.content.length; ++i)
            this._contentNodes[flow.content[i]] = flowHash;
        for (var i = 0; i < flow.regions.length; ++i)
            this._regionNodes[flow.regions[i].nodeId] = flowHash;

        var flowTreeItem = new WebInspector.FlowTreeElement(flowContainer);
        flowTreeItem.onselect = this._selectNamedFlowTab.bind(this, flowHash);

        flowContainer.flowTreeItem = flowTreeItem;
        this._namedFlows[flowHash] = flowContainer;

        if (!this._flowTree.children.length)
            this._setSidebarHasContent(true);
        this._flowTree.appendChild(flowTreeItem);
    },

    /**
     * @param {string} flowHash
     */
    _removeNamedFlow: function(flowHash)
    {
        var flowContainer = this._namedFlows[flowHash];

        if (this._tabbedPane._tabsById[flowHash])
            this._tabbedPane.closeTab(flowHash);
        this._flowTree.removeChild(flowContainer.flowTreeItem);

        var flow = flowContainer.flow;
        for (var i = 0; i < flow.content.length; ++i)
            delete this._contentNodes[flow.content[i]];
        for (var i = 0; i < flow.regions.length; ++i)
            delete this._regionNodes[flow.regions[i].nodeId];

        delete this._namedFlows[flowHash];

        if (!this._flowTree.children.length)
            this._setSidebarHasContent(false);
    },

    /**
     * @param {WebInspector.NamedFlow} flow
     */
    _updateNamedFlow: function(flow)
    {
        var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
        var flowContainer = this._namedFlows[flowHash];

        if (!flowContainer)
            return;

        var oldFlow = flowContainer.flow;
        flowContainer.flow = flow;

        for (var i = 0; i < oldFlow.content.length; ++i)
            delete this._contentNodes[oldFlow.content[i]];
        for (var i = 0; i < oldFlow.regions.length; ++i)
            delete this._regionNodes[oldFlow.regions[i].nodeId];

        for (var i = 0; i < flow.content.length; ++i)
            this._contentNodes[flow.content[i]] = flowHash;
        for (var i = 0; i < flow.regions.length; ++i)
            this._regionNodes[flow.regions[i].nodeId] = flowHash;

        flowContainer.flowTreeItem.setOverset(flow.overset);

        if (flowContainer.flowView)
            flowContainer.flowView.flow = flow;
    },

    /**
     * @param {WebInspector.NamedFlowCollection} namedFlowCollection
     */
    _resetNamedFlows: function(namedFlowCollection)
    {
        for (var flowHash in this._namedFlows)
            this._removeNamedFlow(flowHash);

        var namedFlows = namedFlowCollection.namedFlowMap;
        for (var flowName in namedFlows)
            this._appendNamedFlow(namedFlows[flowName]);

        if (!this._flowTree.children.length)
            this._setSidebarHasContent(false);
        else
            this._showNamedFlowForNode(WebInspector.panel("elements").treeOutline.selectedDOMNode());
    },

    /**
     * @param {WebInspector.Event} event
     */
    _namedFlowCreated: function(event)
    {
        // FIXME: We only have support for Named Flows in the main document.
        if (event.data.documentNodeId !== this._document.id)
            return;

        var flow = /** @type {WebInspector.NamedFlow} */ (event.data);
        this._appendNamedFlow(flow);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _namedFlowRemoved: function(event)
    {
        // FIXME: We only have support for Named Flows in the main document.
        if (event.data.documentNodeId !== this._document.id)
            return;

        this._removeNamedFlow(this._hashNamedFlow(event.data.documentNodeId, event.data.flowName));
    },

    /**
     * @param {WebInspector.Event} event
     */
    _regionLayoutUpdated: function(event)
    {
        // FIXME: We only have support for Named Flows in the main document.
        if (event.data.documentNodeId !== this._document.id)
            return;

        var flow = /** @type {WebInspector.NamedFlow} */ (event.data);
        this._updateNamedFlow(flow);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _regionOversetChanged: function(event)
    {
        // FIXME: We only have support for Named Flows in the main document.
        if (event.data.documentNodeId !== this._document.id)
            return;

        var flow = /** @type {WebInspector.NamedFlow} */ (event.data);
        this._updateNamedFlow(flow);
    },

    /**
     * @param {DOMAgent.NodeId} documentNodeId
     * @param {string} flowName
     */
    _hashNamedFlow: function(documentNodeId, flowName)
    {
        return documentNodeId + "|" + flowName;
    },

    /**
     * @param {string} flowHash
     */
    _showNamedFlow: function(flowHash)
    {
        this._selectNamedFlowInSidebar(flowHash);
        this._selectNamedFlowTab(flowHash);
    },

    /**
     * @param {string} flowHash
     */
    _selectNamedFlowInSidebar: function(flowHash)
    {
        this._namedFlows[flowHash].flowTreeItem.select(true);
    },

    /**
     * @param {string} flowHash
     */
    _selectNamedFlowTab: function(flowHash)
    {
        var flowContainer = this._namedFlows[flowHash];

        if (this._tabbedPane.selectedTabId === flowHash)
            return;

        if (!this._tabbedPane.selectTab(flowHash)) {
            if (!flowContainer.flowView)
                flowContainer.flowView = new WebInspector.CSSNamedFlowView(flowContainer.flow);

            this._tabbedPane.appendTab(flowHash, flowContainer.flow.name, flowContainer.flowView);
            this._tabbedPane.selectTab(flowHash);
        }
    },

    /**
     * @param {WebInspector.Event} event
     */
    _selectedNodeChanged: function(event)
    {
        var node = /** @type {WebInspector.DOMNode} */ (event.data);
        this._showNamedFlowForNode(node);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _tabSelected: function(event)
    {
        this._selectNamedFlowInSidebar(event.data.tabId);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _tabClosed: function(event)
    {
        this._namedFlows[event.data.tabId].flowTreeItem.deselect();
    },

    /**
     * @param {?WebInspector.DOMNode} node
     */
    _showNamedFlowForNode: function(node)
    {
        if (!node)
            return;

        if (this._regionNodes[node.id]) {
            this._showNamedFlow(this._regionNodes[node.id]);
            return;
        }

        while (node) {
            if (this._contentNodes[node.id]) {
                this._showNamedFlow(this._contentNodes[node.id]);
                return;
            }

            node = node.parentNode;
        }
    },

    wasShown: function()
    {
        WebInspector.SidebarView.prototype.wasShown.call(this);

        WebInspector.domAgent.requestDocument(this._setDocument.bind(this));

        WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);

        WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
        WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
        WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
        WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);

        WebInspector.panel("elements").treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);

        this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
        this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
    },

    willHide: function()
    {
        WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);

        WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
        WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
        WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
        WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);

        WebInspector.panel("elements").treeOutline.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);

        this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
        this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
    },

    __proto__: WebInspector.SidebarView.prototype
}

/**
 * @constructor
 * @extends {TreeElement}
 */
WebInspector.FlowTreeElement = function(flowContainer)
{
    var container = document.createElement("div");
    container.createChild("div", "selection");
    container.createChild("span", "title").createChild("span").textContent = flowContainer.flow.name;

    TreeElement.call(this, container, flowContainer, false);

    this._overset = false;
    this.setOverset(flowContainer.flow.overset);
}

WebInspector.FlowTreeElement.prototype = {
    /**
     * @param {boolean} newOverset
     */
    setOverset: function(newOverset)
    {
        if (this._overset === newOverset)
            return;

        if (newOverset) {
            this.title.addStyleClass("named-flow-overflow");
            this.tooltip = WebInspector.UIString("Overflows.");
        } else {
            this.title.removeStyleClass("named-flow-overflow");
            this.tooltip = "";
        }

        this._overset = newOverset;
    },

    __proto__: TreeElement.prototype
}
