// 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 "chrome/browser/ui/gtk/rounded_window.h"

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

#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "ui/base/gtk/gtk_signal_registrar.h"
#include "ui/gfx/gtk_compat.h"

namespace gtk_util {

namespace {

const char* kRoundedData = "rounded-window-data";

// If the border radius is less than |kMinRoundedBorderSize|, we don't actually
// round the corners, we just truncate the corner.
const int kMinRoundedBorderSize = 8;

struct RoundedWindowData {
  // Expected window size. Used to detect when we need to reshape the window.
  int expected_width;
  int expected_height;

  // Color of the border.
  GdkColor border_color;

  // Radius of the edges in pixels.
  int corner_size;

  // Which corners should be rounded?
  int rounded_edges;

  // Which sides of the window should have an internal border?
  int drawn_borders;

  // Keeps track of attached signal handlers.
  ui::GtkSignalRegistrar signals;
};

// Callback from GTK to release allocated memory.
void FreeRoundedWindowData(gpointer data) {
  delete static_cast<RoundedWindowData*>(data);
}

enum FrameType {
  FRAME_MASK,
  FRAME_STROKE,
};

// Returns a list of points that either form the outline of the status bubble
// (|type| == FRAME_MASK) or form the inner border around the inner edge
// (|type| == FRAME_STROKE).
std::vector<GdkPoint> MakeFramePolygonPoints(RoundedWindowData* data,
                                             FrameType type) {
  using gtk_util::MakeBidiGdkPoint;
  int width = data->expected_width;
  int height = data->expected_height;
  int corner_size = data->corner_size;

  std::vector<GdkPoint> points;

  bool ltr = !base::i18n::IsRTL();
  // If we have a stroke, we have to offset some of our points by 1 pixel.
  // We have to inset by 1 pixel when we draw horizontal lines that are on the
  // bottom or when we draw vertical lines that are closer to the end (end is
  // right for ltr).
  int y_off = (type == FRAME_MASK) ? 0 : -1;
  // We use this one for LTR.
  int x_off_l = ltr ? y_off : 0;
  // We use this one for RTL.
  int x_off_r = !ltr ? -y_off : 0;

  // Build up points starting with the bottom left corner and continuing
  // clockwise.

  // Bottom left corner.
  if (type == FRAME_MASK ||
      (data->drawn_borders & (BORDER_LEFT | BORDER_BOTTOM))) {
    if (data->rounded_edges & ROUNDED_BOTTOM_LEFT) {
      if (corner_size >= kMinRoundedBorderSize) {
        // We are careful to only add points that are horizontal or vertically
        // offset from the previous point (not both).  This avoids rounding
        // differences when two points are connected.
        for (int x = 0; x <= corner_size; ++x) {
          int y = static_cast<int>(sqrt(static_cast<double>(
              (corner_size * corner_size) - (x * x))));
          if (x > 0) {
            points.push_back(MakeBidiGdkPoint(
                corner_size - x + x_off_r + 1,
                height - (corner_size - y) + y_off, width, ltr));
          }
          points.push_back(MakeBidiGdkPoint(
              corner_size - x + x_off_r,
              height - (corner_size - y) + y_off, width, ltr));
        }
      } else {
        points.push_back(MakeBidiGdkPoint(
            corner_size + x_off_l, height + y_off, width, ltr));
        points.push_back(MakeBidiGdkPoint(
            x_off_r, height - corner_size, width, ltr));
      }
    } else {
      points.push_back(MakeBidiGdkPoint(x_off_r, height + y_off, width, ltr));
    }
  }

  // Top left corner.
  if (type == FRAME_MASK ||
      (data->drawn_borders & (BORDER_LEFT | BORDER_TOP))) {
    if (data->rounded_edges & ROUNDED_TOP_LEFT) {
      if (corner_size >= kMinRoundedBorderSize) {
        for (int x = corner_size; x >= 0; --x) {
          int y = static_cast<int>(sqrt(static_cast<double>(
              (corner_size * corner_size) - (x * x))));
          points.push_back(MakeBidiGdkPoint(corner_size - x + x_off_r,
              corner_size - y, width, ltr));
          if (x > 0) {
            points.push_back(MakeBidiGdkPoint(corner_size - x + 1 + x_off_r,
                corner_size - y, width, ltr));
          }
        }
      } else {
        points.push_back(MakeBidiGdkPoint(
            x_off_r, corner_size - 1, width, ltr));
        points.push_back(MakeBidiGdkPoint(
            corner_size + x_off_r - 1, 0, width, ltr));
      }
    } else {
      points.push_back(MakeBidiGdkPoint(x_off_r, 0, width, ltr));
    }
  }

  // Top right corner.
  if (type == FRAME_MASK ||
      (data->drawn_borders & (BORDER_TOP | BORDER_RIGHT))) {
    if (data->rounded_edges & ROUNDED_TOP_RIGHT) {
      if (corner_size >= kMinRoundedBorderSize) {
        for (int x = 0; x <= corner_size; ++x) {
          int y = static_cast<int>(sqrt(static_cast<double>(
              (corner_size * corner_size) - (x * x))));
          if (x > 0) {
            points.push_back(MakeBidiGdkPoint(
                width - (corner_size - x) + x_off_l - 1,
                corner_size - y, width, ltr));
          }
          points.push_back(MakeBidiGdkPoint(
              width - (corner_size - x) + x_off_l,
              corner_size - y, width, ltr));
        }
      } else {
        points.push_back(MakeBidiGdkPoint(
            width - corner_size + 1 + x_off_l, 0, width, ltr));
        points.push_back(MakeBidiGdkPoint(
            width + x_off_l, corner_size - 1, width, ltr));
      }
    } else {
      points.push_back(MakeBidiGdkPoint(
          width + x_off_l, 0, width, ltr));
    }
  }

  // Bottom right corner.
  if (type == FRAME_MASK ||
      (data->drawn_borders & (BORDER_RIGHT | BORDER_BOTTOM))) {
    if (data->rounded_edges & ROUNDED_BOTTOM_RIGHT) {
      if (corner_size >= kMinRoundedBorderSize) {
        for (int x = corner_size; x >= 0; --x) {
          int y = static_cast<int>(sqrt(static_cast<double>(
              (corner_size * corner_size) - (x * x))));
          points.push_back(MakeBidiGdkPoint(
              width - (corner_size - x) + x_off_l,
              height - (corner_size - y) + y_off, width, ltr));
          if (x > 0) {
            points.push_back(MakeBidiGdkPoint(
                width - (corner_size - x) + x_off_l - 1,
                height - (corner_size - y) + y_off, width, ltr));
          }
        }
      } else {
        points.push_back(MakeBidiGdkPoint(
            width + x_off_l, height - corner_size, width, ltr));
        points.push_back(MakeBidiGdkPoint(
            width - corner_size + x_off_r, height + y_off, width, ltr));
      }
    } else {
      points.push_back(MakeBidiGdkPoint(
          width + x_off_l, height + y_off, width, ltr));
    }
  }

  return points;
}

// Set the window shape in needed, lets our owner do some drawing (if it wants
// to), and finally draw the border.
gboolean OnRoundedWindowExpose(GtkWidget* widget,
                               GdkEventExpose* event) {
  RoundedWindowData* data = static_cast<RoundedWindowData*>(
      g_object_get_data(G_OBJECT(widget), kRoundedData));

  GtkAllocation allocation;
  gtk_widget_get_allocation(widget, &allocation);

  if (data->expected_width != allocation.width ||
      data->expected_height != allocation.height) {
    data->expected_width = allocation.width;
    data->expected_height = allocation.height;

    // We need to update the shape of the status bubble whenever our GDK
    // window changes shape.
    std::vector<GdkPoint> mask_points = MakeFramePolygonPoints(
        data, FRAME_MASK);
    GdkRegion* mask_region = gdk_region_polygon(&mask_points[0],
                                                mask_points.size(),
                                                GDK_EVEN_ODD_RULE);
    gdk_window_shape_combine_region(gtk_widget_get_window(widget),
                                    mask_region, 0, 0);
    gdk_region_destroy(mask_region);
  }

  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);
  gdk_gc_set_clip_rectangle(gc, &event->area);
  gdk_gc_set_rgb_fg_color(gc, &data->border_color);

