/*
 * Copyright (C) 2011 Igalia S.L.
 *
 * 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 "WebKitWindowProperties.h"

#include "WebKitPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebURLRequest.h"
#include <WebCore/IntRect.h>
#include <glib/gi18n-lib.h>

/**
 * SECTION: WebKitWindowProperties
 * @short_description: Window properties of a #WebKitWebView
 * @title: WebKitWindowProperties
 * @see_also: #WebKitWebView::ready-to-show
 *
 * The content of a #WebKitWebView can request to change certain
 * properties of the window containing the view. This can include the x, y position
 * of the window, the width and height but also if a toolbar,
 * scrollbar, statusbar, locationbar should be visible to the user,
 * and the request to show the #WebKitWebView fullscreen.
 *
 * The #WebKitWebView::ready-to-show signal handler is the proper place
 * to apply the initial window properties. Then you can monitor the
 * #WebKitWindowProperties by connecting to ::notify signal.
 *
 * <informalexample><programlisting>
 * static void ready_to_show_cb (WebKitWebView *web_view, gpointer user_data)
 * {
 *     GtkWidget *window;
 *     WebKitWindowProperties *window_properties;
 *     gboolean visible;
 *
 *     /<!-- -->* Create the window to contain the WebKitWebView *<!-- -->/
 *     window = browser_window_new ();
 *     gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (web_view));
 *     gtk_widget_show (GTK_WIDGET (web_view));
 *
 *     /<!-- -->* Get the WebKitWindowProperties of the web view and monitor it *<!-- -->/
 *     window_properties = webkit_web_view_get_window_properties (web_view);
 *     g_signal_connect (window_properties, "notify::geometry",
 *                       G_CALLBACK (window_geometry_changed), window);
 *     g_signal_connect (window_properties, "notify::toolbar-visible",
 *                       G_CALLBACK (window_toolbar_visibility_changed), window);
 *     g_signal_connect (window_properties, "notify::menubar-visible",
 *                       G_CALLBACK (window_menubar_visibility_changed), window);
 *     ....
 *
 *     /<!-- -->* Apply the window properties before showing the window *<!-- -->/
 *     visible = webkit_window_properties_get_toolbar_visible (window_properties);
 *     browser_window_set_toolbar_visible (BROWSER_WINDOW (window), visible);
 *     visible = webkit_window_properties_get_menubar_visible (window_properties);
 *     browser_window_set_menubar_visible (BROWSER_WINDOW (window), visible);
 *     ....
 *
 *     if (webkit_window_properties_get_fullscreen (window_properties)) {
 *         gtk_window_fullscreen (GTK_WINDOW (window));
 *     } else {
 *         GdkRectangle geometry;
 *
 *         gtk_window_set_resizable (GTK_WINDOW (window),
 *                                   webkit_window_properties_get_resizable (window_properties));
 *         webkit_window_properties_get_geometry (window_properties, &geometry);
 *         gtk_window_move (GTK_WINDOW (window), geometry.x, geometry.y);
 *         gtk_window_resize (GTK_WINDOW (window), geometry.width, geometry.height);
 *     }
 *
 *     gtk_widget_show (window);
 * }
 * </programlisting></informalexample>
 */

enum {
    PROP_0,

    PROP_GEOMETRY,
    PROP_TOOLBAR_VISIBLE,
    PROP_STATUSBAR_VISIBLE,
    PROP_SCROLLBARS_VISIBLE,
    PROP_MENUBAR_VISIBLE,
    PROP_LOCATIONBAR_VISIBLE,
    PROP_RESIZABLE,
    PROP_FULLSCREEN
};

using namespace WebCore;

G_DEFINE_TYPE(WebKitWindowProperties, webkit_window_properties, G_TYPE_OBJECT)

struct _WebKitWindowPropertiesPrivate {
    GdkRectangle geometry;

