// Copyright 2014 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 "base/bind.h"
#include "base/macros.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/examples/keyboard/keyboard.mojom.h"
#include "mojo/examples/window_manager/debug_panel.h"
#include "mojo/examples/window_manager/window_manager.mojom.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/interface_factory_impl.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
#include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/cpp/view_manager/window_manager_delegate.h"
#include "mojo/services/public/interfaces/input_events/input_events.mojom.h"
#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
#include "mojo/services/window_manager/window_manager_app.h"
#include "mojo/views/views_init.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/wm/core/focus_rules.h"

#if defined CreateWindow
#undef CreateWindow
#endif

namespace mojo {
namespace examples {

class WindowManager;

namespace {

const int kBorderInset = 25;
const int kControlPanelWidth = 200;
const int kTextfieldHeight = 25;

class WMFocusRules : public wm::FocusRules {
 public:
  WMFocusRules(mojo::WindowManagerApp* window_manager_app,
               mojo::View* window_container)
      : window_container_(window_container),
        window_manager_app_(window_manager_app) {}
  virtual ~WMFocusRules() {}

 private:
  // Overridden from wm::FocusRules:
  virtual bool IsToplevelWindow(aura::Window* window) const override {
    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
        window_container_;
  }
  virtual bool CanActivateWindow(aura::Window* window) const override {
    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
        window_container_;
  }
  virtual bool CanFocusWindow(aura::Window* window) const override {
    return true;
  }
  virtual aura::Window* GetToplevelWindow(aura::Window* window) const override {
    mojo::View* view = mojo::WindowManagerApp::GetViewForWindow(window);
    while (view->parent() != window_container_) {
      view = view->parent();
      // Unparented hierarchy, there is no "top level" window.
      if (!view)
        return NULL;
    }

    return window_manager_app_->GetWindowForViewId(view->id());
  }
  virtual aura::Window* GetActivatableWindow(
      aura::Window* window) const override {
    return GetToplevelWindow(window);
  }
  virtual aura::Window* GetFocusableWindow(
      aura::Window* window) const override {
    return window;
  }
  virtual aura::Window* GetNextActivatableWindow(
      aura::Window* ignore) const override {
    aura::Window* activatable = GetActivatableWindow(ignore);
    const aura::Window::Windows& children = activatable->parent()->children();
    for (aura::Window::Windows::const_reverse_iterator it = children.rbegin();
         it != children.rend(); ++it) {
      if (*it != ignore)
        return *it;
    }
    return NULL;
  }

  mojo::View* window_container_;
  mojo::WindowManagerApp* window_manager_app_;

  DISALLOW_COPY_AND_ASSIGN(WMFocusRules);
};

}  // namespace

class WindowManagerConnection : public InterfaceImpl<IWindowManager> {
 public:
  explicit WindowManagerConnection(WindowManager* window_manager)
      : window_manager_(window_manager) {}
  virtual ~WindowManagerConnection() {}

 private:
  // Overridden from IWindowManager:
  virtual void CloseWindow(Id view_id) override;
  virtual void ShowKeyboard(Id view_id, RectPtr bounds) override;
  virtual void HideKeyboard(Id view_id) override;

  WindowManager* window_manager_;

  DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection);
};

class NavigatorHostImpl : public InterfaceImpl<NavigatorHost> {
 public:
  explicit NavigatorHostImpl(WindowManager* window_manager, Id view_id)
      : window_manager_(window_manager), view_id_(view_id) {}
  virtual ~NavigatorHostImpl() {
  }

 private:
  virtual void DidNavigateLocally(const mojo::String& url) override;
  virtual void RequestNavigate(Target target, URLRequestPtr request) override;

  WindowManager* window_manager_;
  Id view_id_;

