/*
 * Copyright (C) 2008 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. ``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
 * 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.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
{
    if (!title) {
        title = Object.describe(object);
        if (title.match(/Prototype$/)) {
            title = title.replace(/Prototype$/, "");
            if (!subtitle)
                subtitle = WebInspector.UIString("Prototype");
        }
    }

    this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
    this.object = object;
    this.ignoreHasOwnProperty = ignoreHasOwnProperty;
    this.extraProperties = extraProperties;
    this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
    this.editable = true;

    WebInspector.PropertiesSection.call(this, title, subtitle);
}

WebInspector.ObjectPropertiesSection.prototype = {
    onpopulate: function()
    {
        this.update();
    },

    update: function()
    {
        var properties = [];
        for (var prop in this.object)
            properties.push(prop);
        if (this.extraProperties)
            for (var prop in this.extraProperties)
                properties.push(prop);
        properties.sort();

        this.propertiesTreeOutline.removeChildren();

        for (var i = 0; i < properties.length; ++i) {
            var object = this.object;
            var propertyName = properties[i];
            if (this.extraProperties && propertyName in this.extraProperties)
                object = this.extraProperties;
            if (propertyName === "__treeElementIdentifier")
                continue;
            if (!this.ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
                continue;
            this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(object, propertyName));
        }

        if (!this.propertiesTreeOutline.children.length) {
            var title = "<div class=\"info\">" + this.emptyPlaceholder + "</div>";
            var infoElement = new TreeElement(title, null, false);
            this.propertiesTreeOutline.appendChild(infoElement);
        }
    }
}

WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.ObjectPropertyTreeElement = function(parentObject, propertyName)
{
    this.parentObject = parentObject;
    this.propertyName = propertyName;

    // Pass an empty title, the title gets made later in onattach.
    TreeElement.call(this, "", null, false);
}

WebInspector.ObjectPropertyTreeElement.prototype = {
    safePropertyValue: function(object, propertyName)
    {
        if (object["__lookupGetter__"] && object.__lookupGetter__(propertyName))
            return;
        return object[propertyName];
    },

    onpopulate: function()
    {
        if (this.children.length && !this.shouldRefreshChildren)
            return;

        this.removeChildren();

        var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
        var properties = Object.sortedProperties(childObject);
        for (var i = 0; i < properties.length; ++i) {
            var propertyName = properties[i];
            if (propertyName === "__treeElementIdentifier")
                continue;
            this.appendChild(new this.treeOutline.section.treeElementConstructor(childObject, propertyName));
        }
    },

    ondblclick: function(element, event)
    {
        this.startEditing();
    },

    onattach: function()
    {
        this.update();
    },

    update: function()
    {
        var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
        var isGetter = ("__lookupGetter__" in this.parentObject && this.parentObject.__lookupGetter__(this.propertyName));

        var nameElement = document.createElement("span");
        nameElement.className = "name";
        nameElement.textContent = this.propertyName;

        this.valueElement = document.createElement("span");
        this.valueElement.className = "value";
        if (!isGetter) {
            this.valueElement.textContent = Object.describe(childObject, true);
        } else {
            // FIXME: this should show something like "getter" (bug 16734).
            this.valueElement.textContent = "\u2014"; // em dash
            this.valueElement.addStyleClass("dimmed");
        }

        this.listItemElement.removeChildren();

        this.listItemElement.appendChild(nameElement);
        this.listItemElement.appendChild(document.createTextNode(": "));
        this.listItemElement.appendChild(this.valueElement);

        var hasSubProperties = false;
        var type = typeof childObject;
        if (childObject && (type === "object" || type === "function")) {
            for (subPropertyName in childObject) {
                if (subPropertyName === "__treeElementIdentifier")
                    continue;
                hasSubProperties = true;
                break;
            }
        }

        this.hasChildren = hasSubProperties;
    },

    updateSiblings: function()
    {
        if (this.parent.root)
            this.treeOutline.section.update();
        else
            this.parent.shouldRefreshChildren = true;
    },

    startEditing: function()
    {
        if (WebInspector.isBeingEdited(this.valueElement) || !this.treeOutline.section.editable)
            return;

        var context = { expanded: this.expanded };

        // Lie about our children to prevent expanding on double click and to collapse subproperties.
        this.hasChildren = false;

        this.listItemElement.addStyleClass("editing-sub-part");

        WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
    },

    editingEnded: function(context)
    {
        this.listItemElement.scrollLeft = 0;
        this.listItemElement.removeStyleClass("editing-sub-part");
        if (context.expanded)
            this.expand();
    },

    editingCancelled: function(element, context)
    {
        this.update();
        this.editingEnded(context);
    },

    editingCommitted: function(element, userInput, previousContent, context)
    {
        if (userInput === previousContent)
            return this.editingCancelled(element, context); // nothing changed, so cancel

        this.applyExpression(userInput, true);

        this.editingEnded(context);
    },

    evaluateExpression: function(expression, callback)
    {
        // Evaluate in the currently selected call frame if the debugger is paused.
        // Otherwise evaluate in against the inspected window.
        if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused && this.treeOutline.section.editInSelectedCallFrameWhenPaused)
            return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, callback);
        try {
            var result = InspectorController.inspectedWindow().eval(expression);
            callback(result);
        } catch (e) {
            callback(e, true);
        }
    },

    applyExpression: function(expression, updateInterface)
    {
        var expressionLength = expression.trimWhitespace().length;

        if (!expressionLength) {
            // The user deleted everything, so try to delete the property.
            delete this.parentObject[this.propertyName];

            if (updateInterface) {
                if (this.propertyName in this.parentObject) {
                    // The property was not deleted, so update.
                    this.update();
                } else {
                    // The property was deleted, so remove this tree element.
                    this.parent.removeChild(this);
                }
            }

            return;
        }

        try {
            // Surround the expression in parenthesis so the result of the eval is the result
            // of the whole expression not the last potential sub-expression.
            var result = this.evaluateExpression("(" + expression + ")");

            // Store the result in the property.
            this.parentObject[this.propertyName] = result;
        } catch(e) {
            try {
                // Try to update as a string
                var result = this.evaluateExpression("\"" + expression.escapeCharacters("\"") + "\"");

                // Store the result in the property.
                this.parentObject[this.propertyName] = result;
            } catch(e) {
                // The expression failed so don't change the value. So just update and return.
                if (updateInterface)
                    this.update();
                return;
            }
        }

        if (updateInterface) {
            // Call updateSiblings since their value might be based on the value that just changed.
            this.updateSiblings();
        }
    }
}

WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
