/*
    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"
#include "JSSVGPreserveAspectRatio.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include <runtime/FunctionPrototype.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsSVGPreserveAspectRatioAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSSVGPreserveAspectRatioAlign(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsSVGPreserveAspectRatioMeetOrSlice(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSSVGPreserveAspectRatioMeetOrSlice(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsSVGPreserveAspectRatioConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSSVGPreserveAspectRatioConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSSVGPreserveAspectRatioPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSSVGPreserveAspectRatioPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSSVGPreserveAspectRatioPrototype* ptr = new (NotNull, JSC::allocateCell<JSSVGPreserveAspectRatioPrototype>(vm.heap)) JSSVGPreserveAspectRatioPrototype(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:
    JSSVGPreserveAspectRatioPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

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

typedef JSDOMConstructorNotConstructable<JSSVGPreserveAspectRatio> JSSVGPreserveAspectRatioConstructor;

/* Hash table for constructor */

static const HashTableValue JSSVGPreserveAspectRatioConstructorTableValues[] =
{
    { "SVG_PRESERVEASPECTRATIO_UNKNOWN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "SVG_PRESERVEASPECTRATIO_NONE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(3) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(4) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(5) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(6) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(7) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(8) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(9) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(10) } },
    { "SVG_MEETORSLICE_UNKNOWN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "SVG_MEETORSLICE_MEET", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "SVG_MEETORSLICE_SLICE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
};

static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN == 0, "SVG_PRESERVEASPECTRATIO_UNKNOWN in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE == 1, "SVG_PRESERVEASPECTRATIO_NONE in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN == 2, "SVG_PRESERVEASPECTRATIO_XMINYMIN in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN == 3, "SVG_PRESERVEASPECTRATIO_XMIDYMIN in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN == 4, "SVG_PRESERVEASPECTRATIO_XMAXYMIN in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID == 5, "SVG_PRESERVEASPECTRATIO_XMINYMID in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID == 6, "SVG_PRESERVEASPECTRATIO_XMIDYMID in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID == 7, "SVG_PRESERVEASPECTRATIO_XMAXYMID in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX == 8, "SVG_PRESERVEASPECTRATIO_XMINYMAX in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX == 9, "SVG_PRESERVEASPECTRATIO_XMIDYMAX in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX == 10, "SVG_PRESERVEASPECTRATIO_XMAXYMAX in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN == 0, "SVG_MEETORSLICE_UNKNOWN in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET == 1, "SVG_MEETORSLICE_MEET in SVGPreserveAspectRatio does not match value from IDL");
static_assert(SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE == 2, "SVG_MEETORSLICE_SLICE in SVGPreserveAspectRatio does not match value from IDL");

template<> JSValue JSSVGPreserveAspectRatioConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(vm);
    return globalObject.functionPrototype();
}

template<> void JSSVGPreserveAspectRatioConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSSVGPreserveAspectRatio::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("SVGPreserveAspectRatio"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
    reifyStaticProperties(vm, JSSVGPreserveAspectRatioConstructorTableValues, *this);
}

template<> const ClassInfo JSSVGPreserveAspectRatioConstructor::s_info = { "SVGPreserveAspectRatio", &Base::s_info, 0, CREATE_METHOD_TABLE(JSSVGPreserveAspectRatioConstructor) };

/* Hash table for prototype */

static const HashTableValue JSSVGPreserveAspectRatioPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPreserveAspectRatioConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSSVGPreserveAspectRatioConstructor) } },
    { "align", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPreserveAspectRatioAlign), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSSVGPreserveAspectRatioAlign) } },
    { "meetOrSlice", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPreserveAspectRatioMeetOrSlice), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSSVGPreserveAspectRatioMeetOrSlice) } },
    { "SVG_PRESERVEASPECTRATIO_UNKNOWN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "SVG_PRESERVEASPECTRATIO_NONE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(3) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMIN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(4) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(5) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(6) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMID", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(7) } },
    { "SVG_PRESERVEASPECTRATIO_XMINYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(8) } },
    { "SVG_PRESERVEASPECTRATIO_XMIDYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(9) } },
    { "SVG_PRESERVEASPECTRATIO_XMAXYMAX", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(10) } },
    { "SVG_MEETORSLICE_UNKNOWN", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(0) } },
    { "SVG_MEETORSLICE_MEET", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(1) } },
    { "SVG_MEETORSLICE_SLICE", DontDelete | ReadOnly | ConstantInteger, NoIntrinsic, { (long long)(2) } },
};

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

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

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