  // Stroke the frame border.
  std::vector<GdkPoint> points = MakeFramePolygonPoints(
      data, FRAME_STROKE);
  if (data->drawn_borders == BORDER_ALL) {
    // If we want to have borders everywhere, we need to draw a polygon instead
    // of a set of lines.
    gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size());
  } else if (!points.empty()) {
    gdk_draw_lines(drawable, gc, &points[0], points.size());
  }

  g_object_unref(gc);
  return FALSE;  // Propagate so our children paint, etc.
}

// On theme changes, window shapes are reset, but we detect whether we need to
// reshape a window by whether its allocation has changed so force it to reset
// the window shape on next expose.
void OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) {
  DCHECK(widget);
  RoundedWindowData* data = static_cast<RoundedWindowData*>(
      g_object_get_data(G_OBJECT(widget), kRoundedData));
  DCHECK(data);
  data->expected_width = -1;
  data->expected_height = -1;
}

}  // namespace

void ActAsRoundedWindow(
    GtkWidget* widget, const GdkColor& color, int corner_size,
    int rounded_edges, int drawn_borders) {
  DCHECK(widget);
  DCHECK(!g_object_get_data(G_OBJECT(widget), kRoundedData));

  gtk_widget_set_app_paintable(widget, TRUE);

  RoundedWindowData* data = new RoundedWindowData;
  data->signals.Connect(widget, "expose-event",
                        G_CALLBACK(OnRoundedWindowExpose), NULL);
  data->signals.Connect(widget, "style-set", G_CALLBACK(OnStyleSet), NULL);

  data->expected_width = -1;
  data->expected_height = -1;

  data->border_color = color;
  data->corner_size = corner_size;

  data->rounded_edges = rounded_edges;
  data->drawn_borders = drawn_borders;

  g_object_set_data_full(G_OBJECT(widget), kRoundedData,
                         data, FreeRoundedWindowData);

  if (gtk_widget_get_visible(widget))
    gtk_widget_queue_draw(widget);
}