  DISALLOW_COPY_AND_ASSIGN(NavigatorHostImpl);
};

class KeyboardManager : public KeyboardClient,
                        public ViewObserver {
 public:
  KeyboardManager() : view_manager_(NULL), view_(NULL) {
  }
  virtual ~KeyboardManager() {
    if (view_)
      view_->parent()->RemoveObserver(this);
  }

  View* view() { return view_; }

  void Init(ApplicationImpl* application,
            ViewManager* view_manager,
            View* parent,
            const gfx::Rect& bounds) {
    view_manager_ = view_manager;
    view_ = View::Create(view_manager);
    view_->SetBounds(bounds);
    parent->AddChild(view_);
    view_->Embed("mojo:mojo_keyboard");
    application->ConnectToService("mojo:mojo_keyboard", &keyboard_service_);
    keyboard_service_.set_client(this);
    parent->AddObserver(this);
  }

  void Show(Id view_id, const gfx::Rect& bounds) {
    keyboard_service_->SetTarget(view_id);
    view_->SetVisible(true);
  }

  void Hide(Id view_id) {
    keyboard_service_->SetTarget(0);
    view_->SetVisible(false);
  }

 private:
  // KeyboardClient:
  virtual void OnKeyboardEvent(Id view_id,
                               int32_t code,
                               int32_t flags) override {
    View* view = view_manager_->GetViewById(view_id);
    if (!view)
      return;
#if defined(OS_WIN)
    const bool is_char = code != ui::VKEY_BACK && code != ui::VKEY_RETURN;
#else
    const bool is_char = false;
#endif
    if (is_char) {
      view_manager_->DispatchEvent(
          view,
          Event::From(ui::KeyEvent(ui::ET_KEY_PRESSED,
                                   static_cast<ui::KeyboardCode>(code),
                                   flags)));
    } else {
      view_manager_->DispatchEvent(
          view,
          Event::From(ui::KeyEvent(static_cast<base::char16>(code),
                                   static_cast<ui::KeyboardCode>(code),
                                   flags)));
    }
    view_manager_->DispatchEvent(
        view,
        Event::From(ui::KeyEvent(ui::ET_KEY_RELEASED,
                                 static_cast<ui::KeyboardCode>(code),
                                 flags)));
  }

  // Overridden from ViewObserver:
  virtual void OnViewBoundsChanged(View* parent,
                                   const gfx::Rect& old_bounds,
                                   const gfx::Rect& new_bounds) override {
    gfx::Rect keyboard_bounds(view_->bounds());
    keyboard_bounds.set_y(new_bounds.bottom() - keyboard_bounds.height());
    keyboard_bounds.set_width(keyboard_bounds.width() +
                              new_bounds.width() - old_bounds.width());
    view_->SetBounds(keyboard_bounds);
  }
  virtual void OnViewDestroyed(View* parent) override {
    DCHECK_EQ(parent, view_->parent());
    parent->RemoveObserver(this);
    view_ = NULL;
  }

  KeyboardServicePtr keyboard_service_;
  ViewManager* view_manager_;

  // View the keyboard is attached to.
  View* view_;

  DISALLOW_COPY_AND_ASSIGN(KeyboardManager);
};

class RootLayoutManager : public ViewObserver {
 public:
  RootLayoutManager(ViewManager* view_manager,
                    View* root,
                    Id content_view_id,
                    Id launcher_ui_view_id,
                    Id control_panel_view_id)
      : root_(root),
        view_manager_(view_manager),
        content_view_id_(content_view_id),
        launcher_ui_view_id_(launcher_ui_view_id),
        control_panel_view_id_(control_panel_view_id) {}
  virtual ~RootLayoutManager() {
    if (root_)
      root_->RemoveObserver(this);
  }

