// Copyright 2015 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/mus/user_window_controller_impl.h"

#include "ash/common/shell_window_ids.h"
#include "ash/mus/bridge/wm_window_mus.h"
#include "ash/mus/property_util.h"
#include "ash/mus/root_window_controller.h"
#include "ash/public/interfaces/container.mojom.h"
#include "components/mus/public/cpp/property_type_converters.h"
#include "components/mus/public/cpp/window.h"
#include "components/mus/public/cpp/window_property.h"
#include "components/mus/public/cpp/window_tree_client.h"
#include "mojo/common/common_type_converters.h"
#include "ui/resources/grit/ui_resources.h"

MUS_DECLARE_WINDOW_PROPERTY_TYPE(uint32_t)

namespace {

// Key used for storing identifier sent to clients for windows.
MUS_DEFINE_LOCAL_WINDOW_PROPERTY_KEY(uint32_t, kUserWindowIdKey, 0u);

}  // namespace

namespace ash {
namespace mus {

namespace {

// Returns |window|, or an ancestor thereof, parented to |container|, or null.
::mus::Window* GetTopLevelWindow(::mus::Window* window,
                                 ::mus::Window* container) {
  while (window && window->parent() != container)
    window = window->parent();
  return window;
}

// Get a UserWindow struct from a mus::Window.
mojom::UserWindowPtr GetUserWindow(::mus::Window* window) {
  mojom::UserWindowPtr user_window(mojom::UserWindow::New());
  DCHECK_NE(0u, window->GetLocalProperty(kUserWindowIdKey));
  user_window->window_id = window->GetLocalProperty(kUserWindowIdKey);
  user_window->window_title = mojo::String::From(GetWindowTitle(window));
  user_window->window_app_icon = GetWindowAppIcon(window);
  user_window->window_app_id = mojo::String::From(GetAppID(window));
  user_window->ignored_by_shelf = GetWindowIgnoredByShelf(window);
  ::mus::Window* focused = window->window_tree()->GetFocusedWindow();
  focused = GetTopLevelWindow(focused, window->parent());
  user_window->window_has_focus = focused == window;
  return user_window;
}

}  // namespace

// Observes property changes on user windows. UserWindowControllerImpl uses
// this separate observer to avoid observing duplicate tree change
// notifications.
class WindowPropertyObserver : public ::mus::WindowObserver {
 public:
  explicit WindowPropertyObserver(UserWindowControllerImpl* controller)
      : controller_(controller) {}
  ~WindowPropertyObserver() override {}

 private:
  // mus::WindowObserver:
  void OnWindowSharedPropertyChanged(
      ::mus::Window* window,
      const std::string& name,
      const std::vector<uint8_t>* old_data,
      const std::vector<uint8_t>* new_data) override {
    if (!controller_->user_window_observer())
      return;
    if (name == ::mus::mojom::WindowManager::kWindowTitle_Property) {
      controller_->user_window_observer()->OnUserWindowTitleChanged(
          window->GetLocalProperty(kUserWindowIdKey),
          mojo::String::From(GetWindowTitle(window)));
    } else if (name == ::mus::mojom::WindowManager::kWindowAppIcon_Property) {
      controller_->user_window_observer()->OnUserWindowAppIconChanged(
          window->GetLocalProperty(kUserWindowIdKey),
          new_data ? mojo::Array<uint8_t>::From(*new_data)
                   : mojo::Array<uint8_t>());
    }
  }

