// 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 "ash/shell/window_type_launcher.h"

#include "ash/root_window_controller.h"
#include "ash/screensaver/screensaver_view.h"
#include "ash/session_state_delegate.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/shell/example_factory.h"
#include "ash/shell/panel_window.h"
#include "ash/shell/toplevel_window.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/web_notification/web_notification_tray.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/notification_types.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/corewm/shadow_types.h"
#include "ui/views/examples/examples_window_with_content.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/test/child_modal_window.h"
#include "ui/views/widget/widget.h"

using views::MenuItemView;
using views::MenuRunner;

namespace ash {
namespace shell {

namespace {

SkColor g_colors[] = { SK_ColorRED,
                       SK_ColorYELLOW,
                       SK_ColorBLUE,
                       SK_ColorGREEN };
int g_color_index = 0;

class ModalWindow : public views::WidgetDelegateView,
                    public views::ButtonListener {
 public:
  explicit ModalWindow(ui::ModalType modal_type)
      : modal_type_(modal_type),
        color_(g_colors[g_color_index]),
        open_button_(new views::LabelButton(this, ASCIIToUTF16("Moar!"))) {
    ++g_color_index %= arraysize(g_colors);
    open_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
    AddChildView(open_button_);
  }
  virtual ~ModalWindow() {
  }

  static void OpenModalWindow(aura::Window* parent, ui::ModalType modal_type) {
    views::Widget* widget =
        views::Widget::CreateWindowWithParent(new ModalWindow(modal_type),
                                              parent);
    widget->GetNativeView()->SetName("ModalWindow");
    widget->Show();
  }

  // Overridden from views::View:
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->FillRect(GetLocalBounds(), color_);
  }
  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(200, 200);
  }
  virtual void Layout() OVERRIDE {
    gfx::Size open_ps = open_button_->GetPreferredSize();
    gfx::Rect local_bounds = GetLocalBounds();
    open_button_->SetBounds(
        5, local_bounds.bottom() - open_ps.height() - 5,
        open_ps.width(), open_ps.height());
  }

  // Overridden from views::WidgetDelegate:
  virtual views::View* GetContentsView() OVERRIDE {
    return this;
  }
  virtual bool CanResize() const OVERRIDE {
    return true;
  }
  virtual base::string16 GetWindowTitle() const OVERRIDE {
    return ASCIIToUTF16("Modal Window");
  }
  virtual ui::ModalType GetModalType() const OVERRIDE {
    return modal_type_;
  }

  // Overridden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender,
                             const ui::Event& event) OVERRIDE {
    DCHECK(sender == open_button_);
    OpenModalWindow(GetWidget()->GetNativeView(), modal_type_);
  }

 private:
  ui::ModalType modal_type_;
  SkColor color_;
  views::LabelButton* open_button_;

  DISALLOW_COPY_AND_ASSIGN(ModalWindow);
};

class NonModalTransient : public views::WidgetDelegateView {
 public:
  NonModalTransient()
      : color_(g_colors[g_color_index]) {
    ++g_color_index %= arraysize(g_colors);
  }
  virtual ~NonModalTransient() {
  }

  static void OpenNonModalTransient(aura::Window* parent) {
    views::Widget* widget =
        views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
    widget->GetNativeView()->SetName("NonModalTransient");
    widget->Show();
  }

  static void ToggleNonModalTransient(aura::Window* parent) {
    if (!non_modal_transient_) {
      non_modal_transient_ =
          views::Widget::CreateWindowWithParent(new NonModalTransient, parent);
      non_modal_transient_->GetNativeView()->SetName("NonModalTransient");
    }
    if (non_modal_transient_->IsVisible())
      non_modal_transient_->Hide();
    else
      non_modal_transient_->Show();
  }

  // Overridden from views::View:
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->FillRect(GetLocalBounds(), color_);
  }
  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(250, 250);
  }

  // Overridden from views::WidgetDelegate:
  virtual views::View* GetContentsView() OVERRIDE {
    return this;
  }
  virtual bool CanResize() const OVERRIDE {
    return true;
  }
  virtual base::string16 GetWindowTitle() const OVERRIDE {
    return ASCIIToUTF16("Non-Modal Transient");
  }
  virtual void DeleteDelegate() OVERRIDE {
    if (GetWidget() == non_modal_transient_)
      non_modal_transient_ = NULL;

    delete this;
  }

 private:
  SkColor color_;

  static views::Widget* non_modal_transient_;

  DISALLOW_COPY_AND_ASSIGN(NonModalTransient);
};

