// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/webcursor.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include "base/logging.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
#include "ui/gfx/gtk_util.h"

using WebKit::WebCursorInfo;

namespace {

// webcursor_gtk_data.h is taken directly from WebKit's CursorGtk.h.
#include "webkit/glue/webcursor_gtk_data.h"

// This helper function is taken directly from WebKit's CursorGtk.cpp.
// It attempts to create a custom cursor from the data inlined in
// webcursor_gtk_data.h.
GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
  static GdkCursor* CustomCursorsGdk[G_N_ELEMENTS(CustomCursors)];
  GdkCursor* cursor = CustomCursorsGdk[type];
  if (cursor)
    return cursor;
  const CustomCursor& custom = CustomCursors[type];
  cursor = gdk_cursor_new_from_name(gdk_display_get_default(), custom.name);
  if (!cursor) {
    const GdkColor fg = { 0, 0, 0, 0 };
    const GdkColor bg = { 65535, 65535, 65535, 65535 };
    GdkPixmap* source = gdk_bitmap_create_from_data(NULL, custom.bits,
                                                    32, 32);
    GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, custom.mask_bits,
                                                  32, 32);
    cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg,
                                        custom.hot_x, custom.hot_y);
    g_object_unref(source);
    g_object_unref(mask);
  }
  CustomCursorsGdk[type] = cursor;
  return cursor;
}

// For GTK 2.16 and beyond, GDK_BLANK_CURSOR is available. Before, we have to
// use a custom cursor.
#if !GTK_CHECK_VERSION(2, 16, 0)
// Get/create a custom cursor which is invisible.
GdkCursor* GetInvisibleCustomCursor() {
  static GdkCursor* cursor = NULL;
  if (cursor)
    return cursor;
  const char bits[] = { 0 };
  const GdkColor color = { 0, 0, 0, 0 };
  GdkPixmap* bitmap = gdk_bitmap_create_from_data(NULL, bits, 1, 1);
  cursor = gdk_cursor_new_from_pixmap(bitmap, bitmap, &color, &color, 0, 0);
  g_object_unref(bitmap);
  return cursor;
}
#endif

}  // end anonymous namespace

int WebCursor::GetCursorType() const {
  // http://library.gnome.org/devel/gdk/2.12/gdk-Cursors.html has images
  // of the default X theme, but beware that the user's cursor theme can
  // change everything.
  switch (type_) {
    case WebCursorInfo::TypePointer:
      return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCross:
      return GDK_CROSS;
    case WebCursorInfo::TypeHand:
      return GDK_HAND2;
    case WebCursorInfo::TypeIBeam:
      return GDK_XTERM;
    case WebCursorInfo::TypeWait:
      return GDK_WATCH;
    case WebCursorInfo::TypeHelp:
      return GDK_QUESTION_ARROW;
    case WebCursorInfo::TypeEastResize:
      return GDK_RIGHT_SIDE;
    case WebCursorInfo::TypeNorthResize:
      return GDK_TOP_SIDE;
    case WebCursorInfo::TypeNorthEastResize:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestResize:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthResize:
      return GDK_BOTTOM_SIDE;
    case WebCursorInfo::TypeSouthEastResize:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestResize:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestResize:
      return GDK_LEFT_SIDE;
    case WebCursorInfo::TypeNorthSouthResize:
      return GDK_SB_V_DOUBLE_ARROW;
    case WebCursorInfo::TypeEastWestResize:
      return GDK_SB_H_DOUBLE_ARROW;
    case WebCursorInfo::TypeNorthEastSouthWestResize:
    case WebCursorInfo::TypeNorthWestSouthEastResize:
      // There isn't really a useful cursor available for these.
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeColumnResize:
      return GDK_SB_H_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeRowResize:
      return GDK_SB_V_DOUBLE_ARROW;  // TODO(evanm): is this correct?
    case WebCursorInfo::TypeMiddlePanning:
      return GDK_FLEUR;
    case WebCursorInfo::TypeEastPanning:
      return GDK_SB_RIGHT_ARROW;
    case WebCursorInfo::TypeNorthPanning:
      return GDK_SB_UP_ARROW;
    case WebCursorInfo::TypeNorthEastPanning:
      return GDK_TOP_RIGHT_CORNER;
    case WebCursorInfo::TypeNorthWestPanning:
      return GDK_TOP_LEFT_CORNER;
    case WebCursorInfo::TypeSouthPanning:
      return GDK_SB_DOWN_ARROW;
    case WebCursorInfo::TypeSouthEastPanning:
      return GDK_BOTTOM_RIGHT_CORNER;
    case WebCursorInfo::TypeSouthWestPanning:
      return GDK_BOTTOM_LEFT_CORNER;
    case WebCursorInfo::TypeWestPanning:
      return GDK_SB_LEFT_ARROW;
    case WebCursorInfo::TypeMove:
      return GDK_FLEUR;
    case WebCursorInfo::TypeVerticalText:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCell:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeContextMenu:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeAlias:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeProgress:
      return GDK_WATCH;
    case WebCursorInfo::TypeNoDrop:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeCopy:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeNone:
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
      return GDK_CURSOR_IS_PIXMAP;
#else
      return GDK_BLANK_CURSOR;
#endif
    case WebCursorInfo::TypeNotAllowed:
      NOTIMPLEMENTED(); return GDK_LAST_CURSOR;
    case WebCursorInfo::TypeZoomIn:
    case WebCursorInfo::TypeZoomOut:
    case WebCursorInfo::TypeGrab:
    case WebCursorInfo::TypeGrabbing:
    case WebCursorInfo::TypeCustom:
      return GDK_CURSOR_IS_PIXMAP;
  }
  NOTREACHED();
  return GDK_LAST_CURSOR;
}