    bool toolbarVisible : 1;
    bool statusbarVisible : 1;
    bool scrollbarsVisible : 1;
    bool menubarVisible : 1;
    bool locationbarVisible : 1;

    bool resizable : 1;
    bool fullscreen : 1;
};

static void webkitWindowPropertiesFinalize(GObject* object)
{
    WEBKIT_WINDOW_PROPERTIES(object)->priv->~WebKitWindowPropertiesPrivate();
    G_OBJECT_CLASS(webkit_window_properties_parent_class)->finalize(object);
}

static void webkitWindowPropertiesGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
    WebKitWindowProperties* windowProperties = WEBKIT_WINDOW_PROPERTIES(object);

    switch (propId) {
    case PROP_GEOMETRY:
        g_value_set_boxed(value, &windowProperties->priv->geometry);
        break;
    case PROP_TOOLBAR_VISIBLE:
        g_value_set_boolean(value, webkit_window_properties_get_toolbar_visible(windowProperties));
        break;
    case PROP_STATUSBAR_VISIBLE:
        g_value_set_boolean(value, webkit_window_properties_get_statusbar_visible(windowProperties));
        break;
    case PROP_SCROLLBARS_VISIBLE:
        g_value_set_boolean(value, webkit_window_properties_get_scrollbars_visible(windowProperties));
        break;
    case PROP_MENUBAR_VISIBLE:
        g_value_set_boolean(value, webkit_window_properties_get_menubar_visible(windowProperties));
        break;
    case PROP_LOCATIONBAR_VISIBLE:
        g_value_set_boolean(value, webkit_window_properties_get_locationbar_visible(windowProperties));
        break;
    case PROP_RESIZABLE:
        g_value_set_boolean(value, webkit_window_properties_get_resizable(windowProperties));
        break;
    case PROP_FULLSCREEN:
        g_value_set_boolean(value, webkit_window_properties_get_fullscreen(windowProperties));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkitWindowPropertiesSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
{
    WebKitWindowProperties* windowProperties = WEBKIT_WINDOW_PROPERTIES(object);

    switch (propId) {
    case PROP_GEOMETRY:
        if (GdkRectangle* geometry = static_cast<GdkRectangle*>(g_value_get_boxed(value)))
            windowProperties->priv->geometry = *geometry;
        break;
    case PROP_TOOLBAR_VISIBLE:
        windowProperties->priv->toolbarVisible = g_value_get_boolean(value);
        break;
    case PROP_STATUSBAR_VISIBLE:
        windowProperties->priv->statusbarVisible = g_value_get_boolean(value);
        break;
    case PROP_SCROLLBARS_VISIBLE:
        windowProperties->priv->scrollbarsVisible = g_value_get_boolean(value);
        break;
    case PROP_MENUBAR_VISIBLE:
        windowProperties->priv->menubarVisible = g_value_get_boolean(value);
        break;
    case PROP_LOCATIONBAR_VISIBLE:
        windowProperties->priv->locationbarVisible = g_value_get_boolean(value);
        break;
    case PROP_RESIZABLE:
        windowProperties->priv->resizable = g_value_get_boolean(value);
        break;
    case PROP_FULLSCREEN:
        windowProperties->priv->fullscreen = g_value_get_boolean(value);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkit_window_properties_class_init(WebKitWindowPropertiesClass* requestClass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);

    objectClass->finalize = webkitWindowPropertiesFinalize;
    objectClass->get_property = webkitWindowPropertiesGetProperty;
    objectClass->set_property = webkitWindowPropertiesSetProperty;

    GParamFlags paramFlags = static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);

    /**
     * WebKitWebWindowProperties:geometry:
     *
     * The size and position of the window on the screen.
     */
    g_object_class_install_property(objectClass,
                                    PROP_GEOMETRY,
                                    g_param_spec_boxed("geometry",
                                                       _("Geometry"),
                                                       _("The size and position of the window on the screen."),
                                                       GDK_TYPE_RECTANGLE,
                                                       paramFlags));

    /**
     * WebKitWebWindowProperties:toolbar-visible:
     *
     * Whether the toolbar should be visible for the window.
     */
    g_object_class_install_property(objectClass,
                                    PROP_TOOLBAR_VISIBLE,
                                    g_param_spec_boolean("toolbar-visible",
                                                         _("Toolbar Visible"),
                                                         _("Whether the toolbar should be visible for the window."),
                                                         TRUE,
                                                         paramFlags));

    /**
     * WebKitWebWindowProperties:statusbar-visible:
     *
     * Whether the statusbar should be visible for the window.
     */
    g_object_class_install_property(objectClass,
                                    PROP_STATUSBAR_VISIBLE,
                                    g_param_spec_boolean("statusbar-visible",
                                                         _("Statusbar Visible"),
                                                         _("Whether the statusbar should be visible for the window."),
                                                         TRUE,
                                                         paramFlags));

    /**
     * WebKitWebWindowProperties:scrollbars-visible:
     *
     * Whether the scrollbars should be visible for the window.
     */
    g_object_class_install_property(objectClass,
                                    PROP_SCROLLBARS_VISIBLE,
                                    g_param_spec_boolean("scrollbars-visible",
                                                         _("Scrollbars Visible"),
                                                         _("Whether the scrollbars should be visible for the window."),
                                                         TRUE,
                                                         paramFlags));

    /**
     * WebKitWebWindowProperties:menubar-visible:
     *
     * Whether the menubar should be visible for the window.
     */
    g_object_class_install_property(objectClass,
                                    PROP_MENUBAR_VISIBLE,
                                    g_param_spec_boolean("menubar-visible",
                                                         _("Menubar Visible"),
                                                         _("Whether the menubar should be visible for the window."),
                                                         TRUE,
                                                         paramFlags));

    /**
     * WebKitWebWindowProperties:locationbar-visible:
     *
     * Whether the locationbar should be visible for the window.
     */
    g_object_class_install_property(objectClass,
                                    PROP_LOCATIONBAR_VISIBLE,
                                    g_param_spec_boolean("locationbar-visible",
                                                         _("Locationbar Visible"),
                                                         _("Whether the locationbar should be visible for the window."),
                                                         TRUE,
                                                         paramFlags));
    /**
     * WebKitWebWindowProperties:resizable:
     *
     * Whether the window can be resized.
     */
    g_object_class_install_property(objectClass,
                                    PROP_RESIZABLE,
                                    g_param_spec_boolean("resizable",
                                                         _("Resizable"),
                                                         _("Whether the window can be resized."),
                                                         TRUE,
                                                         paramFlags));

    /**
     * WebKitWebWindowProperties:fullscreen:
     *
     * Whether window will be displayed fullscreen.
     */
    g_object_class_install_property(objectClass,
                                    PROP_FULLSCREEN,
                                    g_param_spec_boolean("fullscreen",
                                                         _("Fullscreen"),
                                                         _("Whether window will be displayed fullscreen."),
                                                         FALSE,
                                                         paramFlags));

    g_type_class_add_private(requestClass, sizeof(WebKitWindowPropertiesPrivate));
}

static void webkit_window_properties_init(WebKitWindowProperties* request)
{
    WebKitWindowPropertiesPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_WINDOW_PROPERTIES, WebKitWindowPropertiesPrivate);
    request->priv = priv;
    new (priv) WebKitWindowPropertiesPrivate();
}

