// 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/browser_titlebar.h"

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

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/memory/singleton.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/avatar_menu.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/gtk/accelerators_gtk.h"
#include "chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h"
#include "chrome/browser/ui/gtk/avatar_menu_button_gtk.h"
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#include "chrome/browser/ui/gtk/custom_button.h"
#if defined(USE_GCONF)
#include "chrome/browser/ui/gtk/gconf_titlebar_listener.h"
#endif
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/menu_gtk.h"
#include "chrome/browser/ui/gtk/nine_box.h"
#include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/ui/gtk/unity_service.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/x/active_window_watcher_x.h"
#include "ui/gfx/image/image.h"

using content::WebContents;

namespace {

// The space above the titlebars.
const int kTitlebarHeight = 14;

// The thickness in pixels of the tab border.
const int kTabOuterThickness = 1;

// Amount to offset the tab images relative to the background.
const int kNormalVerticalOffset = kTitlebarHeight + kTabOuterThickness;

// A linux specific menu item for toggling window decorations.
const int kShowWindowDecorationsCommand = 200;

const int kAvatarBottomSpacing = 1;
// There are 2 px on each side of the avatar (between the frame border and
// it on the left, and between it and the tabstrip on the right).
const int kAvatarSideSpacing = 2;

// There is a 4px gap between the icon and the title text.
const int kIconTitleSpacing = 4;

// Padding around the icon when in app mode or popup mode.
const int kAppModePaddingTop = 5;
const int kAppModePaddingBottom = 4;
const int kAppModePaddingLeft = 2;

// The left padding of the tab strip.  In Views, the tab strip has a left
// margin of FrameBorderThickness + kClientEdgeThickness.  This offset is to
// account for kClientEdgeThickness.
const int kTabStripLeftPadding = 1;

// Spacing between buttons of the titlebar.
const int kButtonSpacing = 2;

// Spacing around outside of titlebar buttons.
const int kButtonOuterPadding = 2;

// Spacing between tabstrip and window control buttons (when the window is
// maximized).
const int kMaximizedTabstripPadding = 16;

gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event,
                          BrowserWindowGtk* browser_window) {
  // Reset to the default mouse cursor.
  browser_window->ResetCustomFrameCursor();
  return TRUE;
}

// Converts a GdkColor to a color_utils::HSL.
color_utils::HSL GdkColorToHSL(const GdkColor* color) {
  color_utils::HSL hsl;
  color_utils::SkColorToHSL(SkColorSetRGB(color->red >> 8,
                                          color->green >> 8,
                                          color->blue >> 8), &hsl);
  return hsl;
}

// Returns either |one| or |two| based on which has a greater difference in
// luminosity.
GdkColor PickLuminosityContrastingColor(const GdkColor* base,
                                        const GdkColor* one,
                                        const GdkColor* two) {
  // Convert all GdkColors to color_utils::HSLs.
  color_utils::HSL baseHSL = GdkColorToHSL(base);
  color_utils::HSL oneHSL = GdkColorToHSL(one);
  color_utils::HSL twoHSL = GdkColorToHSL(two);
  double one_difference = fabs(baseHSL.l - oneHSL.l);
  double two_difference = fabs(baseHSL.l - twoHSL.l);

  // Be biased towards the first color presented.
  if (two_difference > one_difference + 0.1)
    return *two;
  else
    return *one;
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// PopupPageMenuModel

// A menu model that builds the contents of the menu shown for popups (when the
// user clicks on the favicon) and all of its submenus.
class PopupPageMenuModel : public ui::SimpleMenuModel {
 public:
  PopupPageMenuModel(ui::SimpleMenuModel::Delegate* delegate, Browser* browser);
  virtual ~PopupPageMenuModel() { }

 private:
  void Build();

  // Models for submenus referenced by this model. SimpleMenuModel only uses
  // weak references so these must be kept for the lifetime of the top-level
  // model.
  scoped_ptr<ZoomMenuModel> zoom_menu_model_;
  scoped_ptr<EncodingMenuModel> encoding_menu_model_;
  Browser* browser_;  // weak

  DISALLOW_COPY_AND_ASSIGN(PopupPageMenuModel);
};

PopupPageMenuModel::PopupPageMenuModel(
    ui::SimpleMenuModel::Delegate* delegate,
    Browser* browser)
    : ui::SimpleMenuModel(delegate), browser_(browser) {
  Build();
}

void PopupPageMenuModel::Build() {
  AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
  AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
  AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
  AddSeparator(ui::NORMAL_SEPARATOR);
  AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB);
  AddSeparator(ui::NORMAL_SEPARATOR);
  AddItemWithStringId(IDC_CUT, IDS_CUT);
  AddItemWithStringId(IDC_COPY, IDS_COPY);
  AddItemWithStringId(IDC_PASTE, IDS_PASTE);
  AddSeparator(ui::NORMAL_SEPARATOR);
  AddItemWithStringId(IDC_FIND, IDS_FIND);
  AddItemWithStringId(IDC_PRINT, IDS_PRINT);
  zoom_menu_model_.reset(new ZoomMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, zoom_menu_model_.get());

  encoding_menu_model_.reset(new EncodingMenuModel(browser_));
  AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
                         encoding_menu_model_.get());

  AddSeparator(ui::NORMAL_SEPARATOR);
  AddItemWithStringId(IDC_CLOSE_WINDOW, IDS_CLOSE);
}

