/*
 * 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.CallFrameTreeElement = class CallFrameTreeElement extends WI.GeneralTreeElement
{
    constructor(callFrame, isAsyncBoundaryCallFrame)
    {
        console.assert(callFrame instanceof WI.CallFrame);

        let className = WI.CallFrameView.iconClassNameForCallFrame(callFrame);
        let title = callFrame.functionName || WI.UIString("(anonymous function)");
        const subtitle = null;
        super(["call-frame", className], title, subtitle, callFrame);

        this._callFrame = callFrame;
        this._isActiveCallFrame = false;

         if (isAsyncBoundaryCallFrame) {
            this.addClassName("async-boundary");
            this.selectable = false;
         }

        if (this._callFrame.nativeCode || !this._callFrame.sourceCodeLocation) {
            this.subtitle = "";
            return;
        }

        let displayScriptURL = this._callFrame.sourceCodeLocation.displaySourceCode.url;
        if (displayScriptURL) {
            this.subtitle = document.createElement("span");
            this._callFrame.sourceCodeLocation.populateLiveDisplayLocationString(this.subtitle, "textContent");
            // Set the tooltip on the entire tree element in onattach, once the element is created.
            this.tooltipHandledSeparately = true;
        }
    }

    // Public

    get callFrame() { return this._callFrame; }
    get isActiveCallFrame() { return this._isActiveCallFrame; }

    set isActiveCallFrame(x)
    {
        if (this._isActiveCallFrame === x)
            return;

        this._isActiveCallFrame = x;
        this._updateStatus();
    }

    // Protected

    onattach()
    {
        super.onattach();

        console.assert(this.element);

        if (this.tooltipHandledSeparately) {
            let tailCallSuffix = "";
            if (this._callFrame.isTailDeleted)
                tailCallSuffix = " " + WI.UIString("(Tail Call)");
            let tooltipPrefix = this.mainTitle + tailCallSuffix + "\n";
            this._callFrame.sourceCodeLocation.populateLiveDisplayLocationTooltip(this.element, tooltipPrefix);
        }

        this._updateStatus();
    }

    // Private

    _updateStatus()
    {
        if (!this.element)
            return;

        if (!this._isActiveCallFrame) {
            this.status = null;
            return;
        }

        if (!this._statusImageElement)
            this._statusImageElement = WI.ImageUtilities.useSVGSymbol("Images/ActiveCallFrame.svg", "status-image");
        this.status = this._statusImageElement;
    }
};