 private:
  // Overridden from ViewObserver:
  virtual void OnViewBoundsChanged(View* view,
                                   const gfx::Rect& old_bounds,
                                   const gfx::Rect& new_bounds) override {
    DCHECK_EQ(view, root_);

    View* content_view = view_manager_->GetViewById(content_view_id_);
    content_view->SetBounds(new_bounds);

    int delta_width = new_bounds.width() - old_bounds.width();
    int delta_height = new_bounds.height() - old_bounds.height();

    View* launcher_ui_view =
        view_manager_->GetViewById(launcher_ui_view_id_);
    gfx::Rect launcher_ui_bounds(launcher_ui_view->bounds());
    launcher_ui_bounds.set_width(launcher_ui_bounds.width() + delta_width);
    launcher_ui_view->SetBounds(launcher_ui_bounds);

    View* control_panel_view =
        view_manager_->GetViewById(control_panel_view_id_);
    gfx::Rect control_panel_bounds(control_panel_view->bounds());
    control_panel_bounds.set_x(control_panel_bounds.x() + delta_width);
    control_panel_view->SetBounds(control_panel_bounds);

    const View::Children& content_views = content_view->children();
    View::Children::const_iterator iter = content_views.begin();
    for(; iter != content_views.end(); ++iter) {
      View* view = *iter;
      if (view->id() == control_panel_view->id() ||
          view->id() == launcher_ui_view->id())
        continue;
      gfx::Rect view_bounds(view->bounds());
      view_bounds.set_width(view_bounds.width() + delta_width);
      view_bounds.set_height(view_bounds.height() + delta_height);
      view->SetBounds(view_bounds);
    }
  }
  virtual void OnViewDestroyed(View* view) override {
    DCHECK_EQ(view, root_);
    root_->RemoveObserver(this);
    root_ = NULL;
  }

  View* root_;
  ViewManager* view_manager_;
  const Id content_view_id_;
  const Id launcher_ui_view_id_;
  const Id control_panel_view_id_;

  DISALLOW_COPY_AND_ASSIGN(RootLayoutManager);
};

class Window : public InterfaceFactory<NavigatorHost> {
 public:
  Window(WindowManager* window_manager, View* view)
      : window_manager_(window_manager), view_(view) {}

  virtual ~Window() {}

  View* view() const { return view_; }

  void Embed(const std::string& url) {
    scoped_ptr<ServiceProviderImpl> service_provider_impl(
        new ServiceProviderImpl());
    service_provider_impl->AddService<NavigatorHost>(this);
    view_->Embed(url, service_provider_impl.Pass());
  }

 private:
  // InterfaceFactory<NavigatorHost>
  virtual void Create(ApplicationConnection* connection,
                      InterfaceRequest<NavigatorHost> request) override {
    BindToRequest(new NavigatorHostImpl(window_manager_, view_->id()),
                  &request);
  }