// static
views::Widget* NonModalTransient::non_modal_transient_ = NULL;

void AddViewToLayout(views::GridLayout* layout, views::View* view) {
  layout->StartRow(0, 0);
  layout->AddView(view);
  layout->AddPaddingRow(0, 5);
}

}  // namespace

void InitWindowTypeLauncher() {
  views::Widget* widget =
      views::Widget::CreateWindowWithContextAndBounds(
          new WindowTypeLauncher,
          Shell::GetPrimaryRootWindow(),
          gfx::Rect(120, 150, 300, 410));
  widget->GetNativeView()->SetName("WindowTypeLauncher");
  views::corewm::SetShadowType(widget->GetNativeView(),
                               views::corewm::SHADOW_TYPE_RECTANGULAR);
  widget->Show();
}

WindowTypeLauncher::WindowTypeLauncher()
    : create_button_(new views::LabelButton(
          this, ASCIIToUTF16("Create Window"))),
      panel_button_(new views::LabelButton(
          this, ASCIIToUTF16("Create Panel"))),
      create_nonresizable_button_(new views::LabelButton(
          this, ASCIIToUTF16("Create Non-Resizable Window"))),
      bubble_button_(new views::LabelButton(
          this, ASCIIToUTF16("Create Pointy Bubble"))),
      lock_button_(new views::LabelButton(
          this, ASCIIToUTF16("Lock Screen"))),
      widgets_button_(new views::LabelButton(
          this, ASCIIToUTF16("Show Example Widgets"))),
      system_modal_button_(new views::LabelButton(
          this, ASCIIToUTF16("Open System Modal Window"))),
      window_modal_button_(new views::LabelButton(
          this, ASCIIToUTF16("Open Window Modal Window"))),
      child_modal_button_(new views::LabelButton(
          this, ASCIIToUTF16("Open Child Modal Window"))),
      transient_button_(new views::LabelButton(
          this, ASCIIToUTF16("Open Non-Modal Transient Window"))),
      examples_button_(new views::LabelButton(
          this, ASCIIToUTF16("Open Views Examples Window"))),
      show_hide_window_button_(new views::LabelButton(
          this, ASCIIToUTF16("Show/Hide a Window"))),
      show_screensaver_(new views::LabelButton(
          this, ASCIIToUTF16("Show the Screensaver [for 5 seconds]"))),
      show_web_notification_(new views::LabelButton(
          this, ASCIIToUTF16("Show a web/app notification"))) {
  create_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  panel_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  create_nonresizable_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  bubble_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  lock_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  widgets_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  system_modal_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  window_modal_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  child_modal_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  transient_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  examples_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  show_hide_window_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  show_screensaver_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
  show_web_notification_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);

  views::GridLayout* layout = new views::GridLayout(this);
  layout->SetInsets(5, 5, 5, 5);
  SetLayoutManager(layout);
  views::ColumnSet* column_set = layout->AddColumnSet(0);
  column_set->AddColumn(views::GridLayout::LEADING,
                        views::GridLayout::CENTER,
                        0,
                        views::GridLayout::USE_PREF,
                        0,
                        0);
  AddViewToLayout(layout, create_button_);
  AddViewToLayout(layout, panel_button_);
  AddViewToLayout(layout, create_nonresizable_button_);
  AddViewToLayout(layout, bubble_button_);
  AddViewToLayout(layout, lock_button_);
  AddViewToLayout(layout, widgets_button_);
  AddViewToLayout(layout, system_modal_button_);
  AddViewToLayout(layout, window_modal_button_);
  AddViewToLayout(layout, child_modal_button_);
  AddViewToLayout(layout, transient_button_);
  AddViewToLayout(layout, examples_button_);
  AddViewToLayout(layout, show_hide_window_button_);
  AddViewToLayout(layout, show_screensaver_);
  AddViewToLayout(layout, show_web_notification_);
  set_context_menu_controller(this);
}

WindowTypeLauncher::~WindowTypeLauncher() {
}

void WindowTypeLauncher::OnPaint(gfx::Canvas* canvas) {
  canvas->FillRect(GetLocalBounds(), SK_ColorWHITE);
}

bool WindowTypeLauncher::OnMousePressed(const ui::MouseEvent& event) {
  // Overridden so we get OnMouseReleased and can show the context menu.
  return true;
}

