// 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 <gtk/gtk.h>

#include <memory>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/numerics/math_constants.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "remoting/base/string_resources.h"
#include "remoting/host/client_session_control.h"
#include "remoting/host/host_window.h"
#include "ui/base/glib/glib_signal.h"
#include "ui/base/l10n/l10n_util.h"

namespace remoting {

namespace {

class DisconnectWindowGtk : public HostWindow {
 public:
  DisconnectWindowGtk();
  ~DisconnectWindowGtk() override;

  // HostWindow overrides.
  void Start(const base::WeakPtr<ClientSessionControl>& client_session_control)
      override;

 private:
  CHROMEG_CALLBACK_1(DisconnectWindowGtk,
                     gboolean,
                     OnDelete,
                     GtkWidget*,
                     GdkEvent*);
  CHROMEG_CALLBACK_0(DisconnectWindowGtk, void, OnClicked, GtkButton*);
  CHROMEG_CALLBACK_1(DisconnectWindowGtk,
                     gboolean,
                     OnConfigure,
                     GtkWidget*,
                     GdkEventConfigure*);
  CHROMEG_CALLBACK_1(DisconnectWindowGtk,
                     gboolean,
                     OnDraw,
                     GtkWidget*,
                     cairo_t*);
  CHROMEG_CALLBACK_1(DisconnectWindowGtk,
                     gboolean,
                     OnButtonPress,
                     GtkWidget*,
                     GdkEventButton*);

  // Used to disconnect the client session.
  base::WeakPtr<ClientSessionControl> client_session_control_;

  GtkWidget* disconnect_window_;
  GtkWidget* message_;
  GtkWidget* button_;

  // Used to distinguish resize events from other types of "configure-event"
  // notifications.
  int current_width_;
  int current_height_;