gfx::NativeCursor WebCursor::GetNativeCursor() {
  int type = GetCursorType();
  if (type == GDK_CURSOR_IS_PIXMAP)
    return GetCustomCursor();
  return gfx::GetCursor(type);
}

GdkCursor* WebCursor::GetCustomCursor() {
  switch (type_) {
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
    case WebCursorInfo::TypeNone:
      return GetInvisibleCustomCursor();
#endif
    case WebCursorInfo::TypeZoomIn:
      return GetInlineCustomCursor(CustomCursorZoomIn);
    case WebCursorInfo::TypeZoomOut:
      return GetInlineCustomCursor(CustomCursorZoomOut);
    case WebCursorInfo::TypeGrab:
      return GetInlineCustomCursor(CustomCursorGrab);
    case WebCursorInfo::TypeGrabbing:
      return GetInlineCustomCursor(CustomCursorGrabbing);
  }

  if (type_ != WebCursorInfo::TypeCustom) {
    NOTREACHED();
    return NULL;
  }

  SkBitmap bitmap;
  bitmap.setConfig(SkBitmap::kARGB_8888_Config,
                   custom_size_.width(), custom_size_.height());
  bitmap.allocPixels();
  memcpy(bitmap.getAddr32(0, 0), custom_data_.data(), custom_data_.size());

  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap);
  GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
                                                 pixbuf,
                                                 hotspot_.x(),
                                                 hotspot_.y());

  gdk_pixbuf_unref(pixbuf);

  if (unref_)
    gdk_cursor_unref(unref_);
  unref_ = cursor;
  return cursor;
}

void WebCursor::InitPlatformData() {
  unref_ = NULL;
  return;
}

bool WebCursor::SerializePlatformData(Pickle* pickle) const {
  return true;
}

bool WebCursor::DeserializePlatformData(const Pickle* pickle, void** iter) {
  return true;
}

bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
  return true;
}

void WebCursor::CleanupPlatformData() {
  if (unref_) {
    gdk_cursor_unref(unref_);
    unref_ = NULL;
  }
  return;
}

void WebCursor::CopyPlatformData(const WebCursor& other) {
  if (other.unref_)
    unref_ = gdk_cursor_ref(other.unref_);
  return;
}