views::View* WindowTypeLauncher::GetContentsView() {
  return this;
}

bool WindowTypeLauncher::CanResize() const {
  return true;
}

base::string16 WindowTypeLauncher::GetWindowTitle() const {
  return ASCIIToUTF16("Examples: Window Builder");
}

bool WindowTypeLauncher::CanMaximize() const {
  return true;
}

void WindowTypeLauncher::ButtonPressed(views::Button* sender,
                                       const ui::Event& event) {
  if (sender == create_button_) {
    ToplevelWindow::CreateParams params;
    params.can_resize = true;
    params.can_maximize = true;
    ToplevelWindow::CreateToplevelWindow(params);
  } else if (sender == panel_button_) {
    PanelWindow::CreatePanelWindow(gfx::Rect());
  } else if (sender == create_nonresizable_button_) {
    ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
  } else if (sender == bubble_button_) {
    CreatePointyBubble(sender);
  } else if (sender == lock_button_) {
    Shell::GetInstance()->session_state_delegate()->LockScreen();
  } else if (sender == widgets_button_) {
    CreateWidgetsWindow();
  } else if (sender == system_modal_button_) {
    ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
                                 ui::MODAL_TYPE_SYSTEM);
  } else if (sender == window_modal_button_) {
    ModalWindow::OpenModalWindow(GetWidget()->GetNativeView(),
                                 ui::MODAL_TYPE_WINDOW);
  } else if (sender == child_modal_button_) {
    views::test::CreateChildModalParent(
        GetWidget()->GetNativeView()->GetRootWindow());
  } else if (sender == transient_button_) {
    NonModalTransient::OpenNonModalTransient(GetWidget()->GetNativeView());
  } else if (sender == show_hide_window_button_) {
    NonModalTransient::ToggleNonModalTransient(GetWidget()->GetNativeView());
  } else if (sender == show_screensaver_) {
    ash::ShowScreensaver(GURL("http://www.google.com"));
    content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
                                            FROM_HERE,
                                            base::Bind(&ash::CloseScreensaver),
                                            base::TimeDelta::FromSeconds(5));

  } else if (sender == show_web_notification_) {
    scoped_ptr<message_center::Notification> notification;
    notification.reset(new message_center::Notification(
        message_center::NOTIFICATION_TYPE_SIMPLE,
        "id0",
        ASCIIToUTF16("Test Shell Web Notification"),
        ASCIIToUTF16("Notification message body."),
        gfx::Image(),
        ASCIIToUTF16("www.testshell.org"),
        message_center::NotifierId(
            message_center::NotifierId::APPLICATION, "test-id"),
        message_center::RichNotificationData(),
        NULL /* delegate */));

    ash::Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget()
        ->web_notification_tray()->message_center()
        ->AddNotification(notification.Pass());
  } else if (sender == examples_button_) {
    views::examples::ShowExamplesWindowWithContent(
        views::examples::DO_NOTHING_ON_CLOSE,
        Shell::GetInstance()->delegate()->GetActiveBrowserContext(),
        NULL);
  }
}

void WindowTypeLauncher::ExecuteCommand(int id, int event_flags) {
  switch (id) {
    case COMMAND_NEW_WINDOW:
      InitWindowTypeLauncher();
      break;
    case COMMAND_TOGGLE_FULLSCREEN:
      GetWidget()->SetFullscreen(!GetWidget()->IsFullscreen());
      break;
    default:
      break;
  }
}

void WindowTypeLauncher::ShowContextMenuForView(
    views::View* source,
    const gfx::Point& point,
    ui::MenuSourceType source_type) {
  MenuItemView* root = new MenuItemView(this);
  root->AppendMenuItem(COMMAND_NEW_WINDOW,
                       ASCIIToUTF16("New Window"),
                       MenuItemView::NORMAL);
  root->AppendMenuItem(COMMAND_TOGGLE_FULLSCREEN,
                       ASCIIToUTF16("Toggle FullScreen"),
                       MenuItemView::NORMAL);
  // MenuRunner takes ownership of root.
  menu_runner_.reset(new MenuRunner(root));
  if (menu_runner_->RunMenuAt(GetWidget(), NULL,
        gfx::Rect(point, gfx::Size()),
        MenuItemView::TOPLEFT,
        source_type,
        MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) ==
        MenuRunner::MENU_DELETED)
    return;
}

}  // namespace shell
}  // namespace ash