void StopActingAsRoundedWindow(GtkWidget* widget) {
  g_object_set_data(G_OBJECT(widget), kRoundedData, NULL);

  if (gtk_widget_get_realized(widget))
    gdk_window_shape_combine_mask(gtk_widget_get_window(widget), NULL, 0, 0);

  if (gtk_widget_get_visible(widget))
    gtk_widget_queue_draw(widget);
}

bool IsActingAsRoundedWindow(GtkWidget* widget) {
  return g_object_get_data(G_OBJECT(widget), kRoundedData) != NULL;
}

void SetRoundedWindowEdgesAndBorders(GtkWidget* widget,
                                     int corner_size,
                                     int rounded_edges,
                                     int drawn_borders) {
  DCHECK(widget);
  RoundedWindowData* data = static_cast<RoundedWindowData*>(
      g_object_get_data(G_OBJECT(widget), kRoundedData));
  DCHECK(data);
  data->corner_size = corner_size;
  data->rounded_edges = rounded_edges;
  data->drawn_borders = drawn_borders;
}

void SetRoundedWindowBorderColor(GtkWidget* widget, GdkColor color) {
  DCHECK(widget);
  RoundedWindowData* data = static_cast<RoundedWindowData*>(
      g_object_get_data(G_OBJECT(widget), kRoundedData));
  DCHECK(data);
  data->border_color = color;
}

}  // namespace gtk_util