////////////////////////////////////////////////////////////////////////////////
// BrowserTitlebar

// static
const char BrowserTitlebar::kDefaultButtonString[] = ":minimize,maximize,close";

BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
                                 GtkWindow* window)
    : browser_window_(browser_window),
      window_(window),
      container_(NULL),
      container_hbox_(NULL),
      titlebar_left_buttons_vbox_(NULL),
      titlebar_right_buttons_vbox_(NULL),
      titlebar_left_buttons_hbox_(NULL),
      titlebar_right_buttons_hbox_(NULL),
      titlebar_left_avatar_frame_(NULL),
      titlebar_right_avatar_frame_(NULL),
      titlebar_left_label_frame_(NULL),
      titlebar_right_label_frame_(NULL),
      avatar_(NULL),
      avatar_label_(NULL),
      avatar_label_bg_(NULL),
      top_padding_left_(NULL),
      top_padding_right_(NULL),
      titlebar_alignment_(NULL),
      app_mode_favicon_(NULL),
      app_mode_title_(NULL),
      using_custom_frame_(false),
      window_has_focus_(false),
      display_avatar_on_left_(false),
      theme_service_(NULL) {
}

void BrowserTitlebar::Init() {
  // The widget hierarchy is shown below.
  //
  // +- EventBox (container_) ------------------------------------------------+
  // +- HBox (container_hbox_) -----------------------------------------------+
  // |+ VBox ---++- Algn. -++- Alignment --------------++- Algn. -++ VBox ---+|
  // || titlebar||titlebar ||   (titlebar_alignment_)  ||titlebar || titlebar||
  // || left    ||left     ||                          ||right    || right   ||
  // || button  ||spy      ||                          ||spy      || button  ||
  // || vbox    ||frame    ||+- TabStripGtk  ---------+||frame    || vbox    ||
  // ||         ||         || tab   tab   tabclose    |||         ||         ||
  // ||         ||         ||+------------------------+||         ||         ||
  // |+---------++---------++--------------------------++---------++---------+|
  // +------------------------------------------------------------------------+
  //
  // There are two vboxes on either side of |container_hbox_| because when the
  // desktop is GNOME, the button placement is configurable based on a metacity
  // gconf key. We can't just have one vbox and move it back and forth because
  // the gconf language allows you to place buttons on both sides of the
  // window.  This being Linux, I'm sure there's a bunch of people who have
  // already configured their window manager to do so and we don't want to get
  // confused when that happens. The actual contents of these vboxes are lazily
  // generated so they don't interfere with alignment when everything is
  // stuffed in the other box.
  //
  // Each vbox has the following hierarchy if it contains buttons:
  //
  // +- VBox (titlebar_{l,r}_buttons_vbox_) ---------+
  // |+- Fixed (top_padding_{l,r}_) ----------------+|
  // ||+- HBox (titlebar_{l,r}_buttons_hbox_ ------+||
  // ||| (buttons of a configurable layout)        |||
  // ||+-------------------------------------------+||
  // |+---------------------------------------------+|
  // +-----------------------------------------------+
  //
  // The two spy alignments are only allocated if this window is an incognito
  // window. Only one of them holds the spy image.
  //
  // If we're a popup window or in app mode, we don't display the spy guy or
  // the tab strip.  Instead, put an hbox in titlebar_alignment_ in place of
  // the tab strip.
  // +- Alignment (titlebar_alignment_) -----------------------------------+
  // |+ HBox -------------------------------------------------------------+|
  // ||+- TabStripGtk -++- Image ----------------++- Label --------------+||
  // ||| hidden        ++    (app_mode_favicon_) ||    (app_mode_title_) |||
  // |||               ||  favicon               ||  page title          |||
  // ||+---------------++------------------------++----------------------+||
  // |+-------------------------------------------------------------------+|
  // +---------------------------------------------------------------------+
  container_hbox_ = gtk_hbox_new(FALSE, 0);

  container_ = gtk_event_box_new();
  gtk_widget_set_name(container_, "chrome-browser-titlebar");
  gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE);
  gtk_container_add(GTK_CONTAINER(container_), container_hbox_);

  g_signal_connect(container_, "scroll-event", G_CALLBACK(OnScrollThunk), this);

  g_signal_connect(window_, "window-state-event",
                   G_CALLBACK(OnWindowStateChangedThunk), this);

  // Allocate the two button boxes on the left and right parts of the bar. These
  // are always allocated, but only displayed in incognito mode or when using
  // multiple profiles.
  titlebar_left_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_left_buttons_vbox_,
                     FALSE, FALSE, 0);
  titlebar_left_avatar_frame_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_widget_set_no_show_all(titlebar_left_avatar_frame_, TRUE);
  gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_left_avatar_frame_), 0,
      kAvatarBottomSpacing, kAvatarSideSpacing, kAvatarSideSpacing);
  gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_left_avatar_frame_,
                     FALSE, FALSE, 0);

  titlebar_left_label_frame_ = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
  gtk_widget_set_no_show_all(titlebar_left_label_frame_, TRUE);
  gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_left_label_frame_), 0,
      kAvatarBottomSpacing, kAvatarSideSpacing, kAvatarSideSpacing);
  gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_left_label_frame_,
                   FALSE, FALSE, 0);

  titlebar_right_avatar_frame_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_widget_set_no_show_all(titlebar_right_avatar_frame_, TRUE);
  gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_right_avatar_frame_), 0,
      kAvatarBottomSpacing, kAvatarSideSpacing, kAvatarSideSpacing);
  gtk_box_pack_end(GTK_BOX(container_hbox_), titlebar_right_avatar_frame_,
                   FALSE, FALSE, 0);

  titlebar_right_label_frame_ = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
  gtk_widget_set_no_show_all(titlebar_right_label_frame_, TRUE);
  gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_right_label_frame_), 0,
      kAvatarBottomSpacing, kAvatarSideSpacing, kAvatarSideSpacing);
  gtk_box_pack_end(GTK_BOX(container_hbox_), titlebar_right_label_frame_,
                   FALSE, FALSE, 0);

  titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_end(GTK_BOX(container_hbox_), titlebar_right_buttons_vbox_,
                   FALSE, FALSE, 0);

  // Create the Avatar button and listen for notifications. It must always be
  // created because a new profile can be added at any time.
  avatar_button_.reset(new AvatarMenuButtonGtk(browser_window_->browser()));

  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
                 content::NotificationService::AllSources());