  WindowManager* window_manager_;
  View* view_;
};

class WindowManager
    : public ApplicationDelegate,
      public DebugPanel::Delegate,
      public ViewManagerDelegate,
      public WindowManagerDelegate,
      public ui::EventHandler {
 public:
  WindowManager()
      : shell_(nullptr),
        window_manager_factory_(this),
        launcher_ui_(NULL),
        view_manager_(NULL),
        window_manager_app_(new WindowManagerApp(this, this)),
        app_(NULL) {}

  virtual ~WindowManager() {
    // host() may be destroyed by the time we get here.
    // TODO: figure out a way to always cleanly remove handler.
    if (window_manager_app_->host())
      window_manager_app_->host()->window()->RemovePreTargetHandler(this);
  }

  void CloseWindow(Id view_id) {
    WindowVector::iterator iter = GetWindowByViewId(view_id);
    DCHECK(iter != windows_.end());
    Window* window = *iter;
    windows_.erase(iter);
    window->view()->Destroy();
  }

  void ShowKeyboard(Id view_id, const gfx::Rect& bounds) {
    // TODO: this needs to validate |view_id|. That is, it shouldn't assume
    // |view_id| is valid and it also needs to make sure the client that sent
    // this really owns |view_id|.
    // TODO: honor |bounds|.
    if (!keyboard_manager_) {
      keyboard_manager_.reset(new KeyboardManager);
      View* parent = view_manager_->GetRoots().back();
      int ideal_height = 200;
      // TODO(sky): 10 is a bit of a hack here. There is a bug that causes
      // white strips to appear when 0 is used. Figure this out!
      const gfx::Rect keyboard_bounds(
          10, parent->bounds().height() - ideal_height,
          parent->bounds().width() - 20, ideal_height);
      keyboard_manager_->Init(app_, view_manager_, parent, keyboard_bounds);
    }
    keyboard_manager_->Show(view_id, bounds);
  }

  void HideKeyboard(Id view_id) {
    // See comment in ShowKeyboard() about validating args.
    if (keyboard_manager_)
      keyboard_manager_->Hide(view_id);
  }

  void DidNavigateLocally(uint32 source_view_id, const mojo::String& url) {
    LOG(ERROR) << "DidNavigateLocally: source_view_id: " << source_view_id
               << " url: " << url.To<std::string>();
  }

  // Overridden from DebugPanel::Delegate:
  virtual void CloseTopWindow() override {
    if (!windows_.empty())
      CloseWindow(windows_.back()->view()->id());
  }

  virtual void RequestNavigate(uint32 source_view_id,
                               Target target,
                               URLRequestPtr request) override {
    OnLaunch(source_view_id, target, request->url);
  }

 private:
  typedef std::vector<Window*> WindowVector;

  // Overridden from ApplicationDelegate:
  virtual void Initialize(ApplicationImpl* app) override {
    shell_ = app->shell();
    app_ = app;
    views_init_.reset(new ViewsInit);
    window_manager_app_->Initialize(app);
  }

  virtual bool ConfigureIncomingConnection(
      ApplicationConnection* connection) override {
    connection->AddService(&window_manager_factory_);
    window_manager_app_->ConfigureIncomingConnection(connection);
    return true;
  }

  // Overridden from ViewManagerDelegate:
  virtual void OnEmbed(ViewManager* view_manager,
                       View* root,
                       ServiceProviderImpl* exported_services,
                       scoped_ptr<ServiceProvider> imported_services) override {
    DCHECK(!view_manager_);
    view_manager_ = view_manager;

    View* view = View::Create(view_manager_);
    root->AddChild(view);
    view->SetBounds(gfx::Rect(root->bounds().size()));
    content_view_id_ = view->id();

    Id launcher_ui_id = CreateLauncherUI();
    Id control_panel_id = CreateControlPanel(view);

    root_layout_manager_.reset(
        new RootLayoutManager(view_manager, root,
                              content_view_id_,
                              launcher_ui_id,
                              control_panel_id));
    root->AddObserver(root_layout_manager_.get());

    window_manager_app_->host()->window()->AddPreTargetHandler(this);

    window_manager_app_->InitFocus(new WMFocusRules(window_manager_app_.get(),
                                                    view));
  }
  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
    DCHECK_EQ(view_manager_, view_manager);
    view_manager_ = NULL;
    base::MessageLoop::current()->Quit();
  }

  // Overridden from WindowManagerDelegate:
  virtual void Embed(
      const String& url,
      InterfaceRequest<ServiceProvider> service_provider) override {
    const Id kInvalidSourceViewId = 0;
    OnLaunch(kInvalidSourceViewId, TARGET_DEFAULT, url);
  }
  virtual void DispatchEvent(EventPtr event) override {}

  // Overridden from ui::EventHandler:
  virtual void OnEvent(ui::Event* event) override {
    View* view = WindowManagerApp::GetViewForWindow(
        static_cast<aura::Window*>(event->target()));
    if (event->type() == ui::ET_MOUSE_PRESSED &&
        !IsDescendantOfKeyboard(view)) {
      view->SetFocus();
    }
  }

  void OnLaunch(uint32 source_view_id,
                Target requested_target,
                const mojo::String& url) {
    Target target = debug_panel_->navigation_target();
    if (target == TARGET_DEFAULT) {
      if (requested_target != TARGET_DEFAULT) {
        target = requested_target;
      } else {
        // TODO(aa): Should be TARGET_NEW_NODE if source origin and dest origin
        // are different?
        target = TARGET_SOURCE_NODE;
      }
    }

    Window* dest_view = NULL;
    if (target == TARGET_SOURCE_NODE) {
      WindowVector::iterator source_view = GetWindowByViewId(source_view_id);
      bool app_initiated = source_view != windows_.end();
      if (app_initiated)
        dest_view = *source_view;
      else if (!windows_.empty())
        dest_view = windows_.back();
    }

    if (!dest_view) {
      dest_view = CreateWindow();
      windows_.push_back(dest_view);
    }

    dest_view->Embed(url);
  }

