// 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 "components/mus/ws/platform_display.h"

#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/shared_quad_state.h"
#include "cc/quads/surface_draw_quad.h"
#include "components/mus/gles2/gpu_state.h"
#include "components/mus/public/interfaces/gpu.mojom.h"
#include "components/mus/public/interfaces/quads.mojom.h"
#include "components/mus/surfaces/display_compositor.h"
#include "components/mus/surfaces/surfaces_state.h"
#include "components/mus/ws/platform_display_factory.h"
#include "components/mus/ws/server_window.h"
#include "components/mus/ws/server_window_surface.h"
#include "components/mus/ws/server_window_surface_manager.h"
#include "components/mus/ws/window_coordinate_conversions.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
#include "mojo/converters/input_events/input_events_type_converters.h"
#include "mojo/converters/input_events/mojo_extended_key_event_data.h"
#include "mojo/converters/surfaces/surfaces_type_converters.h"
#include "mojo/converters/surfaces/surfaces_utils.h"
#include "mojo/converters/transform/transform_type_converters.h"
#include "services/shell/public/cpp/connection.h"
#include "services/shell/public/cpp/connector.h"
#include "third_party/skia/include/core/SkXfermode.h"
#include "ui/base/cursor/cursor_loader.h"
#include "ui/display/display.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/platform_window/platform_ime_controller.h"
#include "ui/platform_window/platform_window.h"

#if defined(OS_WIN)
#include "ui/platform_window/win/win_window.h"
#elif defined(USE_X11)
#include "ui/platform_window/x11/x11_window.h"
#elif defined(OS_ANDROID)
#include "ui/platform_window/android/platform_window_android.h"
#elif defined(USE_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif

using mojo::Rect;
using mojo::Size;