#if defined(USE_GCONF)
  // Either read the gconf database and register for updates (on GNOME), or use
  // the default value (anywhere else).
  GConfTitlebarListener::GetInstance()->SetTitlebarButtons(this);
#else
  BuildButtons(kDefaultButtonString);
#endif

  UpdateAvatar();

  // We use an alignment to control the titlebar height.
  titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  if (browser_window_->browser()->is_type_tabbed()) {
    gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_alignment_, TRUE,
                       TRUE, 0);

    // Put the tab strip in the titlebar.
    gtk_container_add(GTK_CONTAINER(titlebar_alignment_),
                      browser_window_->tabstrip()->widget());
  } else {
    // App mode specific widgets.
    gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_alignment_, TRUE,
                       TRUE, 0);
    GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing);
    gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox);

    // Put the tab strip in the hbox even though we don't show it.  Sometimes
    // we need the position of the tab strip so make sure it's in our widget
    // hierarchy.
    gtk_box_pack_start(GTK_BOX(app_mode_hbox),
        browser_window_->tabstrip()->widget(), FALSE, FALSE, 0);

    GtkWidget* favicon_event_box = gtk_event_box_new();
    gtk_event_box_set_visible_window(GTK_EVENT_BOX(favicon_event_box), FALSE);
    g_signal_connect(favicon_event_box, "button-press-event",
                     G_CALLBACK(OnFaviconMenuButtonPressedThunk), this);
    gtk_box_pack_start(GTK_BOX(app_mode_hbox), favicon_event_box, FALSE,
                       FALSE, 0);
    // We use the app logo as a placeholder image so the title doesn't jump
    // around.
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    app_mode_favicon_ = gtk_image_new_from_pixbuf(rb.GetNativeImageNamed(
        IDR_PRODUCT_LOGO_16, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf());
    g_object_set_data(G_OBJECT(app_mode_favicon_), "left-align-popup",
                      reinterpret_cast<void*>(true));
    gtk_container_add(GTK_CONTAINER(favicon_event_box), app_mode_favicon_);

    app_mode_title_ = gtk_label_new(NULL);
    gtk_label_set_ellipsize(GTK_LABEL(app_mode_title_), PANGO_ELLIPSIZE_END);
    gtk_misc_set_alignment(GTK_MISC(app_mode_title_), 0.0, 0.5);
    gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_title_, TRUE, TRUE,
                       0);

    UpdateTitleAndIcon();
  }

  theme_service_ = GtkThemeService::GetFrom(
      browser_window_->browser()->profile());
  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
                 content::Source<ThemeService>(theme_service_));
  theme_service_->InitThemesFor(this);

  gtk_widget_show_all(container_);

  ui::ActiveWindowWatcherX::AddObserver(this);
}

BrowserTitlebar::~BrowserTitlebar() {
  ui::ActiveWindowWatcherX::RemoveObserver(this);
#if defined(USE_GCONF)
  GConfTitlebarListener::GetInstance()->RemoveObserver(this);
#endif
}

