/*
 * Copyright (C) 2016 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.HeapSnapshotClusterContentView = class HeapSnapshotClusterContentView extends WI.ClusterContentView
{
    constructor(heapSnapshot)
    {
        super(heapSnapshot);

        console.assert(heapSnapshot instanceof WI.HeapSnapshotProxy || heapSnapshot instanceof WI.HeapSnapshotDiffProxy);

        this._heapSnapshot = heapSnapshot;

        function createPathComponent(displayName, className, identifier)
        {
            let pathComponent = new WI.HierarchicalPathComponent(displayName, className, identifier, false, true);
            pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
            pathComponent.comparisonData = heapSnapshot;
            return pathComponent;
        }

        this._shownInitialContent = false;
        this._instancesContentView = null;
        this._objectGraphContentView = null;

        this._instancesPathComponent = createPathComponent.call(this, WI.UIString("Instances"), "heap-snapshot-instances-icon", WI.HeapSnapshotClusterContentView.InstancesIdentifier);
        this._objectGraphPathComponent = createPathComponent.call(this, WI.UIString("Object Graph"), "heap-snapshot-object-graph-icon", WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier);

        if (this._supportsObjectGraph()) {
            this._instancesPathComponent.nextSibling = this._objectGraphPathComponent;
            this._objectGraphPathComponent.previousSibling = this._instancesPathComponent;
        }

        this._currentContentViewSetting = new WI.Setting("heap-snapshot-cluster-current-view", WI.HeapSnapshotClusterContentView.InstancesIdentifier);
    }

    // Static

    static iconStyleClassNameForClassName(className, internal, isObjectType)
    {
        if (internal)
            return "native";
        if (isObjectType)
            return "object";

        switch (className) {
        case "Object":
        case "Array":
        case "Map":
        case "Set":
        case "WeakMap":
        case "WeakSet":
        case "Promise":
        case "Error":
        case "Window":
        case "Map Iterator":
        case "Set Iterator":
        case "Math":
        case "JSON":
        case "GlobalObject":
            return "object";
        case "Function":
            return "function";
        case "RegExp":
            return "regex";
        case "Number":
            return "number";
        case "Boolean":
            return "boolean";
        case "String":
        case "string":
            return "string";
        case "Symbol":
        case "symbol":
            return "symbol";
        }

        if (className.endsWith("Prototype"))
            return "object";
        if (className.endsWith("Element") || className === "Node" || className === "Text")
            return "node";

        return "native";
    }

    // Public

    get heapSnapshot() { return this._heapSnapshot; }

    get instancesContentView()
    {
        if (!this._instancesContentView)
            this._instancesContentView = new WI.HeapSnapshotInstancesContentView(this._heapSnapshot);
        return this._instancesContentView;
    }

    get objectGraphContentView()
    {
        if (!this._supportsObjectGraph())
            return null;

        if (!this._objectGraphContentView)
            this._objectGraphContentView = new WI.HeapSnapshotObjectGraphContentView(this._heapSnapshot);
        return this._objectGraphContentView;
    }

    get selectionPathComponents()
    {
        let currentContentView = this._contentViewContainer.currentContentView;
        if (!currentContentView)
            return [];

        let components = [this._pathComponentForContentView(currentContentView)];
        return components.concat(currentContentView.selectionPathComponents);
    }

    shown()
    {
        super.shown();

        if (this._shownInitialContent)
            return;

        this._showContentViewForIdentifier(this._currentContentViewSetting.value);
    }

    closed()
    {
        super.closed();

        this._shownInitialContent = false;
    }

    saveToCookie(cookie)
    {
        cookie[WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value;
    }

    restoreFromCookie(cookie)
    {
        this._showContentViewForIdentifier(cookie[WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey]);
    }

    showInstances()
    {
        this._shownInitialContent = true;
        return this._showContentViewForIdentifier(WI.HeapSnapshotClusterContentView.InstancesIdentifier);
    }

    showObjectGraph()
    {
        this._shownInitialContent = true;
        return this._showContentViewForIdentifier(WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier);
    }

    // Private

    _supportsObjectGraph()
    {
        return this._heapSnapshot instanceof WI.HeapSnapshotProxy;
    }

    _pathComponentForContentView(contentView)
    {
        console.assert(contentView);
        if (!contentView)
            return null;
        if (contentView === this._instancesContentView)
            return this._instancesPathComponent;
        if (contentView === this._objectGraphContentView)
            return this._objectGraphPathComponent;
        console.error("Unknown contentView.");
        return null;
    }

    _identifierForContentView(contentView)
    {
        console.assert(contentView);
        if (!contentView)
            return null;
        if (contentView === this._instancesContentView)
            return WI.HeapSnapshotClusterContentView.InstancesIdentifier;
        if (contentView === this._objectGraphContentView)
            return WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier;
        console.error("Unknown contentView.");
        return null;
    }

    _showContentViewForIdentifier(identifier)
    {
        let contentViewToShow = null;

        switch (identifier) {
        case WI.HeapSnapshotClusterContentView.InstancesIdentifier:
            contentViewToShow = this.instancesContentView;
            break;
        case WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier:
            contentViewToShow = this.objectGraphContentView;
            break;
        }

        if (!contentViewToShow)
            contentViewToShow = this.instancesContentView;

        console.assert(contentViewToShow);

        this._shownInitialContent = true;

        this._currentContentViewSetting.value = this._identifierForContentView(contentViewToShow);

        return this.contentViewContainer.showContentView(contentViewToShow);
    }

    _pathComponentSelected(event)
    {
        this._showContentViewForIdentifier(event.data.pathComponent.representedObject);
    }
};

WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey = "heap-snapshot-cluster-content-view-identifier";

WI.HeapSnapshotClusterContentView.InstancesIdentifier = "instances";
WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier = "object-graph";
