static const int kDefaultMessageWidth = 320;

namespace views {

///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, public:

MessageBoxView::MessageBoxView(int dialog_flags,
                               const std::wstring& message,
                               const std::wstring& default_prompt,
                               int message_width)
    : message_label_(new Label(message)),
      prompt_field_(NULL),
      icon_(NULL),
      checkbox_(NULL),
      message_width_(message_width),
      ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)) {
  Init(dialog_flags, default_prompt);
}

MessageBoxView::MessageBoxView(int dialog_flags,
                               const std::wstring& message,
                               const std::wstring& default_prompt)
    : message_label_(new Label(message)),
      prompt_field_(NULL),
      icon_(NULL),
      checkbox_(NULL),
      message_width_(kDefaultMessageWidth),
      ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)) {
  Init(dialog_flags, default_prompt);
}

MessageBoxView::~MessageBoxView() {}

std::wstring MessageBoxView::GetInputText() {
  if (prompt_field_)
    return UTF16ToWideHack(prompt_field_->text());
  return std::wstring();
}

bool MessageBoxView::IsCheckBoxSelected() {
  return checkbox_ ? checkbox_->checked() : false;
}

void MessageBoxView::SetIcon(const SkBitmap& icon) {
  if (!icon_)
    icon_ = new ImageView();
  icon_->SetImage(icon);
  icon_->SetBounds(0, 0, icon.width(), icon.height());
  ResetLayoutManager();
}

void MessageBoxView::SetCheckBoxLabel(const std::wstring& label) {
  if (!checkbox_)
    checkbox_ = new Checkbox(label);
  else
    checkbox_->SetLabel(label);
  ResetLayoutManager();
}

void MessageBoxView::SetCheckBoxSelected(bool selected) {
  if (!checkbox_)
    return;
  checkbox_->SetChecked(selected);
}

///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, View overrides:

void MessageBoxView::ViewHierarchyChanged(bool is_add,
                                          View* parent,
                                          View* child) {
  if (child == this && is_add) {
    if (prompt_field_)
      prompt_field_->SelectAll();
  }
}

bool MessageBoxView::AcceleratorPressed(
    const Accelerator& accelerator) {
  // We only accepts Ctrl-C.
  DCHECK(accelerator.GetKeyCode() == 'C' && accelerator.IsCtrlDown());

  // We must not intercept Ctrl-C when we have a text box and it's focused.
  if (prompt_field_ && prompt_field_->HasFocus())
    return false;

  if (!ViewsDelegate::views_delegate)
    return false;

  ui::Clipboard* clipboard = ViewsDelegate::views_delegate->GetClipboard();
  if (!clipboard)
    return false;

  ui::ScopedClipboardWriter scw(clipboard);
  scw.WriteText(WideToUTF16Hack(message_label_->GetText()));
  return true;
}

///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, private:

void MessageBoxView::Init(int dialog_flags,
                          const std::wstring& default_prompt) {
  message_label_->SetMultiLine(true);
  message_label_->SetAllowCharacterBreak(true);
  if (dialog_flags & ui::MessageBoxFlags::kAutoDetectAlignment) {
    // Determine the alignment and directionality based on the first character
    // with strong directionality.
    base::i18n::TextDirection direction =
        base::i18n::GetFirstStrongCharacterDirection(message_label_->GetText());
    Label::Alignment alignment;
    if (direction == base::i18n::RIGHT_TO_LEFT)
      alignment = Label::ALIGN_RIGHT;
    else
      alignment = Label::ALIGN_LEFT;
    // In addition, we should set the RTL alignment mode as
    // AUTO_DETECT_ALIGNMENT so that the alignment will not be flipped around
    // in RTL locales.
    message_label_->set_rtl_alignment_mode(Label::AUTO_DETECT_ALIGNMENT);
    message_label_->SetHorizontalAlignment(alignment);
  } else {
    message_label_->SetHorizontalAlignment(Label::ALIGN_LEFT);
  }

  if (dialog_flags & ui::MessageBoxFlags::kFlagHasPromptField) {
    prompt_field_ = new Textfield;
    prompt_field_->SetText(WideToUTF16Hack(default_prompt));
  }

  ResetLayoutManager();
}

void MessageBoxView::ResetLayoutManager() {
  // Initialize the Grid Layout Manager used for this dialog box.
  GridLayout* layout = GridLayout::CreatePanel(this);
  SetLayoutManager(layout);

  gfx::Size icon_size;
  if (icon_)
    icon_size = icon_->GetPreferredSize();

  // Add the column set for the message displayed at the top of the dialog box.
  // And an icon, if one has been set.
  const int message_column_view_set_id = 0;
  ColumnSet* column_set = layout->AddColumnSet(message_column_view_set_id);
  if (icon_) {
    column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
                          GridLayout::FIXED, icon_size.width(),
                          icon_size.height());
    column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
  }
  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                        GridLayout::FIXED, message_width_, 0);

  // Column set for prompt Textfield, if one has been set.
  const int textfield_column_view_set_id = 1;
  if (prompt_field_) {
    column_set = layout->AddColumnSet(textfield_column_view_set_id);
    if (icon_) {
      column_set->AddPaddingColumn(
          0, icon_size.width() + kUnrelatedControlHorizontalSpacing);
    }
    column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                          GridLayout::USE_PREF, 0, 0);
  }

  // Column set for checkbox, if one has been set.
  const int checkbox_column_view_set_id = 2;
  if (checkbox_) {
    column_set = layout->AddColumnSet(checkbox_column_view_set_id);
    if (icon_) {
      column_set->AddPaddingColumn(
          0, icon_size.width() + kUnrelatedControlHorizontalSpacing);
    }
    column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                          GridLayout::USE_PREF, 0, 0);
  }

  layout->StartRow(0, message_column_view_set_id);
  if (icon_)
    layout->AddView(icon_);

  layout->AddView(message_label_);

  if (prompt_field_) {
    layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
    layout->StartRow(0, textfield_column_view_set_id);
    layout->AddView(prompt_field_);
  }

  if (checkbox_) {
    layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
    layout->StartRow(0, checkbox_column_view_set_id);
    layout->AddView(checkbox_);
  }

  layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}

}  // namespace views