void BrowserTitlebar::BuildButtons(const std::string& button_string) {
  // Clear out all previous data.
  close_button_.reset();
  restore_button_.reset();
  maximize_button_.reset();
  minimize_button_.reset();
  gtk_util::RemoveAllChildren(titlebar_left_buttons_vbox_);
  gtk_util::RemoveAllChildren(titlebar_right_buttons_vbox_);
  titlebar_left_buttons_hbox_ = NULL;
  titlebar_right_buttons_hbox_ = NULL;
  top_padding_left_ = NULL;
  top_padding_right_ = NULL;

  bool left_side = true;
  base::StringTokenizer tokenizer(button_string, ":,");
  tokenizer.set_options(base::StringTokenizer::RETURN_DELIMS);
  int left_count = 0;
  int right_count = 0;
  while (tokenizer.GetNext()) {
    if (tokenizer.token_is_delim()) {
      if (*tokenizer.token_begin() == ':')
        left_side = false;
    } else {
      base::StringPiece token = tokenizer.token_piece();
      if (BuildButton(token.as_string(), left_side))
        (left_side ? left_count : right_count)++;
    }
  }

  // If we are in incognito mode, add the spy guy to either the end of the left
  // or the beginning of the right depending on which side has fewer buttons.
  display_avatar_on_left_ = right_count > left_count;

  // Now show the correct widgets in the two hierarchies.
  if (using_custom_frame_) {
    gtk_widget_show_all(titlebar_left_buttons_vbox_);
    gtk_widget_show_all(titlebar_right_buttons_vbox_);
  }
  UpdateMaximizeRestoreVisibility();
}

bool BrowserTitlebar::BuildButton(const std::string& button_token,
                                  bool left_side) {
  if (button_token == "minimize") {
    minimize_button_.reset(CreateTitlebarButton("minimize", left_side));

    gtk_widget_size_request(minimize_button_->widget(),
                            &minimize_button_req_);
    return true;
  } else if (button_token == "maximize") {
    restore_button_.reset(CreateTitlebarButton("unmaximize", left_side));
    maximize_button_.reset(CreateTitlebarButton("maximize", left_side));

    gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
                                               true, true, true);
    gtk_widget_size_request(restore_button_->widget(),
                            &restore_button_req_);
    return true;
  } else if (button_token == "close") {
    close_button_.reset(CreateTitlebarButton("close", left_side));
    close_button_->set_flipped(left_side);

    gtk_widget_size_request(close_button_->widget(), &close_button_req_);
    return true;
  }
  // Ignore any other values like "pin" since we don't have images for
  // those.
  return false;
}

GtkWidget* BrowserTitlebar::GetButtonHBox(bool left_side) {
  if (left_side && titlebar_left_buttons_hbox_)
    return titlebar_left_buttons_hbox_;
  else if (!left_side && titlebar_right_buttons_hbox_)
    return titlebar_right_buttons_hbox_;

  // We put the min/max/restore/close buttons in a vbox so they are top aligned
  // (up to padding) and don't vertically stretch.
  GtkWidget* vbox = left_side ? titlebar_left_buttons_vbox_ :
                    titlebar_right_buttons_vbox_;

  GtkWidget* top_padding = gtk_fixed_new();
  gtk_widget_set_size_request(top_padding, -1, kButtonOuterPadding);
  gtk_box_pack_start(GTK_BOX(vbox), top_padding, FALSE, FALSE, 0);

  GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing);
  gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 0);

  if (left_side) {
    titlebar_left_buttons_hbox_ = buttons_hbox;
    top_padding_left_ = top_padding;
  } else {
    titlebar_right_buttons_hbox_ = buttons_hbox;
    top_padding_right_ = top_padding;
  }

  return buttons_hbox;
}

CustomDrawButton* BrowserTitlebar::CreateTitlebarButton(
    const std::string& button_name, bool left_side) {
  int normal_image_id;
  int pressed_image_id;
  int hover_image_id;
  int tooltip_id;
  GetButtonResources(button_name, &normal_image_id, &pressed_image_id,
                     &hover_image_id, &tooltip_id);

  CustomDrawButton* button = new CustomDrawButton(normal_image_id,
                                                  pressed_image_id,
                                                  hover_image_id,
                                                  0);
  gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
  g_signal_connect(button->widget(), "clicked",
                   G_CALLBACK(OnButtonClickedThunk), this);
  g_signal_connect(button->widget(), "motion-notify-event",
                   G_CALLBACK(OnMouseMoveEvent), browser_window_);

  std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip_id);
  gtk_widget_set_tooltip_text(button->widget(),
                              localized_tooltip.c_str());

  GtkWidget* box = GetButtonHBox(left_side);
  gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
  return button;
}

void BrowserTitlebar::GetButtonResources(const std::string& button_name,
                                         int* normal_image_id,
                                         int* pressed_image_id,
                                         int* hover_image_id,
                                         int* tooltip_id) const {
  if (button_name == "close") {
    *normal_image_id = IDR_CLOSE;
    *pressed_image_id = IDR_CLOSE_P;
    *hover_image_id = IDR_CLOSE_H;
    *tooltip_id = IDS_XPFRAME_CLOSE_TOOLTIP;
  } else if (button_name == "minimize") {
    *normal_image_id = IDR_MINIMIZE;
    *pressed_image_id = IDR_MINIMIZE_P;
    *hover_image_id = IDR_MINIMIZE_H;
    *tooltip_id = IDS_XPFRAME_MINIMIZE_TOOLTIP;
  } else if (button_name == "maximize") {
    *normal_image_id = IDR_MAXIMIZE;
    *pressed_image_id = IDR_MAXIMIZE_P;
    *hover_image_id = IDR_MAXIMIZE_H;
    *tooltip_id = IDS_XPFRAME_MAXIMIZE_TOOLTIP;
  } else if (button_name == "unmaximize") {
    *normal_image_id = IDR_RESTORE;
    *pressed_image_id = IDR_RESTORE_P;
    *hover_image_id = IDR_RESTORE_H;
    *tooltip_id = IDS_XPFRAME_RESTORE_TOOLTIP;
  }
}