WebKitWindowProperties* webkitWindowPropertiesCreate()
{
    return WEBKIT_WINDOW_PROPERTIES(g_object_new(WEBKIT_TYPE_WINDOW_PROPERTIES, NULL));
}

void webkitWindowPropertiesSetGeometry(WebKitWindowProperties* windowProperties, GdkRectangle* geometry)
{
    if (windowProperties->priv->geometry.x == geometry->x
        && windowProperties->priv->geometry.y == geometry->y
        && windowProperties->priv->geometry.width == geometry->width
        && windowProperties->priv->geometry.height == geometry->height)
        return;
    windowProperties->priv->geometry = *geometry;
    g_object_notify(G_OBJECT(windowProperties), "geometry");
}

void webkitWindowPropertiesSetToolbarVisible(WebKitWindowProperties* windowProperties, bool toolbarsVisible)
{
    if (windowProperties->priv->toolbarVisible == toolbarsVisible)
        return;
    windowProperties->priv->toolbarVisible = toolbarsVisible;
    g_object_notify(G_OBJECT(windowProperties), "toolbar-visible");
}

void webkitWindowPropertiesSetMenubarVisible(WebKitWindowProperties* windowProperties, bool menuBarVisible)
{
    if (windowProperties->priv->menubarVisible == menuBarVisible)
        return;
    windowProperties->priv->menubarVisible = menuBarVisible;
    g_object_notify(G_OBJECT(windowProperties), "menubar-visible");
}

