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

#include "MediaQueryListListener.h"
#include "TestMediaQueryListListener.h"
#include "WebDOMMediaQueryListListener.h"
#include "WebExceptionHandler.h"
#include <wtf/GetPtr.h>
#include <wtf/RefPtr.h>

struct WebDOMTestMediaQueryListListener::WebDOMTestMediaQueryListListenerPrivate {
    WebDOMTestMediaQueryListListenerPrivate(WebCore::TestMediaQueryListListener* object = 0)
        : impl(object)
    {
    }

    RefPtr<WebCore::TestMediaQueryListListener> impl;
};

WebDOMTestMediaQueryListListener::WebDOMTestMediaQueryListListener()
    : WebDOMObject()
    , m_impl(0)
{
}

WebDOMTestMediaQueryListListener::WebDOMTestMediaQueryListListener(WebCore::TestMediaQueryListListener* impl)
    : WebDOMObject()
    , m_impl(new WebDOMTestMediaQueryListListenerPrivate(impl))
{
}

WebDOMTestMediaQueryListListener::WebDOMTestMediaQueryListListener(const WebDOMTestMediaQueryListListener& copy)
    : WebDOMObject()
{
    m_impl = copy.impl() ? new WebDOMTestMediaQueryListListenerPrivate(copy.impl()) : 0;
}

WebDOMTestMediaQueryListListener& WebDOMTestMediaQueryListListener::operator=(const WebDOMTestMediaQueryListListener& copy)
{
    delete m_impl;
    m_impl = copy.impl() ? new WebDOMTestMediaQueryListListenerPrivate(copy.impl()) : 0;
    return *this;
}

WebCore::TestMediaQueryListListener* WebDOMTestMediaQueryListListener::impl() const
{
    return m_impl ? m_impl->impl.get() : 0;
}

WebDOMTestMediaQueryListListener::~WebDOMTestMediaQueryListListener()
{
    delete m_impl;
    m_impl = 0;
}

void WebDOMTestMediaQueryListListener::method(const WebDOMMediaQueryListListener& listener)
{
    if (!impl())
        return;

    impl()->method(toWebCore(listener));
}

WebCore::TestMediaQueryListListener* toWebCore(const WebDOMTestMediaQueryListListener& wrapper)
{
    return wrapper.impl();
}

WebDOMTestMediaQueryListListener toWebKit(WebCore::TestMediaQueryListListener* value)
{
    return WebDOMTestMediaQueryListListener(value);
}