void BrowserTitlebar::UpdateButtonBackground(CustomDrawButton* button) {
  SkColor color = theme_service_->GetColor(
      ThemeProperties::COLOR_BUTTON_BACKGROUND);
  SkBitmap background = theme_service_->GetImageNamed(
      IDR_THEME_WINDOW_CONTROL_BACKGROUND).AsBitmap();

  // TODO(erg): For now, we just use a completely black mask and we can get
  // away with this in the short term because our buttons are rectangles. We
  // should get Glen to make properly hinted masks that match our min/max/close
  // buttons (which have some odd alpha blending around the
  // edges). http://crbug.com/103661
  SkBitmap mask;
  mask.setConfig(SkBitmap::kARGB_8888_Config,
                 button->SurfaceWidth(), button->SurfaceHeight(), 0);
  mask.allocPixels();
  mask.eraseColor(SK_ColorBLACK);

  button->SetBackground(color, background, mask);
}

void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) {
  using_custom_frame_ = use_custom_frame;
  if (!use_custom_frame ||
      (browser_window_->IsMaximized() && unity::IsRunning())) {
    if (titlebar_left_buttons_vbox_)
      gtk_widget_hide(titlebar_left_buttons_vbox_);
    if (titlebar_right_buttons_vbox_)
      gtk_widget_hide(titlebar_right_buttons_vbox_);
  } else {
    if (titlebar_left_buttons_vbox_)
      gtk_widget_show_all(titlebar_left_buttons_vbox_);
    if (titlebar_right_buttons_vbox_)
      gtk_widget_show_all(titlebar_right_buttons_vbox_);
  }
  UpdateTitlebarAlignment();
  UpdateMaximizeRestoreVisibility();
}

void BrowserTitlebar::UpdateTitleAndIcon() {
  if (!app_mode_title_)
    return;

  // Get the page title and elide it to the available space.
  string16 title = browser_window_->browser()->GetWindowTitleForCurrentTab();
  gtk_label_set_text(GTK_LABEL(app_mode_title_), UTF16ToUTF8(title).c_str());

  if (browser_window_->browser()->is_app()) {
    switch (browser_window_->browser()->type()) {
      case Browser::TYPE_POPUP: {
        // Update the system app icon.  We don't need to update the icon in the
        // top left of the custom frame, that will get updated when the
        // throbber is updated.
        Profile* profile = browser_window_->browser()->profile();
        gfx::Image icon = browser_window_->browser()->GetCurrentPageIcon();
        if (icon.IsEmpty()) {
          gtk_util::SetWindowIcon(window_, profile);
        } else {
          gtk_util::SetWindowIcon(window_, profile, icon.ToGdkPixbuf());
        }
        break;
      }
      case Browser::TYPE_TABBED: {
        NOTREACHED() << "We should never have a tabbed app window.";
        break;
      }
    }
  }
}

void BrowserTitlebar::UpdateThrobber(WebContents* web_contents) {
  DCHECK(app_mode_favicon_);

  if (web_contents && web_contents->IsLoading()) {
    GdkPixbuf* icon_pixbuf =
        throbber_.GetNextFrame(web_contents->IsWaitingForResponse());
    gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf);
  } else {
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();

    // Note: we want to exclude the application popup/panel window.
    if ((browser_window_->browser()->is_app() &&
        !browser_window_->browser()->is_type_tabbed()) ||
        browser_window_->browser()->is_type_popup()) {
      gfx::Image icon = browser_window_->browser()->GetCurrentPageIcon();
      if (icon.IsEmpty()) {
        // Fallback to the Chromium icon if the page has no icon.
        gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
            rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
      } else {
        gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
                                  icon.ToGdkPixbuf());
      }
    } else {
      gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
          rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
    }
    throbber_.Reset();
  }
}

