// 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 "ui/aura/local/window_port_local.h"

#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/layout.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"

namespace aura {
namespace {

class ScopedCursorHider {
 public:
  explicit ScopedCursorHider(Window* window)
      : window_(window), hid_cursor_(false) {
    if (!window_->IsRootWindow())
      return;
    const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
        Env::GetInstance()->last_mouse_location());
    client::CursorClient* cursor_client = client::GetCursorClient(window_);
    if (cursor_is_in_bounds && cursor_client &&
        cursor_client->IsCursorVisible()) {
      cursor_client->HideCursor();
      hid_cursor_ = true;
    }
  }
  ~ScopedCursorHider() {
    if (!window_->IsRootWindow())
      return;

    // Update the device scale factor of the cursor client only when the last
    // mouse location is on this root window.
    if (hid_cursor_) {
      client::CursorClient* cursor_client = client::GetCursorClient(window_);
      if (cursor_client) {
        const display::Display& display =
            display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
        cursor_client->SetDisplay(display);
        cursor_client->ShowCursor();
      }
    }
  }

 private:
  Window* window_;
  bool hid_cursor_;

  DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
};

}  // namespace

WindowPortLocal::WindowPortLocal(Window* window)
    : window_(window), weak_factory_(this) {}

WindowPortLocal::~WindowPortLocal() {}

void WindowPortLocal::OnPreInit(Window* window) {}

void WindowPortLocal::OnDeviceScaleFactorChanged(
    float old_device_scale_factor,
    float new_device_scale_factor) {
  if (last_device_scale_factor_ != new_device_scale_factor &&
      local_surface_id_.is_valid()) {
    last_device_scale_factor_ = new_device_scale_factor;
    local_surface_id_ = local_surface_id_allocator_.GenerateId();
    if (frame_sink_)
      frame_sink_->SetLocalSurfaceId(local_surface_id_);
  }

  ScopedCursorHider hider(window_);
  if (window_->delegate()) {
    window_->delegate()->OnDeviceScaleFactorChanged(old_device_scale_factor,
                                                    new_device_scale_factor);
  }
}

void WindowPortLocal::OnWillAddChild(Window* child) {}

void WindowPortLocal::OnWillRemoveChild(Window* child) {}

void WindowPortLocal::OnWillMoveChild(size_t current_index, size_t dest_index) {
}

void WindowPortLocal::OnVisibilityChanged(bool visible) {}

void WindowPortLocal::OnDidChangeBounds(const gfx::Rect& old_bounds,
                                        const gfx::Rect& new_bounds) {
  if (last_size_ != new_bounds.size() && local_surface_id_.is_valid()) {
    last_size_ = new_bounds.size();
    local_surface_id_ = local_surface_id_allocator_.GenerateId();
    if (frame_sink_)
      frame_sink_->SetLocalSurfaceId(local_surface_id_);
  }
}

void WindowPortLocal::OnDidChangeTransform(
    const gfx::Transform& old_transform,
    const gfx::Transform& new_transform) {}

std::unique_ptr<ui::PropertyData> WindowPortLocal::OnWillChangeProperty(
    const void* key) {
  return nullptr;
}

void WindowPortLocal::OnPropertyChanged(
    const void* key,
    int64_t old_value,
    std::unique_ptr<ui::PropertyData> data) {}

std::unique_ptr<cc::LayerTreeFrameSink>
WindowPortLocal::CreateLayerTreeFrameSink() {
  DCHECK(!frame_sink_id_.is_valid());
  auto* context_factory_private =
      aura::Env::GetInstance()->context_factory_private();
  frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
  auto frame_sink = std::make_unique<LayerTreeFrameSinkLocal>(
      frame_sink_id_, context_factory_private->GetHostFrameSinkManager(),
      window_->GetName());
  frame_sink->SetSurfaceChangedCallback(base::Bind(
      &WindowPortLocal::OnSurfaceChanged, weak_factory_.GetWeakPtr()));
  frame_sink_ = frame_sink->GetWeakPtr();
  AllocateLocalSurfaceId();
  if (window_->GetRootWindow())
    window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
  return std::move(frame_sink);
}

viz::SurfaceId WindowPortLocal::GetSurfaceId() const {
  return viz::SurfaceId(frame_sink_id_, local_surface_id_);
}

void WindowPortLocal::AllocateLocalSurfaceId() {
  last_device_scale_factor_ = ui::GetScaleFactorForNativeView(window_);
  last_size_ = window_->bounds().size();
  local_surface_id_ = local_surface_id_allocator_.GenerateId();
  if (frame_sink_)
    frame_sink_->SetLocalSurfaceId(local_surface_id_);
}

const viz::LocalSurfaceId& WindowPortLocal::GetLocalSurfaceId() {
  if (!local_surface_id_.is_valid())
    AllocateLocalSurfaceId();
  return local_surface_id_;
}

viz::FrameSinkId WindowPortLocal::GetFrameSinkId() const {
  return frame_sink_id_;
}

void WindowPortLocal::OnWindowAddedToRootWindow() {
  if (frame_sink_id_.is_valid())
    window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
}

void WindowPortLocal::OnWillRemoveWindowFromRootWindow() {
  if (frame_sink_id_.is_valid())
    window_->layer()->GetCompositor()->RemoveFrameSink(frame_sink_id_);
}

void WindowPortLocal::OnEventTargetingPolicyChanged() {}

void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
  DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_);
  DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
  scoped_refptr<viz::SurfaceReferenceFactory> reference_factory =
      aura::Env::GetInstance()
          ->context_factory_private()
          ->GetFrameSinkManager()
          ->surface_manager()
          ->reference_factory();
  window_->layer()->SetShowPrimarySurface(
      surface_info.id(), window_->bounds().size(), reference_factory);
  window_->layer()->SetFallbackSurfaceId(surface_info.id());
}

bool WindowPortLocal::ShouldRestackTransientChildren() {
  return true;
}

}  // namespace aura
