/*
 * Copyright (C) 2012 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "PlatformWebView.h"

#include <WebKit/WKPagePrivateWPE.h>
#include <WebKit/WKRetainPtr.h>
#include <WebKit/WKView.h>

#if USE(LIBWPE)
#include <WPEToolingBackends/HeadlessViewBackend.h>
#endif

#if ENABLE(WPE_PLATFORM)
#include <wpe/headless/wpe-headless.h>
#endif

namespace TestWebKitAPI {

PlatformWebView::PlatformWebView(WKContextRef contextRef)
    : m_window(nullptr)
{
    WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate());
    WKPageConfigurationSetContext(configuration.get(), contextRef);

    initialize(configuration.get());
}

PlatformWebView::PlatformWebView(WKPageConfigurationRef configuration)
    : m_window(nullptr)
{
    initialize(configuration);
}

PlatformWebView::PlatformWebView(WKPageRef relatedPage)
    : m_window(nullptr)
{
    WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate());
    WKPageConfigurationSetContext(configuration.get(), WKPageGetContext(relatedPage));
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    WKPageConfigurationSetRelatedPage(configuration.get(), relatedPage);
    ALLOW_DEPRECATED_DECLARATIONS_END

    auto relatedConfiguration = adoptWK(WKPageCopyPageConfiguration(relatedPage));
    if (auto* preferences = WKPageConfigurationGetPreferences(relatedConfiguration.get()))
        WKPageConfigurationSetPreferences(configuration.get(), preferences);

    initialize(configuration.get());
}

PlatformWebView::~PlatformWebView()
{
    WKRelease(m_view);
#if ENABLE(WPE_PLATFORM)
    if (g_type_class_peek(WPE_TYPE_DISPLAY))
        return;
#endif
#if USE(LIBWPE)
    delete static_cast<WPEToolingBackends::HeadlessViewBackend*>(m_window);
#endif
}

void PlatformWebView::initialize(WKPageConfigurationRef configuration)
{
#if ENABLE(WPE_PLATFORM)
    if (g_type_class_peek(WPE_TYPE_DISPLAY)) {
        auto* display = wpe_display_get_primary();
        g_assert(WPE_IS_DISPLAY_HEADLESS(display));
        m_view = WKViewCreate(display, configuration);
        auto* wpeView = WKViewGetView(m_view);
        wpe_view_focus_in(wpeView);
        m_window = wpe_view_get_toplevel(wpeView);
        wpe_toplevel_resize(WPE_TOPLEVEL(m_window), 800, 600);
        return;
    }
#endif
#if USE(LIBWPE)
    m_window = new WPEToolingBackends::HeadlessViewBackend(800, 600);
    m_view = WKViewCreateDeprecated(static_cast<WPEToolingBackends::HeadlessViewBackend*>(m_window)->backend(), configuration);
#endif
}

WKPageRef PlatformWebView::page() const
{
    return WKViewGetPage(m_view);
}

void PlatformWebView::resizeTo(unsigned width, unsigned height)
{
    // FIXME: implement this.
}

void PlatformWebView::simulateSpacebarKeyPress()
{
    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
    WKPageHandleKeyboardEvent(page(), WKKeyboardEventMake(kWKEventKeyDown, kWKInputTypeNormal, " ", 1, WPE_KEY_space, 0x0041, 0));
    WKPageHandleKeyboardEvent(page(), WKKeyboardEventMake(kWKEventKeyUp, kWKInputTypeNormal, " ", 1, WPE_KEY_space, 0x0041, 0));
}

void PlatformWebView::simulateAltKeyPress()
{
    // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
    WKPageHandleKeyboardEvent(page(), WKKeyboardEventMake(kWKEventKeyDown, kWKInputTypeNormal, nullptr, 0, WPE_KEY_Alt_L, 0x0040, 0));
    WKPageHandleKeyboardEvent(page(), WKKeyboardEventMake(kWKEventKeyUp, kWKInputTypeNormal, nullptr, 0, WPE_KEY_Alt_L, 0x0040, 0));
}

void PlatformWebView::simulateRightClick(unsigned x, unsigned y)
{
    simulateButtonClick(kWKEventMouseButtonRightButton, x, y, 0);
}

void PlatformWebView::simulateButtonClick(WKEventMouseButton button, unsigned x, unsigned y, WKEventModifiers modifiers)
{
    WKPageHandleMouseEvent(page(), WKMouseEventMake(kWKEventMouseDown, button, WKPointMake(x, y), 0, modifiers));
    WKPageHandleMouseEvent(page(), WKMouseEventMake(kWKEventMouseUp, button, WKPointMake(x, y), 0, modifiers));
}

void PlatformWebView::simulateMouseMove(unsigned x, unsigned y, WKEventModifiers modifiers)
{
    WKPageHandleMouseEvent(page(), WKMouseEventMake(kWKEventMouseMove, kWKEventMouseButtonNoButton, WKPointMake(x, y), 0, modifiers));
}

} // namespace TestWebKitAPI