void BrowserTitlebar::UpdateTitlebarAlignment() {
  if (browser_window_->browser()->is_type_tabbed()) {
    int top_padding = 0;
    int side_padding = 0;
    int vertical_offset = kNormalVerticalOffset;

    if (using_custom_frame_) {
      if (!browser_window_->IsMaximized()) {
        top_padding = kTitlebarHeight;
      } else if (using_custom_frame_ && browser_window_->IsMaximized()) {
        vertical_offset = 0;
        if (!unity::IsRunning())
          side_padding = kMaximizedTabstripPadding;
      }
    }

    int right_padding = 0;
    int left_padding = kTabStripLeftPadding;
    if (titlebar_right_buttons_hbox_)
      right_padding = side_padding;
    if (titlebar_left_buttons_hbox_)
      left_padding = side_padding;

    gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
                              top_padding, 0,
                              left_padding, right_padding);
    browser_window_->tabstrip()->SetVerticalOffset(vertical_offset);
  } else {
    if (using_custom_frame_ && !browser_window_->IsFullscreen()) {
      gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
          kAppModePaddingTop, kAppModePaddingBottom, kAppModePaddingLeft, 0);
      gtk_widget_show(titlebar_alignment_);
    } else {
      gtk_widget_hide(titlebar_alignment_);
    }
  }

  // Resize the buttons so that the clickable area extends all the way to the
  // edge of the browser window.
  GtkRequisition close_button_req = close_button_req_;
  GtkRequisition minimize_button_req = minimize_button_req_;
  GtkRequisition restore_button_req = restore_button_req_;
  if (using_custom_frame_ && browser_window_->IsMaximized()) {
    close_button_req.width += kButtonOuterPadding;
    close_button_req.height += kButtonOuterPadding;
    minimize_button_req.height += kButtonOuterPadding;
    restore_button_req.height += kButtonOuterPadding;
    if (top_padding_left_)
      gtk_widget_hide(top_padding_left_);
    if (top_padding_right_)
      gtk_widget_hide(top_padding_right_);
  } else {
    if (top_padding_left_)
      gtk_widget_show(top_padding_left_);
    if (top_padding_right_)
      gtk_widget_show(top_padding_right_);
  }
  if (close_button_.get()) {
    gtk_widget_set_size_request(close_button_->widget(),
                                close_button_req.width,
                                close_button_req.height);
  }
  if (minimize_button_.get()) {
    gtk_widget_set_size_request(minimize_button_->widget(),
                                minimize_button_req.width,
                                minimize_button_req.height);
  }
  if (maximize_button_.get()) {
    gtk_widget_set_size_request(restore_button_->widget(),
                                restore_button_req.width,
                                restore_button_req.height);
  }
}

void BrowserTitlebar::UpdateTextColor() {
  if (!app_mode_title_)
    return;

  if (theme_service_ && theme_service_->UsingNativeTheme()) {
    // We don't really have any good options here.
    //
    // Colors from window manager themes aren't exposed in GTK; the window
    // manager is a separate component and when there is information sharing
    // (in the case of metacity), it's one way where the window manager reads
    // data from the GTK theme (which allows us to do a decent job with
    // picking the frame color).
    //
    // We probably won't match in the majority of cases, but we can at the
    // very least make things legible. The default metacity and xfwm themes
    // on ubuntu have white text hardcoded. Determine whether black or white
    // has more luminosity contrast and then set that color as the text
    // color.
    GdkColor frame_color;
    if (window_has_focus_) {
      frame_color = theme_service_->GetGdkColor(
          ThemeProperties::COLOR_FRAME);
    } else {
      frame_color = theme_service_->GetGdkColor(
          ThemeProperties::COLOR_FRAME_INACTIVE);
    }
    GdkColor text_color = PickLuminosityContrastingColor(
        &frame_color, &ui::kGdkWhite, &ui::kGdkBlack);
    gtk_util::SetLabelColor(app_mode_title_, &text_color);
  } else {
    gtk_util::SetLabelColor(app_mode_title_, &ui::kGdkWhite);
  }
}

void BrowserTitlebar::UpdateAvatarLabel() {
  if (theme_service_ && avatar_label_) {
    GdkColor text_color =
        theme_service_->GetGdkColor(ThemeProperties::COLOR_MANAGED_USER_LABEL);
    GdkColor label_background = theme_service_->GetGdkColor(
        ThemeProperties::COLOR_MANAGED_USER_LABEL_BACKGROUND);
    gtk_util::SetLabelColor(avatar_label_, &text_color);
    gtk_widget_modify_bg(
        GTK_WIDGET(avatar_label_bg_), GTK_STATE_NORMAL, &label_background);
    char* markup = g_markup_printf_escaped(
        "<span size='small'>%s</span>",
        l10n_util::GetStringUTF8(IDS_MANAGED_USER_AVATAR_LABEL).c_str());
    gtk_label_set_markup(GTK_LABEL(avatar_label_), markup);
    g_free(markup);
  }
}

