/*
 * Copyright (C) 2003, 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 COMPUTER, 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 COMPUTER, 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. 
 */

#include "config.h"
#include "runtime_object.h"

#include "JSDOMBinding.h"
#include "runtime_method.h"
#include "runtime_root.h"
#include <runtime/Error.h>
#include <runtime/ObjectPrototype.h>

using namespace WebCore;

namespace JSC {

using namespace Bindings;

const ClassInfo RuntimeObjectImp::s_info = { "RuntimeObject", 0, 0, 0 };

RuntimeObjectImp::RuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> instance)
    : JSObject(getDOMStructure<RuntimeObjectImp>(exec))
    , m_instance(instance)
{
    m_instance->rootObject()->addRuntimeObject(this);
}

RuntimeObjectImp::RuntimeObjectImp(ExecState*, PassRefPtr<Structure> structure, PassRefPtr<Instance> instance)
    : JSObject(structure)
    , m_instance(instance)
{
    m_instance->rootObject()->addRuntimeObject(this);
}

RuntimeObjectImp::~RuntimeObjectImp()
{
    if (m_instance)
        m_instance->rootObject()->removeRuntimeObject(this);
}

void RuntimeObjectImp::invalidate()
{
    ASSERT(m_instance);
    m_instance = 0;
}

JSValue RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
    RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
    RefPtr<Instance> instance = thisObj->m_instance;

    if (!instance)
        return throwInvalidAccessError(exec);
    
    instance->begin();

    Class *aClass = instance->getClass();
    JSValue result = aClass->fallbackObject(exec, instance.get(), propertyName);

    instance->end();
            
    return result;
}

JSValue RuntimeObjectImp::fieldGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{    
    RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
    RefPtr<Instance> instance = thisObj->m_instance;

    if (!instance)
        return throwInvalidAccessError(exec);
    
    instance->begin();

    Class *aClass = instance->getClass();
    Field* aField = aClass->fieldNamed(propertyName, instance.get());
    JSValue result = aField->valueFromInstance(exec, instance.get());
    
    instance->end();
            
    return result;
}

JSValue RuntimeObjectImp::methodGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
    RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
    RefPtr<Instance> instance = thisObj->m_instance;

    if (!instance)
        return throwInvalidAccessError(exec);
    
    instance->begin();

    Class *aClass = instance->getClass();
    MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
    JSValue result = new (exec) RuntimeMethod(exec, propertyName, methodList);

    instance->end();
            
    return result;
}

bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (!m_instance) {
        throwInvalidAccessError(exec);
        return false;
    }
    
    RefPtr<Instance> instance = m_instance;

    instance->begin();
    
    Class *aClass = instance->getClass();
    
    if (aClass) {
        // See if the instance has a field with the specified name.
        Field *aField = aClass->fieldNamed(propertyName, instance.get());
        if (aField) {
            slot.setCustom(this, fieldGetter);
            instance->end();
            return true;
        } else {
            // Now check if a method with specified name exists, if so return a function object for
            // that method.
            MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
            if (methodList.size() > 0) {
                slot.setCustom(this, methodGetter);
                
                instance->end();
                return true;
            }
        }

        // Try a fallback object.
        if (!aClass->fallbackObject(exec, instance.get(), propertyName).isUndefined()) {
            slot.setCustom(this, fallbackObjectGetter);
            instance->end();
            return true;
        }
    }
        
    instance->end();
    
    return instance->getOwnPropertySlot(this, exec, propertyName, slot);
}

void RuntimeObjectImp::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
    if (!m_instance) {
        throwInvalidAccessError(exec);
        return;
    }
    
    RefPtr<Instance> instance = m_instance;
    instance->begin();

    // Set the value of the property.
    Field *aField = instance->getClass()->fieldNamed(propertyName, instance.get());
    if (aField)
        aField->setValueToInstance(exec, instance.get(), value);
    else if (!instance->setValueOfUndefinedField(exec, propertyName, value))
        instance->put(this, exec, propertyName, value, slot);

    instance->end();
}

bool RuntimeObjectImp::deleteProperty(ExecState*, const Identifier&)
{
    // Can never remove a property of a RuntimeObject.
    return false;
}

JSValue RuntimeObjectImp::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
{
    if (!m_instance)
        return throwInvalidAccessError(exec);
    
    RefPtr<Instance> instance = m_instance;

    instance->begin();
    JSValue result = instance->defaultValue(exec, hint);
    instance->end();
    return result;
}

static JSValue JSC_HOST_CALL callRuntimeObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args)
{
    RefPtr<Instance> instance(static_cast<RuntimeObjectImp*>(function)->getInternalInstance());
    instance->begin();
    JSValue result = instance->invokeDefaultMethod(exec, args);
    instance->end();
    return result;
}

CallType RuntimeObjectImp::getCallData(CallData& callData)
{
    if (!m_instance)
        return CallTypeNone;
    
    RefPtr<Instance> instance = m_instance;
    if (!instance->supportsInvokeDefaultMethod())
        return CallTypeNone;
    
    callData.native.function = callRuntimeObject;
    return CallTypeHost;
}

static JSObject* callRuntimeConstructor(ExecState* exec, JSObject* constructor, const ArgList& args)
{
    RefPtr<Instance> instance(static_cast<RuntimeObjectImp*>(constructor)->getInternalInstance());
    instance->begin();
    JSValue result = instance->invokeConstruct(exec, args);
    instance->end();
    
    ASSERT(result);
    return result.isObject() ? static_cast<JSObject*>(result.asCell()) : constructor;
}

ConstructType RuntimeObjectImp::getConstructData(ConstructData& constructData)
{
    if (!m_instance)
        return ConstructTypeNone;
    
    RefPtr<Instance> instance = m_instance;
    if (!instance->supportsConstruct())
        return ConstructTypeNone;
    
    constructData.native.function = callRuntimeConstructor;
    return ConstructTypeHost;
}

void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
    if (!m_instance) {
        throwInvalidAccessError(exec);
        return;
    }

    RefPtr<Instance> instance = m_instance;

    instance->begin();
    instance->getPropertyNames(exec, propertyNames);
    instance->end();
}

JSObject* RuntimeObjectImp::throwInvalidAccessError(ExecState* exec)
{
    return throwError(exec, ReferenceError, "Trying to access object from destroyed plug-in.");
}

}