void webkitWindowPropertiesSetStatusbarVisible(WebKitWindowProperties* windowProperties, bool statusBarVisible)
{
    if (windowProperties->priv->statusbarVisible == statusBarVisible)
        return;
    windowProperties->priv->statusbarVisible = statusBarVisible;
    g_object_notify(G_OBJECT(windowProperties), "statusbar-visible");
}

void webkitWindowPropertiesSetLocationbarVisible(WebKitWindowProperties* windowProperties, bool locationBarVisible)
{
    if (windowProperties->priv->locationbarVisible == locationBarVisible)
        return;
    windowProperties->priv->locationbarVisible = locationBarVisible;
    g_object_notify(G_OBJECT(windowProperties), "locationbar-visible");
}

void webkitWindowPropertiesSetScrollbarsVisible(WebKitWindowProperties* windowProperties, bool scrollBarsVisible)
{
    if (windowProperties->priv->scrollbarsVisible == scrollBarsVisible)
        return;
    windowProperties->priv->scrollbarsVisible = scrollBarsVisible;
    g_object_notify(G_OBJECT(windowProperties), "scrollbars-visible");
}

void webkitWindowPropertiesSetResizable(WebKitWindowProperties* windowProperties, bool resizable)
{
    if (windowProperties->priv->resizable == resizable)
        return;
    windowProperties->priv->resizable = resizable;
    g_object_notify(G_OBJECT(windowProperties), "resizable");
}

void webkitWindowPropertiesSetFullscreen(WebKitWindowProperties* windowProperties, bool fullscreen)
{
    if (windowProperties->priv->fullscreen == fullscreen)
        return;
    windowProperties->priv->fullscreen = fullscreen;
    g_object_notify(G_OBJECT(windowProperties), "fullscreen");
}

