/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"

#if ENABLE(GEOLOCATION)

#include "JSCoordinates.h"

#include "JSDOMBinding.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsCoordinatesLatitude(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesLongitude(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesAltitude(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesAccuracy(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesAltitudeAccuracy(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesHeading(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsCoordinatesSpeed(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSCoordinatesConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSCoordinatesPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSCoordinatesPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSCoordinatesPrototype* ptr = new (NotNull, JSC::allocateCell<JSCoordinatesPrototype>(vm.heap)) JSCoordinatesPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSCoordinatesPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

/* Hash table for prototype */

static const HashTableValue JSCoordinatesPrototypeTableValues[] =
{
    { "latitude", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesLatitude), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "longitude", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesLongitude), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "altitude", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesAltitude), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "accuracy", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesAccuracy), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "altitudeAccuracy", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesAltitudeAccuracy), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "heading", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesHeading), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "speed", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCoordinatesSpeed), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};

const ClassInfo JSCoordinatesPrototype::s_info = { "CoordinatesPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCoordinatesPrototype) };

void JSCoordinatesPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSCoordinatesPrototypeTableValues, *this);
}

const ClassInfo JSCoordinates::s_info = { "Coordinates", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCoordinates) };

JSCoordinates::JSCoordinates(Structure* structure, JSDOMGlobalObject& globalObject, Ref<Coordinates>&& impl)
    : JSDOMWrapper<Coordinates>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSCoordinates::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSCoordinatesPrototype::create(vm, globalObject, JSCoordinatesPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

JSObject* JSCoordinates::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSCoordinates>(vm, globalObject);
}

void JSCoordinates::destroy(JSC::JSCell* cell)
{
    JSCoordinates* thisObject = static_cast<JSCoordinates*>(cell);
    thisObject->JSCoordinates::~JSCoordinates();
}

EncodedJSValue jsCoordinatesLatitude(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "latitude");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.latitude());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesLongitude(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "longitude");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.longitude());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesAltitude(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "altitude");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toNullableJSNumber(impl.altitude());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesAccuracy(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "accuracy");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.accuracy());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesAltitudeAccuracy(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "altitudeAccuracy");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toNullableJSNumber(impl.altitudeAccuracy());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesHeading(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "heading");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toNullableJSNumber(impl.heading());
    return JSValue::encode(result);
}


EncodedJSValue jsCoordinatesSpeed(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSCoordinates*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "Coordinates", "speed");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toNullableJSNumber(impl.speed());
    return JSValue::encode(result);
}


bool setJSCoordinatesConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSCoordinatesPrototype* domObject = jsDynamicCast<JSCoordinatesPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

bool JSCoordinatesOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    UNUSED_PARAM(handle);
    UNUSED_PARAM(visitor);
    return false;
}

void JSCoordinatesOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsCoordinates = jsCast<JSCoordinates*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsCoordinates->wrapped(), jsCoordinates);
}

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<Coordinates>&& impl)
{
#if COMPILER(CLANG)
    // If you hit this failure the interface definition has the ImplementationLacksVTable
    // attribute. You should remove that attribute. If the class has subclasses
    // that may be passed through this toJS() function you should use the SkipVTableValidation
    // attribute to Coordinates.
    static_assert(!__is_polymorphic(Coordinates), "Coordinates is polymorphic but the IDL claims it is not");
#endif
    return createWrapper<Coordinates>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, Coordinates& impl)
{
    return wrap(state, globalObject, impl);
}

Coordinates* JSCoordinates::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSCoordinates*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}

#endif // ENABLE(GEOLOCATION)
