/*
 * Copyright (C) 2009, 2010 Igalia S.L.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "config.h"
#include "DragClientGtk.h"

#include "ClipboardGtk.h"
#include "ClipboardUtilitiesGtk.h"
#include "DataObjectGtk.h"
#include "Document.h"
#include "DragController.h"
#include "Element.h"
#include "Frame.h"
#include "GOwnPtrGtk.h"
#include "GRefPtrGtk.h"
#include "GtkVersioning.h"
#include "NotImplemented.h"
#include "PasteboardHelper.h"
#include "RenderObject.h"
#include "webkitwebframeprivate.h"
#include "webkitwebviewprivate.h"
#include "webkitwebview.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h>

using namespace WebCore;

namespace WebKit {

#ifdef GTK_API_VERSION_2
static gboolean dragIconWindowDrawEventCallback(GtkWidget* widget, GdkEventExpose* event, DragClient* client)
{
    RefPtr<cairo_t> context = adoptRef(gdk_cairo_create(event->window));
    client->drawDragIconWindow(widget, context.get());
    return TRUE;
}
#else
static gboolean dragIconWindowDrawEventCallback(GtkWidget* widget, cairo_t* context, DragClient* client)
{
    if (!gdk_cairo_get_clip_rectangle(context, 0))
        return FALSE;
    client->drawDragIconWindow(widget, context);
    return TRUE;
}
#endif // GTK_API_VERSION_2

DragClient::DragClient(WebKitWebView* webView)
    : m_webView(webView)
    , m_startPos(0, 0)
    , m_dragIconWindow(gtk_window_new(GTK_WINDOW_POPUP))
{
#ifdef GTK_API_VERSION_2
    g_signal_connect(m_dragIconWindow, "expose-event", G_CALLBACK(dragIconWindowDrawEventCallback), this);
#else
    g_signal_connect(m_dragIconWindow, "draw", G_CALLBACK(dragIconWindowDrawEventCallback), this);
#endif
}

DragClient::~DragClient()
{
    gtk_widget_destroy(m_dragIconWindow);
}

void DragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*)
{
}

void DragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint& startPos, Clipboard*)
{
    m_startPos = startPos;
}

DragDestinationAction DragClient::actionMaskForDrag(DragData*)
{
    notImplemented();
    return DragDestinationActionAny;
}

DragSourceAction DragClient::dragSourceActionMaskForPoint(const IntPoint&)
{
    notImplemented();
    return DragSourceActionAny;
}

void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool linkDrag)
{
    ClipboardGtk* clipboardGtk = reinterpret_cast<ClipboardGtk*>(clipboard);

    WebKitWebView* webView = webkit_web_frame_get_web_view(kit(frame));
    RefPtr<DataObjectGtk> dataObject = clipboardGtk->dataObject();
    GRefPtr<GtkTargetList> targetList(clipboardGtk->helper()->targetListForDataObject(dataObject.get()));
    GOwnPtr<GdkEvent> currentEvent(gtk_get_current_event());

    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, currentEvent.get());
    webView->priv->draggingDataObjects.set(context, dataObject);

    // A drag starting should prevent a double-click from happening. This might
    // happen if a drag is followed very quickly by another click (like in the DRT).
    webView->priv->previousClickTime = 0;

    // This strategy originally comes from Chromium:
    // src/chrome/browser/gtk/tab_contents_drag_source.cc
    if (image) {
        m_dragImage = image;
        IntSize imageSize(cairo_image_surface_get_width(image), cairo_image_surface_get_height(image));
        gtk_window_resize(GTK_WINDOW(m_dragIconWindow), imageSize.width(), imageSize.height());

        if (!gtk_widget_get_realized(m_dragIconWindow)) {
            GdkScreen* screen = gtk_widget_get_screen(m_dragIconWindow);
#ifdef GTK_API_VERSION_2
            GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen);
            if (rgba)
                gtk_widget_set_colormap(m_dragIconWindow, rgba);
#else
            GdkVisual* visual = gdk_screen_get_rgba_visual(screen);
            if (!visual)
                visual = gdk_screen_get_system_visual(screen);
            gtk_widget_set_visual(m_dragIconWindow, visual);
#endif // GTK_API_VERSION_2
        }

        IntSize origin = eventPos - dragImageOrigin;
        gtk_drag_set_icon_widget(context, m_dragIconWindow,
                                 origin.width(), origin.height());
    } else
        gtk_drag_set_icon_default(context);
}

void DragClient::drawDragIconWindow(GtkWidget* widget, cairo_t* context)
{
    cairo_rectangle(context, 0, 0,
                    cairo_image_surface_get_width(m_dragImage.get()),
                    cairo_image_surface_get_height(m_dragImage.get()));
    cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
    cairo_set_source_surface(context, m_dragImage.get(), 0, 0);
    cairo_fill(context);
}

void DragClient::dragControllerDestroyed()
{
    delete this;
}
}