void webkitWindowPropertiesUpdateFromWKWindowFeatures(WebKitWindowProperties* windowProperties, WKDictionaryRef wkFeatures)
{
    GdkRectangle geometry = windowProperties->priv->geometry;

    WKDoubleRef doubleValue;
    WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("x"));
    if (doubleValue = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(wkFeatures, xKey.get())))
        geometry.x = WKDoubleGetValue(doubleValue);

    WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("y"));
    if (doubleValue = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(wkFeatures, yKey.get())))
        geometry.y = WKDoubleGetValue(doubleValue);

    WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
    if (doubleValue = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(wkFeatures, widthKey.get())))
        geometry.width = WKDoubleGetValue(doubleValue);

    WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
    if (doubleValue = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(wkFeatures, heightKey.get())))
        geometry.height = WKDoubleGetValue(doubleValue);
    webkitWindowPropertiesSetGeometry(windowProperties, &geometry);

    WKBooleanRef booleanValue;
    WKRetainPtr<WKStringRef> menuBarVisibleKey(AdoptWK, WKStringCreateWithUTF8CString("menuBarVisible"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, menuBarVisibleKey.get())))
        webkitWindowPropertiesSetMenubarVisible(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> statusBarVisibleKey(AdoptWK, WKStringCreateWithUTF8CString("statusBarVisible"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, statusBarVisibleKey.get())))
        webkitWindowPropertiesSetStatusbarVisible(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> toolBarVisibleKey(AdoptWK, WKStringCreateWithUTF8CString("toolBarVisible"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, toolBarVisibleKey.get())))
        webkitWindowPropertiesSetToolbarVisible(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> locationBarVisibleKey(AdoptWK, WKStringCreateWithUTF8CString("locationBarVisible"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, locationBarVisibleKey.get())))
        webkitWindowPropertiesSetLocationbarVisible(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> scrollbarsVisibleKey(AdoptWK, WKStringCreateWithUTF8CString("scrollbarsVisible"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, scrollbarsVisibleKey.get())))
        webkitWindowPropertiesSetScrollbarsVisible(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> resizableKey(AdoptWK, WKStringCreateWithUTF8CString("resizable"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, resizableKey.get())))
        webkitWindowPropertiesSetResizable(windowProperties, WKBooleanGetValue(booleanValue));

    WKRetainPtr<WKStringRef> fullscreenKey(AdoptWK, WKStringCreateWithUTF8CString("fullscreen"));
    if (booleanValue = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(wkFeatures, fullscreenKey.get())))
        webkitWindowPropertiesSetFullscreen(windowProperties, WKBooleanGetValue(booleanValue));
}

/**
 * webkit_window_properties_get_geometry:
 * @window_properties: a #WebKitWindowProperties
 * @geometry: (out): return location for the window geometry
 *
 * Get the geometry the window should have on the screen when shown.
 */
void webkit_window_properties_get_geometry(WebKitWindowProperties* windowProperties, GdkRectangle* geometry)
{
    g_return_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties));
    g_return_if_fail(geometry);

    *geometry = windowProperties->priv->geometry;
}

/**
 * webkit_window_properties_get_toolbar_visible:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should have the toolbar visible or not.
 *
 * Returns: %TRUE if toolbar should be visible or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_toolbar_visible(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->toolbarVisible;
}

/**
 * webkit_window_properties_get_statusbar_visible:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should have the statusbar visible or not.
 *
 * Returns: %TRUE if statusbar should be visible or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_statusbar_visible(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->statusbarVisible;
}

/**
 * webkit_window_properties_get_scrollbars_visible:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should have the scrollbars visible or not.
 *
 * Returns: %TRUE if scrollbars should be visible or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_scrollbars_visible(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->scrollbarsVisible;
}

/**
 * webkit_window_properties_get_menubar_visible:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should have the menubar visible or not.
 *
 * Returns: %TRUE if menubar should be visible or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_menubar_visible(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->menubarVisible;
}

/**
 * webkit_window_properties_get_locationbar_visible:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should have the locationbar visible or not.
 *
 * Returns: %TRUE if locationbar should be visible or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_locationbar_visible(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->locationbarVisible;
}

/**
 * webkit_window_properties_get_resizable:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should be resizable by the user or not.
 *
 * Returns: %TRUE if the window should be resizable or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_resizable(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), TRUE);

    return windowProperties->priv->resizable;
}

/**
 * webkit_window_properties_get_fullscreen:
 * @window_properties: a #WebKitWindowProperties
 *
 * Get whether the window should be shown in fullscreen state or not.
 *
 * Returns: %TRUE if the window should be fullscreen or %FALSE otherwise.
 */
gboolean webkit_window_properties_get_fullscreen(WebKitWindowProperties* windowProperties)
{
    g_return_val_if_fail(WEBKIT_IS_WINDOW_PROPERTIES(windowProperties), FALSE);

    return windowProperties->priv->fullscreen;
}