  DISALLOW_COPY_AND_ASSIGN(DisconnectWindowGtk);
};

// Helper function for creating a rectangular path with rounded corners, as
// Cairo doesn't have this facility.  |radius| is the arc-radius of each
// corner.  The bounding rectangle extends from (0, 0) to (width, height).
void AddRoundRectPath(cairo_t* cairo_context, int width, int height,
                      int radius) {
  cairo_new_sub_path(cairo_context);
  cairo_arc(cairo_context, width - radius, radius, radius, -base::kPiDouble / 2,
            0);
  cairo_arc(cairo_context, width - radius, height - radius, radius, 0,
            base::kPiDouble / 2);
  cairo_arc(cairo_context, radius, height - radius, radius, base::kPiDouble / 2,
            base::kPiDouble);
  cairo_arc(cairo_context, radius, radius, radius, base::kPiDouble,
            3 * base::kPiDouble / 2);
  cairo_close_path(cairo_context);
}

// Renders the disconnect window background.
void DrawBackground(cairo_t* cairo_context, int width, int height) {
  // Set the arc radius for the corners.
  const int kCornerRadius = 6;

  // Initialize the whole bitmap to be transparent.
  cairo_save(cairo_context);
  cairo_set_source_rgba(cairo_context, 0, 0, 0, 0);
  cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
  cairo_paint(cairo_context);
  cairo_restore(cairo_context);

  AddRoundRectPath(cairo_context, width, height, kCornerRadius);
  cairo_clip(cairo_context);

  // Paint the whole bitmap one color.
  cairo_set_source_rgb(cairo_context, 0.91, 0.91, 0.91);
  cairo_paint(cairo_context);

  // Paint the round-rectangle edge.
  cairo_set_source_rgb(cairo_context, 0.13, 0.69, 0.11);
  cairo_set_line_width(cairo_context, 6);
  AddRoundRectPath(cairo_context, width, height, kCornerRadius);
  cairo_stroke(cairo_context);

  // Render the window-gripper.  In order for a straight line to light up
  // single pixels, Cairo requires the coordinates to have fractional
  // components of 0.5 (so the "/ 2" is a deliberate integer division).
  double gripper_top = height / 2 - 10.5;
  double gripper_bottom = height / 2 + 10.5;
  cairo_set_line_width(cairo_context, 1);

  double x = 12.5;
  cairo_set_source_rgb(cairo_context, 0.70, 0.70, 0.70);
  cairo_move_to(cairo_context, x, gripper_top);
  cairo_line_to(cairo_context, x, gripper_bottom);
  cairo_stroke(cairo_context);
  x += 3;
  cairo_move_to(cairo_context, x, gripper_top);
  cairo_line_to(cairo_context, x, gripper_bottom);
  cairo_stroke(cairo_context);

  x -= 2;
  cairo_set_source_rgb(cairo_context, 0.97, 0.97, 0.97);
  cairo_move_to(cairo_context, x, gripper_top);
  cairo_line_to(cairo_context, x, gripper_bottom);
  cairo_stroke(cairo_context);
  x += 3;
  cairo_move_to(cairo_context, x, gripper_top);
  cairo_line_to(cairo_context, x, gripper_bottom);
  cairo_stroke(cairo_context);
}

DisconnectWindowGtk::DisconnectWindowGtk()
    : disconnect_window_(nullptr),
      current_width_(0),
      current_height_(0) {
}

DisconnectWindowGtk::~DisconnectWindowGtk() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (disconnect_window_) {
    gtk_widget_destroy(disconnect_window_);
    disconnect_window_ = nullptr;
  }
}

void DisconnectWindowGtk::Start(
    const base::WeakPtr<ClientSessionControl>& client_session_control) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!client_session_control_.get());
  DCHECK(client_session_control.get());
  DCHECK(!disconnect_window_);

  client_session_control_ = client_session_control;

  // Create the window.
  disconnect_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  GtkWindow* window = GTK_WINDOW(disconnect_window_);

  g_signal_connect(disconnect_window_, "delete-event",
                   G_CALLBACK(OnDeleteThunk), this);
  gtk_window_set_title(window,
                       l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str());
  gtk_window_set_resizable(window, FALSE);

  // Try to keep the window always visible.
  gtk_window_stick(window);
  gtk_window_set_keep_above(window, TRUE);

  // Remove window titlebar.
  gtk_window_set_decorated(window, FALSE);

  // In case the titlebar is still there, try to remove some of the buttons.
  // Utility windows have no minimize button or taskbar presence.
  gtk_window_set_type_hint(window, GDK_WINDOW_TYPE_HINT_UTILITY);
  gtk_window_set_deletable(window, FALSE);

  // Allow custom rendering of the background pixmap.
  gtk_widget_set_app_paintable(disconnect_window_, TRUE);
  g_signal_connect(disconnect_window_, "draw", G_CALLBACK(OnDrawThunk), this);

  // Handle window resizing, to regenerate the background pixmap and window
  // shape bitmap.  The stored width & height need to be initialized here
  // in case the window is created a second time (the size of the previous
  // window would be remembered, preventing the generation of bitmaps for the
  // new window).
  current_height_ = current_width_ = 0;
  g_signal_connect(disconnect_window_, "configure-event",
                   G_CALLBACK(OnConfigureThunk), this);

  // Handle mouse events to allow the user to drag the window around.
  gtk_widget_set_events(disconnect_window_, GDK_BUTTON_PRESS_MASK);
  g_signal_connect(disconnect_window_, "button-press-event",
                   G_CALLBACK(OnButtonPressThunk), this);

  // All magic numbers taken from screen shots provided by UX.
  // The alignment sets narrow margins at the top and bottom, compared with
  // left and right.  The left margin is made larger to accommodate the
  // window movement gripper.
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
  GtkWidget* align = gtk_alignment_new(0, 0, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(align), 8, 8, 24, 12);
  G_GNUC_END_IGNORE_DEPRECATIONS;
  gtk_container_add(GTK_CONTAINER(window), align);

#if GTK_MAJOR_VERSION == 2
  GtkWidget* button_row = gtk_hbox_new(FALSE, 12);
#else
  GtkWidget* button_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
  gtk_box_set_homogeneous(GTK_BOX(button_row), FALSE);
#endif
  gtk_container_add(GTK_CONTAINER(align), button_row);

  button_ = gtk_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_STOP_SHARING_BUTTON).c_str());
  gtk_box_pack_end(GTK_BOX(button_row), button_, FALSE, FALSE, 0);

  g_signal_connect(button_, "clicked", G_CALLBACK(OnClickedThunk), this);

  message_ = gtk_label_new(nullptr);
  gtk_box_pack_end(GTK_BOX(button_row), message_, FALSE, FALSE, 0);

  // Override any theme setting for the text color, so that the text is
  // readable against the window's background pixmap.
  PangoAttrList* attributes = pango_attr_list_new();
  PangoAttribute* text_color = pango_attr_foreground_new(0, 0, 0);
  pango_attr_list_insert(attributes, text_color);
  gtk_label_set_attributes(GTK_LABEL(message_), attributes);
  pango_attr_list_unref(attributes);