void BrowserTitlebar::UpdateAvatar() {
  // Remove previous state.
  gtk_util::RemoveAllChildren(titlebar_left_avatar_frame_);
  gtk_util::RemoveAllChildren(titlebar_right_avatar_frame_);
  gtk_util::RemoveAllChildren(titlebar_left_label_frame_);
  gtk_util::RemoveAllChildren(titlebar_right_label_frame_);

  if (!ShouldDisplayAvatar())
    return;

  if (!avatar_) {
    if (IsOffTheRecord()) {
      ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
      gfx::Image avatar_image =
          rb.GetNativeImageNamed(IDR_OTR_ICON, ui::ResourceBundle::RTL_ENABLED);
      avatar_ = gtk_image_new_from_pixbuf(avatar_image.ToGdkPixbuf());
      gtk_misc_set_alignment(GTK_MISC(avatar_), 0.0, 1.0);
      gtk_widget_set_size_request(avatar_, -1, 0);
    } else {
      // Use a clickable avatar.
      avatar_ = avatar_button_->widget();
    }
  }

  gtk_widget_show_all(avatar_);

  Profile* profile = browser_window_->browser()->profile();
  if (profile->IsManaged()) {
    avatar_label_ = gtk_label_new(NULL);
    gtk_misc_set_padding(GTK_MISC(avatar_label_), 10, 2);
    avatar_label_bg_ = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(avatar_label_bg_), avatar_label_);
    g_signal_connect(avatar_label_bg_, "button-press-event",
                     G_CALLBACK(OnAvatarLabelButtonPressedThunk), this);
    UpdateAvatarLabel();
    gtk_widget_show(avatar_label_bg_);
    gtk_widget_show(avatar_label_);
    if (display_avatar_on_left_) {
      gtk_container_add(GTK_CONTAINER(titlebar_left_label_frame_),
                        avatar_label_bg_);
      gtk_widget_show(titlebar_left_label_frame_);
      gtk_widget_hide(titlebar_right_label_frame_);
    } else {
      gtk_container_add(GTK_CONTAINER(titlebar_right_label_frame_),
                        avatar_label_bg_);
      gtk_widget_show(titlebar_right_label_frame_);
      gtk_widget_hide(titlebar_left_label_frame_);
    }
  }

  if (display_avatar_on_left_) {
    gtk_container_add(GTK_CONTAINER(titlebar_left_avatar_frame_), avatar_);
    gtk_widget_show(titlebar_left_avatar_frame_);
    gtk_widget_hide(titlebar_right_avatar_frame_);
  } else {
    gtk_container_add(GTK_CONTAINER(titlebar_right_avatar_frame_), avatar_);
    gtk_widget_show(titlebar_right_avatar_frame_);
    gtk_widget_hide(titlebar_left_avatar_frame_);
  }

  if (IsOffTheRecord())
    return;

  bool is_gaia_picture = false;
  gfx::Image avatar;
  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath());
  if (index == std::string::npos)
    return;

  is_gaia_picture =
      cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
      cache.GetGAIAPictureOfProfileAtIndex(index);
  avatar = cache.GetAvatarIconOfProfileAtIndex(index);
  avatar_button_->SetIcon(avatar, is_gaia_picture);
  avatar_button_->set_menu_frame_style(display_avatar_on_left_ ?
      BubbleGtk::ANCHOR_TOP_LEFT : BubbleGtk::ANCHOR_TOP_RIGHT);
}

void BrowserTitlebar::MaximizeButtonClicked() {
  GdkEvent* event = gtk_get_current_event();
  if (event->button.button == 1) {
    gtk_window_maximize(window_);
  } else {
    GtkWidget* widget = GTK_WIDGET(window_);
    GdkScreen* screen = gtk_widget_get_screen(widget);
    gint monitor = gdk_screen_get_monitor_at_window(
        screen, gtk_widget_get_window(widget));
    GdkRectangle screen_rect;
    gdk_screen_get_monitor_geometry(screen, monitor, &screen_rect);

    gint x, y;
    gtk_window_get_position(window_, &x, &y);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);
    gint width = allocation.width;
    gint height = allocation.height;

    if (event->button.button == 3) {
      x = 0;
      width = screen_rect.width;
    } else if (event->button.button == 2) {
      y = 0;
      height = screen_rect.height;
    }

    browser_window_->SetBounds(gfx::Rect(x, y, width, height));
  }
  gdk_event_free(event);
}

void BrowserTitlebar::UpdateMaximizeRestoreVisibility() {
  if (maximize_button_.get()) {
    if (browser_window_->IsMaximized()) {
      gtk_widget_hide(maximize_button_->widget());
      gtk_widget_show(restore_button_->widget());
    } else {
      gtk_widget_hide(restore_button_->widget());
      gtk_widget_show(maximize_button_->widget());
    }
  }
}

gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
                                               GdkEventWindowState* event) {
  UpdateMaximizeRestoreVisibility();
  UpdateTitlebarAlignment();
  UpdateTextColor();
  return FALSE;
}

gboolean BrowserTitlebar::OnScroll(GtkWidget* widget, GdkEventScroll* event) {
  Browser* browser = browser_window_->browser();
  int index = browser->tab_strip_model()->active_index();
  if (event->direction == GDK_SCROLL_LEFT ||
      event->direction == GDK_SCROLL_UP) {
    if (index != 0)
      chrome::SelectPreviousTab(browser);
  } else if (index + 1 < browser->tab_strip_model()->count()) {
    chrome::SelectNextTab(browser);
  }
  return TRUE;
}

void BrowserTitlebar::OnButtonClicked(GtkWidget* button) {
  if (close_button_.get() && close_button_->widget() == button) {
    browser_window_->Close();
  } else if (restore_button_.get() && restore_button_->widget() == button) {
    browser_window_->UnMaximize();
  } else if (maximize_button_.get() && maximize_button_->widget() == button) {
    MaximizeButtonClicked();
  } else if (minimize_button_.get() && minimize_button_->widget() == button) {
    gtk_window_iconify(window_);
  }
}

