// Copyright (c) 2013 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/protocol_dialog_gtk.h"

#include <gtk/gtk.h>

#include <string>

#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/ui/external_protocol_dialog_delegate.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

const int kMessageWidth = 400;

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// ExternalProtocolHandler

// static
void ExternalProtocolHandler::RunExternalProtocolDialog(
    const GURL& url, int render_process_host_id, int routing_id) {
  new ProtocolDialogGtk(scoped_ptr<const ProtocolDialogDelegate>(
        new ExternalProtocolDialogDelegate(url)));
}

///////////////////////////////////////////////////////////////////////////////
// ProtocolDialogGtk

ProtocolDialogGtk::ProtocolDialogGtk(
    scoped_ptr<const ProtocolDialogDelegate> delegate)
    : delegate_(delegate.Pass()),
      creation_time_(base::TimeTicks::Now()) {
  DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type());

  dialog_ = gtk_dialog_new_with_buttons(
      UTF16ToUTF8(delegate_->GetTitleText()).c_str(),
      NULL,
      GTK_DIALOG_NO_SEPARATOR,
      NULL);

  // Add the response buttons.
  gtk_util::AddButtonToDialog(dialog_,
      l10n_util::GetStringUTF8(
          IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT).c_str(),
      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
  gtk_util::AddButtonToDialog(dialog_,
      l10n_util::GetStringUTF8(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT).c_str(),
      GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);

  // Create the content-holding vbox.
  GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kControlSpacing);
  gtk_container_set_border_width(GTK_CONTAINER(vbox),
                                 ui::kContentAreaBorder);

  // Add the message text.
  GtkWidget* label = gtk_label_new(
      UTF16ToUTF8(delegate_->GetMessageText()).c_str());
  gtk_util::SetLabelWidth(label, kMessageWidth);
  gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);

  // Add the checkbox.
  checkbox_ = gtk_check_button_new_with_label(
      UTF16ToUTF8(delegate_->GetCheckboxText()).c_str());
  gtk_box_pack_start(GTK_BOX(vbox), checkbox_,
                     FALSE, FALSE, 0);

  // Add our vbox to the dialog.
  GtkWidget* content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog_));
  gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0);

  g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);

  gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
  gtk_widget_show_all(dialog_);
}

ProtocolDialogGtk::~ProtocolDialogGtk() {
}

void ProtocolDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
  bool checkbox = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox_));
  if (response_id == GTK_RESPONSE_ACCEPT) {
    delegate_->DoAccept(delegate_->url(), checkbox);
    UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
                             base::TimeTicks::Now() - creation_time_);
  } else if (response_id == GTK_RESPONSE_REJECT) {
    delegate_->DoCancel(delegate_->url(), checkbox);
  }
  // If the response is GTK_RESPONSE_DELETE, triggered by the user closing
  // the dialog, do nothing.

  gtk_widget_destroy(dialog_);
  delete this;
}