JSSVGPreserveAspectRatio::JSSVGPreserveAspectRatio(Structure* structure, JSDOMGlobalObject& globalObject, Ref<SVGPropertyTearOff<SVGPreserveAspectRatio>>&& impl)
    : JSDOMWrapper<SVGPropertyTearOff<SVGPreserveAspectRatio>>(structure, globalObject, WTFMove(impl))
{
}

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

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

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

EncodedJSValue jsSVGPreserveAspectRatioAlign(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<JSSVGPreserveAspectRatio*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "SVGPreserveAspectRatio", "align");
    }
    SVGPreserveAspectRatio& impl = castedThis->wrapped().propertyReference();
    JSValue result = jsNumber(impl.align());
    return JSValue::encode(result);
}


EncodedJSValue jsSVGPreserveAspectRatioMeetOrSlice(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<JSSVGPreserveAspectRatio*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "SVGPreserveAspectRatio", "meetOrSlice");
    }
    SVGPreserveAspectRatio& impl = castedThis->wrapped().propertyReference();
    JSValue result = jsNumber(impl.meetOrSlice());
    return JSValue::encode(result);
}


EncodedJSValue jsSVGPreserveAspectRatioConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSSVGPreserveAspectRatioPrototype* domObject = jsDynamicCast<JSSVGPreserveAspectRatioPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSSVGPreserveAspectRatio::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSSVGPreserveAspectRatioConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSSVGPreserveAspectRatioPrototype* domObject = jsDynamicCast<JSSVGPreserveAspectRatioPrototype*>(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 setJSSVGPreserveAspectRatioAlign(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSSVGPreserveAspectRatio* castedThis = jsDynamicCast<JSSVGPreserveAspectRatio*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "SVGPreserveAspectRatio", "align");
    }
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto nativeValue = convert<uint16_t>(*state, value, NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, false);
    if (impl.isReadOnly()) {
        setDOMException(state, throwScope, NO_MODIFICATION_ALLOWED_ERR);
        return false;
    }
    SVGPreserveAspectRatio& podImpl = impl.propertyReference();
    podImpl.setAlign(nativeValue, ec);
    setDOMException(state, throwScope, ec);
    if (LIKELY(!ec))
        impl.commitChange();
    return true;
}


bool setJSSVGPreserveAspectRatioMeetOrSlice(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSSVGPreserveAspectRatio* castedThis = jsDynamicCast<JSSVGPreserveAspectRatio*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "SVGPreserveAspectRatio", "meetOrSlice");
    }
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    auto nativeValue = convert<uint16_t>(*state, value, NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, false);
    if (impl.isReadOnly()) {
        setDOMException(state, throwScope, NO_MODIFICATION_ALLOWED_ERR);
        return false;
    }
    SVGPreserveAspectRatio& podImpl = impl.propertyReference();
    podImpl.setMeetOrSlice(nativeValue, ec);
    setDOMException(state, throwScope, ec);
    if (LIKELY(!ec))
        impl.commitChange();
    return true;
}


JSValue JSSVGPreserveAspectRatio::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSSVGPreserveAspectRatioConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

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

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

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<SVGPropertyTearOff<SVGPreserveAspectRatio>>&& impl)
{
    return createWrapper<SVGPropertyTearOff<SVGPreserveAspectRatio>>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, SVGPropertyTearOff<SVGPreserveAspectRatio>& impl)
{
    return wrap(state, globalObject, impl);
}

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

}
