// Copyright (c) 2012 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 "ui/gfx/gtk_util.h"

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

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkUnPreMultiply.h"
#include "ui/gfx/rect.h"

namespace {

// A process wide singleton that manages our usage of gdk cursors.
// gdk_cursor_new() hits the disk in several places and GdkCursor instances can
// be reused throughout the process.
class GdkCursorCache {
 public:
  GdkCursorCache() {}
  ~GdkCursorCache() {
    for (GdkCursorMap::iterator i(cursors_.begin()); i != cursors_.end(); ++i) {
      gdk_cursor_unref(i->second);
    }
    cursors_.clear();
  }

  GdkCursor* GetCursorImpl(GdkCursorType type) {
    GdkCursorMap::iterator it = cursors_.find(type);
    GdkCursor* cursor = NULL;
    if (it == cursors_.end()) {
      cursor = gdk_cursor_new(type);
      cursors_.insert(std::make_pair(type, cursor));
    } else {
      cursor = it->second;
    }

    // It is not necessary to add a reference here. The callers can ref the
    // cursor if they need it for something.
    return cursor;
  }

 private:
  typedef std::map<GdkCursorType, GdkCursor*> GdkCursorMap;
  GdkCursorMap cursors_;

  DISALLOW_COPY_AND_ASSIGN(GdkCursorCache);
};

}  // namespace

namespace gfx {

static void CommonInitFromCommandLine(const CommandLine& command_line,
                                      void (*init_func)(gint*, gchar***)) {
  const std::vector<std::string>& args = command_line.argv();
  int argc = args.size();
  scoped_ptr<char *[]> argv(new char *[argc + 1]);
  for (size_t i = 0; i < args.size(); ++i) {
    // TODO(piman@google.com): can gtk_init modify argv? Just being safe
    // here.
    argv[i] = strdup(args[i].c_str());
  }
  argv[argc] = NULL;
  char **argv_pointer = argv.get();

  init_func(&argc, &argv_pointer);
  for (size_t i = 0; i < args.size(); ++i) {
    free(argv[i]);
  }
}

void GtkInitFromCommandLine(const CommandLine& command_line) {
  CommonInitFromCommandLine(command_line, gtk_init);
}

void GdkInitFromCommandLine(const CommandLine& command_line) {
  CommonInitFromCommandLine(command_line, gdk_init);
}

GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
  if (bitmap.isNull())
    return NULL;

  SkAutoLockPixels lock_pixels(bitmap);

  int width = bitmap.width();
  int height = bitmap.height();

  GdkPixbuf* pixbuf = gdk_pixbuf_new(
      GDK_COLORSPACE_RGB,  // The only colorspace gtk supports.
      TRUE,  // There is an alpha channel.
      8,
      width, height);

  // SkBitmaps are premultiplied, we need to unpremultiply them.
  const int kBytesPerPixel = 4;
  uint8* divided = gdk_pixbuf_get_pixels(pixbuf);

  for (int y = 0, i = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      uint32 pixel = bitmap.getAddr32(0, y)[x];

      int alpha = SkColorGetA(pixel);
      if (alpha != 0 && alpha != 255) {
        SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
        divided[i + 0] = SkColorGetR(unmultiplied);
        divided[i + 1] = SkColorGetG(unmultiplied);
        divided[i + 2] = SkColorGetB(unmultiplied);
        divided[i + 3] = alpha;
      } else {
        divided[i + 0] = SkColorGetR(pixel);
        divided[i + 1] = SkColorGetG(pixel);
        divided[i + 2] = SkColorGetB(pixel);
        divided[i + 3] = alpha;
      }
      i += kBytesPerPixel;
    }
  }

  return pixbuf;
}

void SubtractRectanglesFromRegion(GdkRegion* region,
                                  const std::vector<Rect>& cutouts) {
  for (size_t i = 0; i < cutouts.size(); ++i) {
    GdkRectangle rect = cutouts[i].ToGdkRectangle();
    GdkRegion* rect_region = gdk_region_rectangle(&rect);
    gdk_region_subtract(region, rect_region);
    // TODO(deanm): It would be nice to be able to reuse the GdkRegion here.
    gdk_region_destroy(rect_region);
  }
}

GdkCursor* GetCursor(int type) {
  CR_DEFINE_STATIC_LOCAL(GdkCursorCache, impl, ());
  return impl.GetCursorImpl(static_cast<GdkCursorType>(type));
}

void InitRCStyles() {
  static const char kRCText[] =
      // Make our dialogs styled like the GNOME HIG.
      //
      // TODO(evanm): content-area-spacing was introduced in a later
      // version of GTK, so we need to set that manually on all dialogs.
      // Perhaps it would make sense to have a shared FixupDialog() function.
      "style \"gnome-dialog\" {\n"
      "  xthickness = 12\n"
      "  GtkDialog::action-area-border = 0\n"
      "  GtkDialog::button-spacing = 6\n"
      "  GtkDialog::content-area-spacing = 18\n"
      "  GtkDialog::content-area-border = 12\n"
      "}\n"
      // Note we set it at the "application" priority, so users can override.
      "widget \"GtkDialog\" style : application \"gnome-dialog\"\n"

      // Make our about dialog special, so the image is flush with the edge.
      "style \"about-dialog\" {\n"
      "  GtkDialog::action-area-border = 12\n"
      "  GtkDialog::button-spacing = 6\n"
      "  GtkDialog::content-area-spacing = 18\n"
      "  GtkDialog::content-area-border = 0\n"
      "}\n"
      "widget \"about-dialog\" style : application \"about-dialog\"\n";

  gtk_rc_parse_string(kRCText);
}

base::TimeDelta GetCursorBlinkCycle() {
  // From http://library.gnome.org/devel/gtk/unstable/GtkSettings.html, this is
  // the default value for gtk-cursor-blink-time.
  static const gint kGtkDefaultCursorBlinkTime = 1200;

  gint cursor_blink_time = kGtkDefaultCursorBlinkTime;
  gboolean cursor_blink = TRUE;
  g_object_get(gtk_settings_get_default(),
               "gtk-cursor-blink-time", &cursor_blink_time,
               "gtk-cursor-blink", &cursor_blink,
               NULL);
  return cursor_blink ?
         base::TimeDelta::FromMilliseconds(cursor_blink_time) :
         base::TimeDelta();
}

}  // namespace gfx
