/*
    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., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "config.h"
#include "V8TestMediaQueryListListener.h"

#include "ExceptionCode.h"
#include "MediaQueryListListener.h"
#include "RuntimeEnabledFeatures.h"
#include "V8Binding.h"
#include "V8BindingMacros.h"
#include "V8BindingState.h"
#include "V8DOMWrapper.h"
#include "V8IsolatedContext.h"
#include "V8Proxy.h"

namespace WebCore {

WrapperTypeInfo V8TestMediaQueryListListener::info = { V8TestMediaQueryListListener::GetTemplate, V8TestMediaQueryListListener::derefObject, 0, 0 };

namespace TestMediaQueryListListenerInternal {

template <typename T> void V8_USE(T) { }

static v8::Handle<v8::Value> methodCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.TestMediaQueryListListener.method");
    TestMediaQueryListListener* imp = V8TestMediaQueryListListener::toNative(args.Holder());
    EXCEPTION_BLOCK(RefPtr<MediaQueryListListener>, listener, MediaQueryListListener::create(args[0]));
    imp->method(listener);
    return v8::Handle<v8::Value>();
}

} // namespace TestMediaQueryListListenerInternal

static const BatchedCallback TestMediaQueryListListenerCallbacks[] = {
    {"method", TestMediaQueryListListenerInternal::methodCallback},
};
static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestMediaQueryListListenerTemplate(v8::Persistent<v8::FunctionTemplate> desc)
{
    v8::Local<v8::Signature> defaultSignature = configureTemplate(desc, "TestMediaQueryListListener", v8::Persistent<v8::FunctionTemplate>(), V8TestMediaQueryListListener::internalFieldCount,
        0, 0,
        TestMediaQueryListListenerCallbacks, WTF_ARRAY_LENGTH(TestMediaQueryListListenerCallbacks));
    v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
    v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
    

    // Custom toString template
    desc->Set(getToStringName(), getToStringTemplate());
    return desc;
}

v8::Persistent<v8::FunctionTemplate> V8TestMediaQueryListListener::GetRawTemplate()
{
    static v8::Persistent<v8::FunctionTemplate> V8TestMediaQueryListListenerRawCache = createRawTemplate();
    return V8TestMediaQueryListListenerRawCache;
}

v8::Persistent<v8::FunctionTemplate> V8TestMediaQueryListListener::GetTemplate()
{
    static v8::Persistent<v8::FunctionTemplate> V8TestMediaQueryListListenerCache = ConfigureV8TestMediaQueryListListenerTemplate(GetRawTemplate());
    return V8TestMediaQueryListListenerCache;
}

bool V8TestMediaQueryListListener::HasInstance(v8::Handle<v8::Value> value)
{
    return GetRawTemplate()->HasInstance(value);
}


v8::Handle<v8::Object> V8TestMediaQueryListListener::wrapSlow(TestMediaQueryListListener* impl)
{
    v8::Handle<v8::Object> wrapper;
    V8Proxy* proxy = 0;
    wrapper = V8DOMWrapper::instantiateV8Object(proxy, &info, impl);
    if (wrapper.IsEmpty())
        return wrapper;

    impl->ref();
    v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper);
    getDOMObjectMap().set(impl, wrapperHandle);
    return wrapper;
}

void V8TestMediaQueryListListener::derefObject(void* object)
{
    static_cast<TestMediaQueryListListener*>(object)->deref();
}

} // namespace WebCore