#if GTK_MAJOR_VERSION > 2
  GdkScreen* screen = gtk_widget_get_screen(disconnect_window_);
  GdkVisual* visual = gdk_screen_get_rgba_visual(screen);

  if (visual)
    gtk_widget_set_visual(disconnect_window_, visual);
#endif

  gtk_widget_show_all(disconnect_window_);

  // Extract the user name from the JID.
  std::string client_jid = client_session_control_->client_jid();
  base::string16 username =
      base::UTF8ToUTF16(client_jid.substr(0, client_jid.find('/')));
  gtk_label_set_text(
      GTK_LABEL(message_),
      l10n_util::GetStringFUTF8(IDS_MESSAGE_SHARED, username).c_str());
  gtk_window_present(window);
}

void DisconnectWindowGtk::OnClicked(GtkButton* button) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (client_session_control_.get())
    client_session_control_->DisconnectSession(protocol::OK);
}

gboolean DisconnectWindowGtk::OnDelete(GtkWidget* window,
                                       GdkEvent* event) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (client_session_control_.get())
    client_session_control_->DisconnectSession(protocol::OK);
  return TRUE;
}

gboolean DisconnectWindowGtk::OnConfigure(GtkWidget* widget,
                                          GdkEventConfigure* event) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Only generate bitmaps if the size has actually changed.
  if (event->width == current_width_ && event->height == current_height_)
    return FALSE;

  current_width_ = event->width;
  current_height_ = event->height;

  // gdk_window_set_back_pixmap() is not supported in GDK3, and
  // background drawing is handled in OnDraw().
#if GTK_MAJOR_VERSION == 2
  // Create the depth 1 pixmap for the window shape.
  GdkPixmap* shape_mask =
      gdk_pixmap_new(nullptr, current_width_, current_height_, 1);
  cairo_t* cairo_context = gdk_cairo_create(shape_mask);

  // Set the arc radius for the corners.
  const int kCornerRadius = 6;

  // Initialize the whole bitmap to be transparent.
  cairo_set_source_rgba(cairo_context, 0, 0, 0, 0);
  cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
  cairo_paint(cairo_context);

  // Paint an opaque round rect covering the whole area (leaving the extreme
  // corners transparent).
  cairo_set_source_rgba(cairo_context, 1, 1, 1, 1);
  cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
  AddRoundRectPath(cairo_context, current_width_, current_height_,
                   kCornerRadius);
  cairo_fill(cairo_context);

  cairo_destroy(cairo_context);
  gdk_window_shape_combine_mask(widget->window, shape_mask, 0, 0);
  g_object_unref(shape_mask);

  // Create a full-color pixmap for the window background image.
  GdkPixmap* background =
      gdk_pixmap_new(nullptr, current_width_, current_height_, 24);
  cairo_context = gdk_cairo_create(background);
  DrawBackground(cairo_context, current_width_, current_height_);
  cairo_destroy(cairo_context);

  gdk_window_set_back_pixmap(widget->window, background, FALSE);
  g_object_unref(background);
  gdk_window_invalidate_rect(widget->window, nullptr, TRUE);
#endif  // GTK_MAJOR_VERSION == 2

  return FALSE;
}

gboolean DisconnectWindowGtk::OnDraw(GtkWidget* widget, cairo_t* cr) {
#if GTK_MAJOR_VERSION == 2
  NOTREACHED();
#endif
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  DrawBackground(cr, current_width_, current_height_);
  return FALSE;
}

gboolean DisconnectWindowGtk::OnButtonPress(GtkWidget* widget,
                                            GdkEventButton* event) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  gtk_window_begin_move_drag(GTK_WINDOW(disconnect_window_),
                             event->button,
                             event->x_root,
                             event->y_root,
                             event->time);
  return FALSE;
}

}  // namespace

// static
std::unique_ptr<HostWindow> HostWindow::CreateDisconnectWindow() {
  return std::make_unique<DisconnectWindowGtk>();
}

}  // namespace remoting