namespace mus {

namespace ws {
namespace {

// DrawWindowTree recursively visits ServerWindows, creating a SurfaceDrawQuad
// for each that lacks one. A ServerWindow may hold a CompositorFrame that
// references other ServerWindows in SurfaceDrawQuads. We should not create new
// SurfaceDrawQuads for these |referenced_window_ids|. Instead,
// cc::SurfaceAggregator will do the heavy lifting here by expanding those
// references to generate one top-level display CompositorFrame.
void DrawWindowTree(cc::RenderPass* pass,
                    ServerWindow* window,
                    const gfx::Vector2d& parent_to_root_origin_offset,
                    float opacity,
                    std::set<WindowId>* referenced_window_ids) {
  if (!window->visible())
    return;

  ServerWindowSurface* default_surface =
      window->surface_manager() ? window->surface_manager()->GetDefaultSurface()
                                : nullptr;

  if (default_surface) {
    // Accumulate referenced windows in each ServerWindow's CompositorFrame.
    referenced_window_ids->insert(
        default_surface->referenced_window_ids().begin(),
        default_surface->referenced_window_ids().end());
  }

  const gfx::Rect absolute_bounds =
      window->bounds() + parent_to_root_origin_offset;
  std::vector<ServerWindow*> children(window->GetChildren());
  // TODO(rjkroege, fsamuel): Make sure we're handling alpha correctly.
  const float combined_opacity = opacity * window->opacity();
  for (auto it = children.rbegin(); it != children.rend(); ++it) {
    DrawWindowTree(pass, *it, absolute_bounds.OffsetFromOrigin(),
                   combined_opacity, referenced_window_ids);
  }

  if (!window->surface_manager() || !window->surface_manager()->ShouldDraw())
    return;

  // If an ancestor has already referenced this window, then we do not need
  // to create a SurfaceDrawQuad for it.
  const bool draw_default_surface =
      default_surface && (referenced_window_ids->count(window->id()) == 0);

  ServerWindowSurface* underlay_surface =
      window->surface_manager()->GetUnderlaySurface();
  if (!draw_default_surface && !underlay_surface)
    return;

  if (draw_default_surface) {
    gfx::Transform quad_to_target_transform;
    quad_to_target_transform.Translate(absolute_bounds.x(),
                                       absolute_bounds.y());

    cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();

    const gfx::Rect bounds_at_origin(window->bounds().size());
    // TODO(fsamuel): These clipping and visible rects are incorrect. They need
    // to be populated from CompositorFrame structs.
    sqs->SetAll(quad_to_target_transform,
                bounds_at_origin.size() /* layer_bounds */,
                bounds_at_origin /* visible_layer_bounds */,
                bounds_at_origin /* clip_rect */, false /* is_clipped */,
                window->opacity(), SkXfermode::kSrcOver_Mode,
                0 /* sorting-context_id */);
    auto quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
    quad->SetAll(sqs, bounds_at_origin /* rect */,
                 gfx::Rect() /* opaque_rect */,
                 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
                 default_surface->id());
  }
  if (underlay_surface) {
    const gfx::Rect underlay_absolute_bounds =
        absolute_bounds - window->underlay_offset();
    gfx::Transform quad_to_target_transform;
    quad_to_target_transform.Translate(underlay_absolute_bounds.x(),
                                       underlay_absolute_bounds.y());
    cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
    const gfx::Rect bounds_at_origin(
        underlay_surface->last_submitted_frame_size());
    sqs->SetAll(quad_to_target_transform,
                bounds_at_origin.size() /* layer_bounds */,
                bounds_at_origin /* visible_layer_bounds */,
                bounds_at_origin /* clip_rect */, false /* is_clipped */,
                window->opacity(), SkXfermode::kSrcOver_Mode,
                0 /* sorting-context_id */);

    auto quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
    quad->SetAll(sqs, bounds_at_origin /* rect */,
                 gfx::Rect() /* opaque_rect */,
                 bounds_at_origin /* visible_rect */, true /* needs_blending*/,
                 underlay_surface->id());
  }
}

}  // namespace

// static
PlatformDisplayFactory* PlatformDisplay::factory_ = nullptr;

// static
PlatformDisplay* PlatformDisplay::Create(
    const PlatformDisplayInitParams& init_params) {
  if (factory_)
    return factory_->CreatePlatformDisplay();

  return new DefaultPlatformDisplay(init_params);
}

DefaultPlatformDisplay::DefaultPlatformDisplay(
    const PlatformDisplayInitParams& init_params)
    : connector_(init_params.connector),
      gpu_state_(init_params.gpu_state),
      surfaces_state_(init_params.surfaces_state),
      delegate_(nullptr),
      draw_timer_(false, false),
      frame_pending_(false),
#if !defined(OS_ANDROID)
      cursor_loader_(ui::CursorLoader::Create()),
#endif
      weak_factory_(this) {
  metrics_.size_in_pixels = mojo::Size::New();
  metrics_.size_in_pixels->width = init_params.display_bounds.width();
  metrics_.size_in_pixels->height = init_params.display_bounds.height();
  // TODO(rjkroege): Preserve the display_id when Ozone platform can use it.
}

void DefaultPlatformDisplay::Init(PlatformDisplayDelegate* delegate) {
  delegate_ = delegate;

  gfx::Rect bounds(metrics_.size_in_pixels.To<gfx::Size>());
#if defined(OS_WIN)
  platform_window_.reset(new ui::WinWindow(this, bounds));
#elif defined(USE_X11)
  platform_window_.reset(new ui::X11Window(this));
#elif defined(OS_ANDROID)
  platform_window_.reset(new ui::PlatformWindowAndroid(this));
#elif defined(USE_OZONE)
  platform_window_ =
      ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
#else
  NOTREACHED() << "Unsupported platform";
#endif
  platform_window_->SetBounds(bounds);
  platform_window_->Show();
}

DefaultPlatformDisplay::~DefaultPlatformDisplay() {
  // Don't notify the delegate from the destructor.
  delegate_ = nullptr;

  // Invalidate WeakPtrs now to avoid callbacks back into the
  // DefaultPlatformDisplay during destruction of |display_compositor_|.
  weak_factory_.InvalidateWeakPtrs();
  display_compositor_.reset();
  // Destroy the PlatformWindow early on as it may call us back during
  // destruction and we want to be in a known state. But destroy the surface
  // first because it can still be using the platform window.
  platform_window_.reset();
}

void DefaultPlatformDisplay::SchedulePaint(const ServerWindow* window,
                                           const gfx::Rect& bounds) {
  DCHECK(window);
  if (!window->IsDrawn())
    return;
  const gfx::Rect root_relative_rect =
      ConvertRectBetweenWindows(window, delegate_->GetRootWindow(), bounds);
  if (root_relative_rect.IsEmpty())
    return;
  dirty_rect_.Union(root_relative_rect);
  WantToDraw();
}

void DefaultPlatformDisplay::SetViewportSize(const gfx::Size& size) {
  platform_window_->SetBounds(gfx::Rect(size));
}

void DefaultPlatformDisplay::SetTitle(const base::string16& title) {
  platform_window_->SetTitle(title);
}

void DefaultPlatformDisplay::SetCapture() {
  platform_window_->SetCapture();
}

void DefaultPlatformDisplay::ReleaseCapture() {
  platform_window_->ReleaseCapture();
}

void DefaultPlatformDisplay::SetCursorById(int32_t cursor_id) {
#if !defined(OS_ANDROID)
  // TODO(erg): This still isn't sufficient, and will only use native cursors
  // that chrome would use, not custom image cursors. For that, we should
  // delegate to the window manager to load images from resource packs.
  //
  // We probably also need to deal with different DPIs.
  ui::Cursor cursor(cursor_id);
  cursor_loader_->SetPlatformCursor(&cursor);
  platform_window_->SetCursor(cursor.platform());
#endif
}

const mojom::ViewportMetrics& DefaultPlatformDisplay::GetViewportMetrics() {
  return metrics_;
}

mojom::Rotation DefaultPlatformDisplay::GetRotation() {
  // TODO(sky): implement me.
  return mojom::Rotation::VALUE_0;
}

void DefaultPlatformDisplay::UpdateTextInputState(
    const ui::TextInputState& state) {
  ui::PlatformImeController* ime = platform_window_->GetPlatformImeController();
  if (ime)
    ime->UpdateTextInputState(state);
}

void DefaultPlatformDisplay::SetImeVisibility(bool visible) {
  ui::PlatformImeController* ime = platform_window_->GetPlatformImeController();
  if (ime)
    ime->SetImeVisibility(visible);
}

void DefaultPlatformDisplay::Draw() {
  if (!delegate_->GetRootWindow()->visible())
    return;

  // TODO(fsamuel): We should add a trace for generating a top level frame.
  std::unique_ptr<cc::CompositorFrame> frame(GenerateCompositorFrame());
  frame_pending_ = true;
  if (display_compositor_) {
    display_compositor_->SubmitCompositorFrame(
        std::move(frame), base::Bind(&DefaultPlatformDisplay::DidDraw,
                                     weak_factory_.GetWeakPtr()));
  }
  dirty_rect_ = gfx::Rect();
}

void DefaultPlatformDisplay::DidDraw(cc::SurfaceDrawStatus status) {
  frame_pending_ = false;
  delegate_->OnCompositorFrameDrawn();
  if (!dirty_rect_.IsEmpty())
    WantToDraw();
}

bool DefaultPlatformDisplay::IsFramePending() const {
  return frame_pending_;
}

void DefaultPlatformDisplay::WantToDraw() {
  if (draw_timer_.IsRunning() || frame_pending_)
    return;

  // TODO(rjkroege): Use vblank to kick off Draw.
  draw_timer_.Start(
      FROM_HERE, base::TimeDelta(),
      base::Bind(&DefaultPlatformDisplay::Draw, weak_factory_.GetWeakPtr()));
}

void DefaultPlatformDisplay::UpdateMetrics(const gfx::Size& size,
                                           float device_pixel_ratio) {
  if (display::Display::HasForceDeviceScaleFactor())
    device_pixel_ratio = display::Display::GetForcedDeviceScaleFactor();
  if (metrics_.size_in_pixels.To<gfx::Size>() == size &&
      metrics_.device_pixel_ratio == device_pixel_ratio)
    return;
  mojom::ViewportMetrics old_metrics;
  old_metrics.size_in_pixels = metrics_.size_in_pixels.Clone();
  old_metrics.device_pixel_ratio = metrics_.device_pixel_ratio;

  metrics_.size_in_pixels = mojo::Size::From(size);
  metrics_.device_pixel_ratio = device_pixel_ratio;

  delegate_->OnViewportMetricsChanged(old_metrics, metrics_);
}

std::unique_ptr<cc::CompositorFrame>
DefaultPlatformDisplay::GenerateCompositorFrame() {
  std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
  render_pass->damage_rect = dirty_rect_;
  render_pass->output_rect = gfx::Rect(metrics_.size_in_pixels.To<gfx::Size>());

  std::set<WindowId> referenced_window_ids;
  DrawWindowTree(render_pass.get(), delegate_->GetRootWindow(), gfx::Vector2d(),
                 1.0f, &referenced_window_ids);

  std::unique_ptr<cc::DelegatedFrameData> frame_data(
      new cc::DelegatedFrameData);
  frame_data->device_scale_factor = metrics_.device_pixel_ratio;
  frame_data->render_pass_list.push_back(std::move(render_pass));

  std::unique_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
  frame->delegated_frame_data = std::move(frame_data);
  return frame;
}

void DefaultPlatformDisplay::OnBoundsChanged(const gfx::Rect& new_bounds) {
  UpdateMetrics(new_bounds.size(), metrics_.device_pixel_ratio);
}

void DefaultPlatformDisplay::OnDamageRect(const gfx::Rect& damaged_region) {
  dirty_rect_.Union(damaged_region);
  WantToDraw();
}

void DefaultPlatformDisplay::DispatchEvent(ui::Event* event) {
  if (event->IsScrollEvent()) {
    // TODO(moshayedi): crbug.com/602859. Dispatch scroll events as
    // they are once we have proper support for scroll events.
    delegate_->OnEvent(ui::MouseWheelEvent(*event->AsScrollEvent()));
  } else if (event->IsMouseEvent() && !event->IsMouseWheelEvent()) {
    delegate_->OnEvent(ui::PointerEvent(*event->AsMouseEvent()));
  } else if (event->IsTouchEvent()) {
    delegate_->OnEvent(ui::PointerEvent(*event->AsTouchEvent()));
  } else {
    delegate_->OnEvent(*event);
  }

#if defined(USE_X11) || defined(USE_OZONE)
  // We want to emulate the WM_CHAR generation behaviour of Windows.
  //
  // On Linux, we've previously inserted characters by having
  // InputMethodAuraLinux take all key down events and send a character event
  // to the TextInputClient. This causes a mismatch in code that has to be
  // shared between Windows and Linux, including blink code. Now that we're
  // trying to have one way of doing things, we need to standardize on and
  // emulate Windows character events.
  //
  // This is equivalent to what we're doing in the current Linux port, but
  // done once instead of done multiple times in different places.
  if (event->type() == ui::ET_KEY_PRESSED) {
    ui::KeyEvent* key_press_event = event->AsKeyEvent();
    ui::KeyEvent char_event(key_press_event->GetCharacter(),
                            key_press_event->key_code(),
                            key_press_event->flags());
    DCHECK_EQ(key_press_event->GetCharacter(), char_event.GetCharacter());
    DCHECK_EQ(key_press_event->key_code(), char_event.key_code());
    DCHECK_EQ(key_press_event->flags(), char_event.flags());
    delegate_->OnEvent(char_event);
  }
#endif
}

void DefaultPlatformDisplay::OnCloseRequest() {
  platform_window_->Close();
}

void DefaultPlatformDisplay::OnClosed() {
  if (delegate_)
    delegate_->OnDisplayClosed();
}

void DefaultPlatformDisplay::OnWindowStateChanged(
    ui::PlatformWindowState new_state) {}

void DefaultPlatformDisplay::OnLostCapture() {
  delegate_->OnNativeCaptureLost();
}

void DefaultPlatformDisplay::OnAcceleratedWidgetAvailable(
    gfx::AcceleratedWidget widget,
    float device_pixel_ratio) {
  if (widget != gfx::kNullAcceleratedWidget) {
    display_compositor_.reset(
        new DisplayCompositor(base::ThreadTaskRunnerHandle::Get(), widget,
                              gpu_state_, surfaces_state_));
  }
  UpdateMetrics(metrics_.size_in_pixels.To<gfx::Size>(), device_pixel_ratio);
}

void DefaultPlatformDisplay::OnAcceleratedWidgetDestroyed() {
  NOTREACHED();
}

void DefaultPlatformDisplay::OnActivationChanged(bool active) {}

void DefaultPlatformDisplay::RequestCopyOfOutput(
    std::unique_ptr<cc::CopyOutputRequest> output_request) {
  if (display_compositor_)
    display_compositor_->RequestCopyOfOutput(std::move(output_request));
}

}  // namespace ws

}  // namespace mus
