// Copyright 2016 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 "mash/browser/browser.h"

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "content/public/common/service_names.mojom.h"
#include "mash/browser/debug_view.h"
#include "mash/public/interfaces/launchable.mojom.h"
#include "services/navigation/public/cpp/view.h"
#include "services/navigation/public/cpp/view_delegate.h"
#include "services/navigation/public/cpp/view_observer.h"
#include "services/navigation/public/interfaces/view.mojom.h"
#include "services/service_manager/public/c/main.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/service_runner.h"
#include "ui/aura/window.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/paint_throbber.h"
#include "ui/gfx/text_constants.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/mus/aura_init.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "url/gurl.h"

namespace mash {
namespace browser {

void EnableButton(views::CustomButton* button, bool enabled) {
  button->SetState(enabled ? views::Button::STATE_NORMAL
                           : views::Button::STATE_DISABLED);
}

class Tab;

class TabStripObserver {
 public:
  virtual void OnTabAdded(Tab* added) {}
  virtual void OnTabRemoved(Tab* removed) {}
  virtual void OnTabSelected(Tab* selected) {}
};

class Tab : public views::LabelButton,
            public navigation::ViewObserver,
            public TabStripObserver {
 public:
  class Background : public views::Background {
   public:
    explicit Background(Tab* tab) : tab_(tab) {}
    ~Background() override {}

   private:
    // views::Background:
    void Paint(gfx::Canvas* canvas, views::View* view) const override {
      DCHECK_EQ(view, tab_);
      SkColor bg = tab_->selected() ? SK_ColorGRAY : SK_ColorLTGRAY;
      gfx::Rect lb = view->GetLocalBounds();
      canvas->FillRect(lb, bg);
      if (!tab_->selected()) {
        lb.set_y(lb.bottom() - 1);
        lb.set_height(1);
        canvas->FillRect(lb, SK_ColorGRAY);
      }
    }

    Tab* tab_;

    DISALLOW_COPY_AND_ASSIGN(Background);
  };

  Tab(std::unique_ptr<navigation::View> view,
      views::ButtonListener* listener)
      : views::LabelButton(listener, base::ASCIIToUTF16("Blank")),
        view_(std::move(view)) {
    view_->AddObserver(this);
    set_background(new Background(this));
  }
  ~Tab() override {
    view_->RemoveObserver(this);
  }

  bool selected() const { return selected_; }

  aura::Window* window() { return window_; }
  void SetWindow(aura::Window* window) {
    window_ = window;
    if (selected_)
      window_->Show();
    else
      window_->Hide();
    view_->EmbedInWindow(window_);
  }
  navigation::View* view() { return view_.get(); }

 private:
  // views::View:
  gfx::Size GetPreferredSize() const override {
    gfx::Size ps = views::LabelButton::GetPreferredSize();
    ps.set_width(180);
    return ps;
  }

  // navigation::ViewObserver:
  void NavigationStateChanged(navigation::View* view) override {
    if (!view->title().empty())
      SetText(view->title());
  }

  // TabStripObserver:
  void OnTabSelected(Tab* selected) override {
    selected_ = selected == this;
    SetTextColor(views::Button::STATE_NORMAL,
                 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
    SetTextColor(views::Button::STATE_HOVERED,
                 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
    SetTextColor(views::Button::STATE_PRESSED,
                 selected_ ? SK_ColorWHITE : SK_ColorBLACK);
    if (window_) {
      if (selected_)
        window_->Show();
      else
        window_->Hide();
    }
  }

  aura::Window* window_ = nullptr;
  std::unique_ptr<navigation::View> view_;
  bool selected_ = false;

  DISALLOW_COPY_AND_ASSIGN(Tab);
};

class TabStrip : public views::View,
                 public views::ButtonListener {
 public:
  class Delegate {
   public:
    virtual void NewTab() = 0;
  };

  explicit TabStrip(Delegate* delegate)
    : delegate_(delegate),
      tab_container_(new views::View),
      new_tab_button_(
          new views::LabelButton(this, base::ASCIIToUTF16("+"))) {
    views::BoxLayout* layout =
        new views::BoxLayout(views::BoxLayout::kHorizontal, 5, 0, 0);
    layout->set_main_axis_alignment(
        views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
    layout->set_cross_axis_alignment(
        views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
    layout->SetDefaultFlex(0);
    SetLayoutManager(layout);

    views::BoxLayout* tab_container_layout =
        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
    tab_container_layout->set_main_axis_alignment(
        views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
    tab_container_layout->set_cross_axis_alignment(
        views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
    tab_container_layout->SetDefaultFlex(0);
    tab_container_->SetLayoutManager(tab_container_layout);
    AddChildView(tab_container_);
    layout->SetFlexForView(tab_container_, 1);
    AddChildView(new_tab_button_);
  }
  ~TabStrip() override {
    for (auto* tab : tabs_)
      RemoveObserver(tab);
  }

  void SetContainerWindow(aura::Window* container) {
    DCHECK(!container_);
    container_ = container;
    for (auto* tab : tabs_) {
      aura::Window* window = new aura::Window(nullptr);
      window->Init(ui::LAYER_NOT_DRAWN);
      container_->AddChild(window);
      tab->SetWindow(window);
    }
  }

  void AddTab(std::unique_ptr<navigation::View> view) {
    selected_index_ = static_cast<int>(tabs_.size());
    Tab* tab = new Tab(std::move(view), this);
    // We won't have a WindowTree until we're added to a view hierarchy.
    if (container_) {
      aura::Window* window = new aura::Window(nullptr);
      window->Init(ui::LAYER_NOT_DRAWN);
      container_->AddChild(window);
      tab->SetWindow(window);
    }
    AddObserver(tab);
    tabs_.push_back(tab);
    tab_container_->AddChildView(tab);
    for (auto& observer : observers_)
      observer.OnTabAdded(tab);
    SelectTab(tab);
  }

  void CloseTabForView(navigation::View* view) {
    for (auto it = tabs_.begin(); it != tabs_.end(); ++it) {
      Tab* tab = *it;
      if (tab->view() == view) {
        CloseTab(tab);
        break;
      }
    }
  }

  void CloseTab(Tab* tab) {
    auto it = std::find(tabs_.begin(), tabs_.end(), tab);
    int tab_index = static_cast<int>(it - tabs_.begin());
    if (tab_index < selected_index_)
      --selected_index_;
    DCHECK(it != tabs_.end());
    tabs_.erase(it);
    RemoveObserver(tab);
    tab_container_->RemoveChildView(tab);
    if (tab->selected()) {
      int next_selected_index = selected_index_;
      if (selected_index_ == static_cast<int>(tabs_.size()))
        --next_selected_index;
      if (next_selected_index >= 0)
        SelectTab(tabs_[next_selected_index]);
    }
    Layout();
    for (auto& observer : observers_)
      observer.OnTabRemoved(tab);
    delete tab;
  }

  bool empty() const { return tabs_.empty(); }

  void SelectTab(Tab* tab) {
    auto it = std::find(tabs_.begin(), tabs_.end(), tab);
    DCHECK(it != tabs_.end());
    selected_index_ = it - tabs_.begin();
    for (auto& observer : observers_)
      observer.OnTabSelected(tab);
  }
  Tab* selected_tab() {
    return selected_index_ != -1 ? tabs_[selected_index_] : nullptr;
  }

  void AddObserver(TabStripObserver* observer) {
    observers_.AddObserver(observer);
  }
  void RemoveObserver(TabStripObserver* observer) {
    observers_.RemoveObserver(observer);
  }

 private:
  // views::View:
  void OnPaint(gfx::Canvas* canvas) override {
    gfx::Rect lb = GetLocalBounds();
    lb.set_y(lb.bottom() - 1);
    lb.set_height(1);
    canvas->FillRect(lb, SK_ColorGRAY);
  }

  // views::ButtonListener:
  void ButtonPressed(views::Button* sender, const ui::Event& event) override {
    auto it = std::find(tabs_.begin(), tabs_.end(), sender);
    if (it != tabs_.end()) {
      if (event.IsControlDown())
        CloseTab(*it);
      else
        SelectTab(*it);
    }
    else if (sender == new_tab_button_ && delegate_)
      delegate_->NewTab();
  }

  Delegate* delegate_;
  views::View* tab_container_;
  views::LabelButton* new_tab_button_;
  std::vector<Tab*> tabs_;
  int selected_index_ = -1;
  base::ObserverList<TabStripObserver> observers_;
  aura::Window* container_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(TabStrip);
};

class NavMenuModel : public ui::MenuModel {
 public:
  class Delegate {
   public:
    virtual void NavigateToOffset(int offset) = 0;
  };

  NavMenuModel(const std::vector<navigation::NavigationListItem>& entries,
               Delegate* delegate)
      : navigation_delegate_(delegate), entries_(entries) {}
  ~NavMenuModel() override {}

 private:
  bool HasIcons() const override { return false; }
  int GetItemCount() const override {
    return static_cast<int>(entries_.size());
  }
  ui::MenuModel::ItemType GetTypeAt(int index) const override {
    return ui::MenuModel::TYPE_COMMAND;
  }
  ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
    return ui::NORMAL_SEPARATOR;
  }
  int GetCommandIdAt(int index) const override {
    return index;
  }
  base::string16 GetLabelAt(int index) const override {
    return entries_[index].title;
  }
  base::string16 GetSublabelAt(int index) const override {
    return base::string16();
  }
  base::string16 GetMinorTextAt(int index) const override {
    return base::string16();
  }
  bool IsItemDynamicAt(int index) const override { return false; }
  bool GetAcceleratorAt(int index,
                        ui::Accelerator* accelerator) const override {
    return false;
  }
  bool IsItemCheckedAt(int index) const override { return false; }
  int GetGroupIdAt(int index) const override { return -1; }
  bool GetIconAt(int index, gfx::Image* icon) override { return false; }
  ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
    return nullptr;
  }
  bool IsEnabledAt(int index) const override { return true; }
  bool IsVisibleAt(int index) const override { return true; }
  ui::MenuModel* GetSubmenuModelAt(int index) const override { return nullptr; }
  void HighlightChangedTo(int index) override {}
  void ActivatedAt(int index) override {
    ActivatedAt(index, 0);
  }
  void ActivatedAt(int index, int event_flags) override {
    navigation_delegate_->NavigateToOffset(entries_[index].offset);
  }
  void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) override {
    delegate_ = delegate;
  }
  ui::MenuModelDelegate* GetMenuModelDelegate() const override {
    return delegate_;
  }

  ui::MenuModelDelegate* delegate_ = nullptr;
  Delegate* navigation_delegate_;
  std::vector<navigation::NavigationListItem> entries_;

  DISALLOW_COPY_AND_ASSIGN(NavMenuModel);
};

class NavButton : public views::LabelButton {
 public:
  enum class Type {
    BACK,
    FORWARD
  };

  class ModelProvider {
   public:
    virtual std::unique_ptr<ui::MenuModel> CreateMenuModel(Type type) = 0;
  };

  NavButton(Type type,
            ModelProvider* model_provider,
            views::ButtonListener* listener,
            const base::string16& label)
      : views::LabelButton(listener, label),
        type_(type),
        model_provider_(model_provider),
        show_menu_factory_(this) {}
  ~NavButton() override {}

 private:
  // views::LabelButton overrides:
  bool OnMousePressed(const ui::MouseEvent& event) override {
    if (IsTriggerableEvent(event) && enabled() &&
        HitTestPoint(event.location())) {
      y_pos_on_lbuttondown_ = event.y();
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE,
          base::Bind(&NavButton::ShowMenu, show_menu_factory_.GetWeakPtr(),
                     ui::GetMenuSourceTypeForEvent(event)),
          base::TimeDelta::FromMilliseconds(500));
    }
    return LabelButton::OnMousePressed(event);
  }
  bool OnMouseDragged(const ui::MouseEvent& event) override {
    bool result = LabelButton::OnMouseDragged(event);
    if (show_menu_factory_.HasWeakPtrs()) {
      if (event.y() > y_pos_on_lbuttondown_ + GetHorizontalDragThreshold()) {
        show_menu_factory_.InvalidateWeakPtrs();
        ShowMenu(ui::GetMenuSourceTypeForEvent(event));
      }
    }
    return result;
  }
  void OnMouseReleased(const ui::MouseEvent& event) override {
    if (IsTriggerableEvent(event))
      show_menu_factory_.InvalidateWeakPtrs();
    LabelButton::OnMouseReleased(event);
  }

  void ShowMenu(ui::MenuSourceType source_type) {
    gfx::Rect local = GetLocalBounds();
    gfx::Point menu_position(local.origin());
    menu_position.Offset(0, local.height() - 1);
    View::ConvertPointToScreen(this, &menu_position);

    model_ = model_provider_->CreateMenuModel(type_);
    menu_model_adapter_.reset(new views::MenuModelAdapter(
        model_.get(),
        base::Bind(&NavButton::OnMenuClosed, base::Unretained(this))));
    menu_model_adapter_->set_triggerable_event_flags(triggerable_event_flags());
    menu_runner_.reset(new views::MenuRunner(menu_model_adapter_->CreateMenu(),
                                             views::MenuRunner::HAS_MNEMONICS));
    menu_runner_->RunMenuAt(GetWidget(), nullptr,
                            gfx::Rect(menu_position, gfx::Size(0, 0)),
                            views::MENU_ANCHOR_TOPLEFT, source_type);
  }

  void OnMenuClosed() {
    SetMouseHandler(nullptr);
    model_.reset();
    menu_runner_.reset();
    menu_model_adapter_.reset();
  }

  Type type_;
  ModelProvider* model_provider_;
  int y_pos_on_lbuttondown_ = 0;
  std::unique_ptr<ui::MenuModel> model_;
  std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_;
  std::unique_ptr<views::MenuRunner> menu_runner_;
  base::WeakPtrFactory<NavButton> show_menu_factory_;

  DISALLOW_COPY_AND_ASSIGN(NavButton);
};

class ProgressBar : public views::View {
 public:
  ProgressBar() {}
  ~ProgressBar() override {}

  void SetProgress(double progress) {
    progress_ = progress;
    SchedulePaint();
  }

 private:
  void OnPaint(gfx::Canvas* canvas) override {
    gfx::Rect stroke_rect = GetLocalBounds();
    stroke_rect.set_y(stroke_rect.bottom() - 1);
    stroke_rect.set_height(1);
    canvas->FillRect(stroke_rect, SK_ColorGRAY);
    if (progress_ != 0.f) {
      gfx::Rect progress_rect = GetLocalBounds();
      progress_rect.set_width(progress_rect.width() * progress_);
      canvas->FillRect(progress_rect, SK_ColorRED);
    }
  }

  double progress_ = 0.f;

  DISALLOW_COPY_AND_ASSIGN(ProgressBar);
};

class Throbber : public views::View {
 public:
  Throbber() : timer_(false, true), weak_factory_(this) {}
  ~Throbber() override {}

  void Start() {
    throbbing_ = true;
    start_time_ = base::TimeTicks::Now();
    SchedulePaint();
    timer_.Start(
        FROM_HERE, base::TimeDelta::FromMilliseconds(30),
        base::Bind(&Throbber::SchedulePaint, weak_factory_.GetWeakPtr()));
  }

  void Stop() {
    throbbing_ = false;
    if (timer_.IsRunning())
      timer_.Stop();
    SchedulePaint();
  }

 private:
  void OnPaint(gfx::Canvas* canvas) override {
    if (!throbbing_)
      return;

    gfx::PaintThrobberSpinning(
        canvas, GetLocalBounds(),
        GetNativeTheme()->GetSystemColor(
            ui::NativeTheme::kColorId_ThrobberSpinningColor),
        base::TimeTicks::Now() - start_time_);
  }

  bool throbbing_ = false;
  base::TimeTicks start_time_;
  base::Timer timer_;
  base::WeakPtrFactory<Throbber> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(Throbber);
};

class UI : public views::WidgetDelegateView,
           public views::ButtonListener,
           public views::TextfieldController,
           public TabStrip::Delegate,
           public TabStripObserver,
           public navigation::ViewDelegate,
           public navigation::ViewObserver,
           public NavButton::ModelProvider,
           public NavMenuModel::Delegate {
 public:
  enum class Type { WINDOW, POPUP };

  UI(Browser* browser, Type type, std::unique_ptr<navigation::View> view)
      : browser_(browser),
        type_(type),
        tab_strip_(new TabStrip(this)),
        back_button_(new NavButton(NavButton::Type::BACK, this, this,
                                   base::ASCIIToUTF16("Back"))),
        forward_button_(new NavButton(NavButton::Type::FORWARD, this, this,
                                      base::ASCIIToUTF16("Forward"))),
        reload_button_(
            new views::LabelButton(this, base::ASCIIToUTF16("Reload"))),
        prompt_(new views::Textfield),
        debug_button_(new views::LabelButton(this, base::ASCIIToUTF16("DV"))),
        throbber_(new Throbber),
        progress_bar_(new ProgressBar),
        debug_view_(new DebugView) {
    set_background(views::Background::CreateStandardPanelBackground());
    prompt_->set_controller(this);
    back_button_->set_request_focus_on_press(false);
    forward_button_->set_request_focus_on_press(false);
    reload_button_->set_request_focus_on_press(false);
    AddChildView(tab_strip_);
    AddChildView(back_button_);
    AddChildView(forward_button_);
    AddChildView(reload_button_);
    AddChildView(prompt_);
    AddChildView(debug_button_);
    AddChildView(throbber_);
    AddChildView(progress_bar_);
    AddChildView(debug_view_);

    tab_strip_->AddObserver(this);
    tab_strip_->AddTab(std::move(view));
  }
  ~UI() override {
    browser_->RemoveWindow(GetWidget());
  }

  void NavigateTo(const GURL& url) {
    selected_view()->NavigateToURL(url);
  }

 private:
  // Overridden from views::WidgetDelegate:
  base::string16 GetWindowTitle() const override {
    // TODO(beng): use resources.
    if (selected_view()->title().empty())
      return base::ASCIIToUTF16("Browser");
    base::string16 format = base::ASCIIToUTF16("%s - Browser");
    base::ReplaceFirstSubstringAfterOffset(&format, 0, base::ASCIIToUTF16("%s"),
                                           selected_view()->title());
    return format;
  }
  bool CanResize() const override { return true; }
  bool CanMaximize() const override { return true; }
  bool CanMinimize() const override { return true; }

  // views::ButtonListener:
  void ButtonPressed(views::Button* sender, const ui::Event& event) override {
    if (sender == back_button_) {
      selected_view()->GoBack();
    } else if (sender == forward_button_) {
      selected_view()->GoForward();
    } else if (sender == reload_button_) {
      if (selected_view()->is_loading())
        selected_view()->Stop();
      else
        selected_view()->Reload(false);
    } else if (sender == debug_button_) {
      ToggleDebugView();
    }
  }

  // Overridden from views::View:
  void Layout() override {
    gfx::Rect local_bounds = GetLocalBounds();

    gfx::Size ps = tab_strip_->GetPreferredSize();
    tab_strip_->SetBoundsRect(
        gfx::Rect(0, 5, local_bounds.width(), ps.height()));

    gfx::Rect bounds = local_bounds;
    bounds.set_y(tab_strip_->bounds().bottom());
    bounds.Inset(5, 5);

    ps = back_button_->GetPreferredSize();
    back_button_->SetBoundsRect(
        gfx::Rect(bounds.x(), bounds.y(), ps.width(), ps.height()));
    ps = forward_button_->GetPreferredSize();
    forward_button_->SetBoundsRect(gfx::Rect(back_button_->bounds().right() + 5,
                                             bounds.y(), ps.width(),
                                             ps.height()));
    ps = reload_button_->GetPreferredSize();
    reload_button_->SetBoundsRect(
        gfx::Rect(forward_button_->bounds().right() + 5, bounds.y(), ps.width(),
                  ps.height()));

    ps = prompt_->GetPreferredSize();
    int throbber_size = ps.height();
    gfx::Size debug_ps = debug_button_->GetPreferredSize();
    int prompt_y =
        bounds.y() + (reload_button_->bounds().height() - ps.height()) / 2;
    int width =
        bounds.width() - reload_button_->bounds().right() - throbber_size - 15 -
        debug_ps.width();
    prompt_->SetBoundsRect(gfx::Rect(reload_button_->bounds().right() + 5,
                                     prompt_y, width, ps.height()));

    debug_button_->SetBoundsRect(
        gfx::Rect(prompt_->bounds().right() + 5,
                  prompt_->bounds().y(), debug_ps.width(), debug_ps.height()));

    throbber_->SetBoundsRect(gfx::Rect(debug_button_->bounds().right() + 5,
                                       prompt_->bounds().y(), throbber_size,
                                       throbber_size));

    gfx::Rect progress_bar_rect(local_bounds.x(),
                                back_button_->bounds().bottom() + 5,
                                local_bounds.width(), 2);
    progress_bar_->SetBoundsRect(progress_bar_rect);

    int debug_view_height = 0;
    if (showing_debug_view_)
      debug_view_height = debug_view_->GetPreferredSize().height();
    debug_view_->SetBoundsRect(
        gfx::Rect(local_bounds.x(), local_bounds.height() - debug_view_height,
                  local_bounds.width(), debug_view_height));

    if (content_area_) {
      int x = local_bounds.x();
      int y = type_ == Type::POPUP ? 0 : progress_bar_->bounds().bottom();
      gfx::Point offset(x, y);
      ConvertPointToWidget(this, &offset);
      int width = local_bounds.width();
      int height = local_bounds.height() - y - debug_view_height;
      content_area_->SetBounds(
          gfx::Rect(offset.x(), offset.y(), width, height));
      for (auto* child : content_area_->children())
        child->SetBounds(gfx::Rect(0, 0, width, height));
    }
  }
  void ViewHierarchyChanged(
      const views::View::ViewHierarchyChangedDetails& details) override {
    if (details.is_add && GetWidget() && !content_area_) {
      aura::Window* window = GetWidget()->GetNativeWindow();
      content_area_ = new aura::Window(nullptr);
      content_area_->Init(ui::LAYER_NOT_DRAWN);
      content_area_->Show();
      window->AddChild(content_area_);
      tab_strip_->SetContainerWindow(content_area_);
    }
  }

  // Overridden from views::TextFieldController:
  bool HandleKeyEvent(views::Textfield* sender,
                      const ui::KeyEvent& key_event) override {
    if (key_event.type() == ui::ET_KEY_PRESSED &&
        key_event.key_code() == ui::VKEY_RETURN)
      selected_view()->NavigateToURL(GURL(prompt_->text()));
    return false;
  }

  // TabStrip::Delegate:
  void NewTab() override {
    tab_strip_->AddTab(browser_->CreateView());
    tab_strip_->selected_tab()->view()->NavigateToURL(GURL("about:blank"));
  }

  // TabStripObserver:
  void OnTabAdded(Tab* added) override {
    added->view()->AddObserver(this);
    added->view()->set_delegate(this);
  }
  void OnTabSelected(Tab* selected) override {
    debug_view_->set_view(selected->view());
    prompt_->SetText(base::UTF8ToUTF16(selected->view()->url().spec()));
    if (GetWidget())
      GetWidget()->UpdateWindowTitle();
  }

  // navigation::ViewDelegate:
  void ViewCreated(navigation::View* source,
                   std::unique_ptr<navigation::View> view,
                   bool is_popup,
                   const gfx::Rect& initial_rect,
                   bool user_gesture) override {
    if (is_popup)
      CreateNewWindow(std::move(view), initial_rect, is_popup);
    else
      tab_strip_->AddTab(std::move(view));
  }
  void Close(navigation::View* source) override {
    tab_strip_->CloseTabForView(source);
    if (tab_strip_->empty())
      GetWidget()->Close();
  }
  void OpenURL(navigation::View* source,
               navigation::mojom::OpenURLParamsPtr params) override {
    switch (params->disposition) {
      case navigation::mojom::WindowOpenDisposition::CURRENT_TAB:
        selected_view()->NavigateToURL(params->url);
        break;
      case navigation::mojom::WindowOpenDisposition::NEW_FOREGROUND_TAB:
        tab_strip_->AddTab(browser_->CreateView());
        tab_strip_->selected_tab()->view()->NavigateToURL(params->url);
        break;
      case navigation::mojom::WindowOpenDisposition::NEW_POPUP:
      case navigation::mojom::WindowOpenDisposition::NEW_WINDOW: {
        std::unique_ptr<navigation::View> view = browser_->CreateView();
        view->NavigateToURL(params->url);
        CreateNewWindow(
            std::move(view), gfx::Rect(),
            params->disposition ==
                navigation::mojom::WindowOpenDisposition::NEW_POPUP);
        break;
      }
      default:
        break;
    }
  }

  // navigation::ViewObserver:
  void LoadingStateChanged(navigation::View* view) override {
    if (view->is_loading()) {
      reload_button_->SetText(base::ASCIIToUTF16("Stop"));
      throbber_->Start();
    } else {
      reload_button_->SetText(base::ASCIIToUTF16("Reload"));
      throbber_->Stop();
      progress_bar_->SetProgress(0.f);
    }
  }
  void LoadProgressChanged(navigation::View* view, double progress) override {
    progress_bar_->SetProgress(progress);
  }
  void NavigationStateChanged(navigation::View* view) override {
    EnableButton(back_button_, view->can_go_back());
    EnableButton(forward_button_, view->can_go_forward());
    prompt_->SetText(base::UTF8ToUTF16(view->url().spec()));
    GetWidget()->UpdateWindowTitle();
  }
  void HoverTargetURLChanged(navigation::View* view, const GURL& url) override {
    if (url.is_valid())
      prompt_->SetText(base::UTF8ToUTF16(url.spec()));
    else
      prompt_->SetText(base::UTF8ToUTF16(selected_view()->url().spec()));
  }

  // NavButton::ModelProvider:
  std::unique_ptr<ui::MenuModel> CreateMenuModel(
      NavButton::Type type) override {
    std::vector<navigation::NavigationListItem> entries;
    if (type == NavButton::Type::BACK) {
      selected_view()->GetBackMenuItems(&entries);
    } else {
      selected_view()->GetForwardMenuItems(&entries);
    }
    return base::MakeUnique<NavMenuModel>(entries, this);
  }

  // NavMenuModel::Delegate:
  void NavigateToOffset(int offset) override {
    selected_view()->NavigateToOffset(offset);
  }

  navigation::View* selected_view() {
    return const_cast<navigation::View*>(
        static_cast<const UI*>(this)->selected_view());
  }
  const navigation::View* selected_view() const {
    return tab_strip_->selected_tab()->view();
  }

  void CreateNewWindow(std::unique_ptr<navigation::View> view,
                       const gfx::Rect& initial_bounds,
                       bool is_popup) {
    gfx::Rect bounds = initial_bounds;
    if (bounds.IsEmpty())
      bounds = gfx::Rect(10, 10, 400, 300);
    views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
        new UI(browser_, is_popup ? UI::Type::POPUP : UI::Type::WINDOW,
               std::move(view)),
        nullptr, bounds);
    window->Show();
    browser_->AddWindow(window);
  }

  void ToggleDebugView() {
    showing_debug_view_ = !showing_debug_view_;
    Layout();
  }

  Browser* browser_;

  Type type_;

  TabStrip* tab_strip_;
  views::LabelButton* back_button_;
  views::LabelButton* forward_button_;
  views::LabelButton* reload_button_;
  views::Textfield* prompt_;
  views::LabelButton* debug_button_;
  Throbber* throbber_;
  ProgressBar* progress_bar_;

  aura::Window* content_area_ = nullptr;

  DebugView* debug_view_;
  bool showing_debug_view_ = false;

  DISALLOW_COPY_AND_ASSIGN(UI);
};

Browser::Browser() {
  registry_.AddInterface<mojom::Launchable>(
      base::Bind(&Browser::Create, base::Unretained(this)));
}
Browser::~Browser() {}

void Browser::AddWindow(views::Widget* window) {
  windows_.push_back(window);
}

void Browser::RemoveWindow(views::Widget* window) {
  auto it = std::find(windows_.begin(), windows_.end(), window);
  DCHECK(it != windows_.end());
  windows_.erase(it);
  if (windows_.empty())
    base::MessageLoop::current()->QuitWhenIdle();
}

std::unique_ptr<navigation::View> Browser::CreateView() {
  navigation::mojom::ViewFactoryPtr factory;
  context()->connector()->BindInterface(content::mojom::kBrowserServiceName,
                                        &factory);
  return base::MakeUnique<navigation::View>(std::move(factory));
}

void Browser::OnStart() {
  aura_init_ = base::MakeUnique<views::AuraInit>(
      context()->connector(), context()->identity(), "views_mus_resources.pak",
      std::string(), nullptr, views::AuraInit::Mode::AURA_MUS);
}

void Browser::OnBindInterface(
    const service_manager::BindSourceInfo& source_info,
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle interface_pipe) {
  registry_.BindInterface(source_info, interface_name,
                          std::move(interface_pipe));
}

void Browser::Launch(uint32_t what, mojom::LaunchMode how) {
  bool reuse =
      how == mojom::LaunchMode::REUSE || how == mojom::LaunchMode::DEFAULT;
  if (reuse && !windows_.empty()) {
    windows_.back()->Activate();
    return;
  }

  UI* ui = new UI(this, UI::Type::WINDOW, CreateView());
  views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
      ui, nullptr, gfx::Rect(10, 10, 1024, 600));
  ui->NavigateTo(GURL("http://www.google.com/"));
  window->Show();
  AddWindow(window);
}

void Browser::Create(const service_manager::BindSourceInfo& source_info,
                     mojom::LaunchableRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

}  // namespace browser
}  // namespace mash
