/*
    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 "JSMediaQueryListListener.h"

#include "JSMediaQueryList.h"
#include "ScriptExecutionContext.h"
#include <runtime/JSLock.h>

using namespace JSC;

namespace WebCore {

JSMediaQueryListListener::JSMediaQueryListListener(JSObject* callback, JSDOMGlobalObject* globalObject)
    : MediaQueryListListener(JSMediaQueryListListenerType)
    , ActiveDOMCallback(globalObject->scriptExecutionContext())
    , m_data(new JSCallbackDataStrong(callback, this))
{
}

JSMediaQueryListListener::~JSMediaQueryListListener()
{
    ScriptExecutionContext* context = scriptExecutionContext();
    // When the context is destroyed, all tasks with a reference to a callback
    // should be deleted. So if the context is 0, we are on the context thread.
    if (!context || context->isContextThread())
        delete m_data;
    else
        context->postTask(DeleteCallbackDataTask(m_data));
#ifndef NDEBUG
    m_data = nullptr;
#endif
}

bool JSMediaQueryListListener::operator==(const MediaQueryListListener& other) const
{
    if (other.type() != type())
        return false;
    return static_cast<const JSMediaQueryListListener*>(&other)->m_data->callback() == m_data->callback();
}


// Functions

bool JSMediaQueryListListener::queryChanged(MediaQueryList* list)
{
    if (!canInvokeCallback())
        return true;

    Ref<JSMediaQueryListListener> protectedThis(*this);

    JSLockHolder lock(m_data->globalObject()->vm());

    ExecState* state = m_data->globalObject()->globalExec();
    MarkedArgumentBuffer args;
    args.append(toJS(state, m_data->globalObject(), list));

    NakedPtr<JSC::Exception> returnedException;
    UNUSED_PARAM(state);
    m_data->invokeCallback(args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
    if (returnedException)
        reportException(state, returnedException);
    return !returnedException;
}

JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, MediaQueryListListener& impl)
{
    if (!static_cast<JSMediaQueryListListener&>(impl).callbackData())
        return jsNull();

    return static_cast<JSMediaQueryListListener&>(impl).callbackData()->callback();

}

}