  // TODO(beng): proper layout manager!!
  Id CreateLauncherUI() {
    View* view = view_manager_->GetViewById(content_view_id_);
    gfx::Rect bounds = view->bounds();
    bounds.Inset(kBorderInset, kBorderInset);
    bounds.set_height(kTextfieldHeight);
    launcher_ui_ = CreateWindow(bounds);
    launcher_ui_->Embed("mojo:mojo_browser");
    return launcher_ui_->view()->id();
  }

  Window* CreateWindow() {
    View* view = view_manager_->GetViewById(content_view_id_);
    gfx::Rect bounds(kBorderInset,
                     2 * kBorderInset + kTextfieldHeight,
                     view->bounds().width() - 3 * kBorderInset -
                         kControlPanelWidth,
                     view->bounds().height() -
                         (3 * kBorderInset + kTextfieldHeight));
    if (!windows_.empty()) {
      gfx::Point position = windows_.back()->view()->bounds().origin();
      position.Offset(35, 35);
      bounds.set_origin(position);
    }
    return CreateWindow(bounds);
  }

  Window* CreateWindow(const gfx::Rect& bounds) {
    View* content = view_manager_->GetViewById(content_view_id_);
    View* view = View::Create(view_manager_);
    content->AddChild(view);
    view->SetBounds(bounds);
    view->SetFocus();
    return new Window(this, view);
  }

  bool IsDescendantOfKeyboard(View* target) {
    return keyboard_manager_.get() &&
        keyboard_manager_->view()->Contains(target);
  }

  Id CreateControlPanel(View* root) {
    View* view = View::Create(view_manager_);
    root->AddChild(view);

    gfx::Rect bounds(root->bounds().width() - kControlPanelWidth -
                         kBorderInset,
                     kBorderInset * 2 + kTextfieldHeight,
                     kControlPanelWidth,
                     root->bounds().height() - kBorderInset * 3 -
                         kTextfieldHeight);
    view->SetBounds(bounds);

    debug_panel_ = new DebugPanel(this, shell_, view);
    return view->id();
  }

  WindowVector::iterator GetWindowByViewId(Id view_id) {
    for (std::vector<Window*>::iterator iter = windows_.begin();
         iter != windows_.end();
         ++iter) {
      if ((*iter)->view()->id() == view_id) {
        return iter;
      }
    }
    return windows_.end();
  }

  Shell* shell_;

  InterfaceFactoryImplWithContext<WindowManagerConnection, WindowManager>
      window_manager_factory_;

  scoped_ptr<ViewsInit> views_init_;
  DebugPanel* debug_panel_;
  Window* launcher_ui_;
  WindowVector windows_;
  ViewManager* view_manager_;
  scoped_ptr<RootLayoutManager> root_layout_manager_;

  scoped_ptr<WindowManagerApp> window_manager_app_;

  // Id of the view most content is added to. The keyboard is NOT added here.
  Id content_view_id_;

  scoped_ptr<KeyboardManager> keyboard_manager_;
  ApplicationImpl* app_;

  DISALLOW_COPY_AND_ASSIGN(WindowManager);
};

void WindowManagerConnection::CloseWindow(Id view_id) {
  window_manager_->CloseWindow(view_id);
}

void WindowManagerConnection::ShowKeyboard(Id view_id, RectPtr bounds) {
  window_manager_->ShowKeyboard(view_id, bounds.To<gfx::Rect>());
}

void WindowManagerConnection::HideKeyboard(Id view_id) {
  window_manager_->HideKeyboard(view_id);
}

void NavigatorHostImpl::DidNavigateLocally(const mojo::String& url) {
  window_manager_->DidNavigateLocally(view_id_, url);
}

void NavigatorHostImpl::RequestNavigate(Target target, URLRequestPtr request) {
  window_manager_->RequestNavigate(view_id_, target, request.Pass());
}

}  // namespace examples
}  // namespace mojo

MojoResult MojoMain(MojoHandle shell_handle) {
  mojo::ApplicationRunnerChromium runner(new mojo::examples::WindowManager);
  return runner.Run(shell_handle);
}
