/*
 * 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 = "";
            this.selectable = false;
            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;
    }
};