  UserWindowControllerImpl* controller_;
  DISALLOW_COPY_AND_ASSIGN(WindowPropertyObserver);
};

UserWindowControllerImpl::UserWindowControllerImpl()
    : root_controller_(nullptr) {}

UserWindowControllerImpl::~UserWindowControllerImpl() {
  if (!root_controller_)
    return;

  ::mus::Window* user_container = GetUserWindowContainer();
  if (!user_container)
    return;

  RemoveObservers(user_container);
}

void UserWindowControllerImpl::Initialize(
    RootWindowController* root_controller) {
  DCHECK(root_controller);
  DCHECK(!root_controller_);
  root_controller_ = root_controller;
  GetUserWindowContainer()->AddObserver(this);
  GetUserWindowContainer()->window_tree()->AddObserver(this);
  window_property_observer_.reset(new WindowPropertyObserver(this));
  for (::mus::Window* window : GetUserWindowContainer()->children()) {
    AssignIdIfNecessary(window);
    window->AddObserver(window_property_observer_.get());
  }
}

void UserWindowControllerImpl::AssignIdIfNecessary(::mus::Window* window) {
  if (window->GetLocalProperty(kUserWindowIdKey) == 0u)
    window->SetLocalProperty(kUserWindowIdKey, next_id_++);
}

void UserWindowControllerImpl::RemoveObservers(::mus::Window* user_container) {
  user_container->RemoveObserver(this);
  user_container->window_tree()->RemoveObserver(this);
  for (auto iter : user_container->children())
    iter->RemoveObserver(window_property_observer_.get());
}

::mus::Window* UserWindowControllerImpl::GetUserWindowById(uint32_t id) {
  for (::mus::Window* window : GetUserWindowContainer()->children()) {
    if (window->GetLocalProperty(kUserWindowIdKey) == id)
      return window;
  }
  return nullptr;
}

::mus::Window* UserWindowControllerImpl::GetUserWindowContainer() const {
  WmWindowMus* window = root_controller_->GetWindowByShellWindowId(
      kShellWindowId_DefaultContainer);
  return window ? window->mus_window() : nullptr;
}

void UserWindowControllerImpl::OnTreeChanging(const TreeChangeParams& params) {
  DCHECK(root_controller_);
  if (params.new_parent == GetUserWindowContainer()) {
    params.target->AddObserver(window_property_observer_.get());
    AssignIdIfNecessary(params.target);
    if (user_window_observer_)
      user_window_observer_->OnUserWindowAdded(GetUserWindow(params.target));
  } else if (params.old_parent == GetUserWindowContainer()) {
    params.target->RemoveObserver(window_property_observer_.get());
    if (user_window_observer_)
      user_window_observer_->OnUserWindowRemoved(
          params.target->GetLocalProperty(kUserWindowIdKey));
  }
}

void UserWindowControllerImpl::OnWindowDestroying(::mus::Window* window) {
  if (window == GetUserWindowContainer())
    RemoveObservers(window);
}

void UserWindowControllerImpl::OnWindowTreeFocusChanged(
    ::mus::Window* gained_focus,
    ::mus::Window* lost_focus) {
  if (!user_window_observer_)
    return;

  // Treat focus in the user window hierarchy as focus of the top-level window.
  gained_focus = GetTopLevelWindow(gained_focus, GetUserWindowContainer());
  lost_focus = GetTopLevelWindow(lost_focus, GetUserWindowContainer());
  if (gained_focus == lost_focus)
    return;

  if (lost_focus) {
    user_window_observer_->OnUserWindowFocusChanged(
        lost_focus->GetLocalProperty(kUserWindowIdKey), false);
  }
  if (gained_focus) {
    user_window_observer_->OnUserWindowFocusChanged(
        gained_focus->GetLocalProperty(kUserWindowIdKey), true);
  }
}

void UserWindowControllerImpl::AddUserWindowObserver(
    mojom::UserWindowObserverPtr observer) {
  // TODO(msw): Support multiple observers.
  user_window_observer_ = std::move(observer);

  const ::mus::Window::Children& windows = GetUserWindowContainer()->children();
  mojo::Array<mojom::UserWindowPtr> user_windows =
      mojo::Array<mojom::UserWindowPtr>::New(windows.size());
  for (size_t i = 0; i < windows.size(); ++i)
    user_windows[i] = GetUserWindow(windows[i]);
  user_window_observer_->OnUserWindowObserverAdded(std::move(user_windows));
}

void UserWindowControllerImpl::FocusUserWindow(uint32_t window_id) {
  ::mus::Window* window = GetUserWindowById(window_id);
  if (window)
    window->SetFocus();
}

}  // namespace mus
}  // namespace ash