gboolean BrowserTitlebar::OnFaviconMenuButtonPressed(GtkWidget* widget,
                                                     GdkEventButton* event) {
  if (event->button != 1)
    return FALSE;

  if (!favicon_menu_model_.get()) {
    favicon_menu_model_.reset(
        new PopupPageMenuModel(this, browser_window_->browser()));

    favicon_menu_.reset(new MenuGtk(NULL, favicon_menu_model_.get()));
  }

  favicon_menu_->PopupForWidget(app_mode_favicon_, event->button, event->time);

  return TRUE;
}

gboolean BrowserTitlebar::OnAvatarLabelButtonPressed(GtkWidget* widget,
                                                     GdkEventButton* event) {
  if (event->button != 1)
    return FALSE;

  // Show the avatar menu bubble with the upward arrow at the x position where
  // the user has clicked.
  gfx::Rect rect = gtk_util::WidgetBounds(widget);
  rect.set_x(event->x);
  rect.set_width(0);
  new AvatarMenuBubbleGtk(
      browser_window_->browser(), widget, BubbleGtk::ANCHOR_TOP_RIGHT, &rect);
  return TRUE;
}

void BrowserTitlebar::ShowContextMenu(GdkEventButton* event) {
  if (!context_menu_.get()) {
    context_menu_model_.reset(new ContextMenuModel(this));
    context_menu_.reset(new MenuGtk(NULL, context_menu_model_.get()));
  }

  context_menu_->PopupAsContext(gfx::Point(event->x_root, event->y_root),
                                event->time);
}

bool BrowserTitlebar::IsCommandIdEnabled(int command_id) const {
  if (command_id == kShowWindowDecorationsCommand)
    return true;

  return chrome::IsCommandEnabled(browser_window_->browser(), command_id);
}

bool BrowserTitlebar::IsCommandIdChecked(int command_id) const {
  if (command_id == kShowWindowDecorationsCommand) {
    PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
    return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
  }

  EncodingMenuController controller;
  if (controller.DoesCommandBelongToEncodingMenu(command_id)) {
    WebContents* web_contents =
        browser_window_->browser()->tab_strip_model()->GetActiveWebContents();
    if (web_contents) {
      return controller.IsItemChecked(browser_window_->browser()->profile(),
                                      web_contents->GetEncoding(),
                                      command_id);
    }
    return false;
  }

  NOTREACHED();
  return false;
}

void BrowserTitlebar::ExecuteCommand(int command_id, int event_flags) {
  if (command_id == kShowWindowDecorationsCommand) {
    PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
    prefs->SetBoolean(prefs::kUseCustomChromeFrame,
                  !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
    return;
  }

  chrome::ExecuteCommand(browser_window_->browser(), command_id);
}

bool BrowserTitlebar::GetAcceleratorForCommandId(
    int command_id,
    ui::Accelerator* out_accelerator) {
  const ui::Accelerator* accelerator =
      AcceleratorsGtk::GetInstance()->GetPrimaryAcceleratorForCommand(
          command_id);
  if (!accelerator)
    return false;
  *out_accelerator = *accelerator;
  return true;
}

void BrowserTitlebar::Observe(int type,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: {
      UpdateTextColor();
      UpdateAvatarLabel();

      if (minimize_button_.get())
        UpdateButtonBackground(minimize_button_.get());
      if (maximize_button_.get())
        UpdateButtonBackground(maximize_button_.get());
      if (restore_button_.get())
        UpdateButtonBackground(restore_button_.get());
      if (close_button_.get())
        UpdateButtonBackground(close_button_.get());
      break;
    }

    case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED:
      if (!IsOffTheRecord())
        UpdateAvatar();
      break;

    default:
      NOTREACHED();
  }
}

void BrowserTitlebar::ActiveWindowChanged(GdkWindow* active_window) {
  // Can be called during shutdown; BrowserWindowGtk will set our |window_|
  // to NULL during that time.
  if (!window_)
    return;

  window_has_focus_ =
      gtk_widget_get_window(GTK_WIDGET(window_)) == active_window;
  UpdateTextColor();
}

bool BrowserTitlebar::ShouldDisplayAvatar() {
  if (IsOffTheRecord())
    return true;

  if (!browser_window_->browser()->is_type_tabbed())
    return false;

  return AvatarMenu::ShouldShowAvatarMenu();
}

bool BrowserTitlebar::IsOffTheRecord() {
  return browser_window_->browser()->profile()->IsOffTheRecord();
}

BrowserTitlebar::ContextMenuModel::ContextMenuModel(
    ui::SimpleMenuModel::Delegate* delegate)
    : SimpleMenuModel(delegate) {
  AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB);
  AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
  AddSeparator(ui::NORMAL_SEPARATOR);
  AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
  AddSeparator(ui::NORMAL_SEPARATOR);
  AddCheckItemWithStringId(kShowWindowDecorationsCommand,
                           IDS_SHOW_WINDOW_DECORATIONS_MENU);
}
