// 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 "sky/shell/ui/engine.h"

#include "base/bind.h"
#include "base/trace_event/trace_event.h"
#include "mojo/public/cpp/application/connect.h"
#include "sky/engine/public/platform/WebInputEvent.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
#include "sky/engine/public/web/Sky.h"
#include "sky/engine/public/web/WebLocalFrame.h"
#include "sky/engine/public/web/WebSettings.h"
#include "sky/engine/public/web/WebView.h"
#include "sky/services/platform/platform_impl.h"
#include "sky/shell/service_provider.h"
#include "sky/shell/ui/animator.h"
#include "sky/shell/ui/input_event_converter.h"
#include "sky/shell/ui/internals.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"

namespace sky {
namespace shell {

namespace {

void ConfigureSettings(blink::WebSettings* settings) {
  settings->setDefaultFixedFontSize(13);
  settings->setDefaultFontSize(16);
  settings->setLoadsImagesAutomatically(true);
}

PlatformImpl* g_platform_impl = nullptr;

}

Engine::Engine(const Config& config)
    : config_(config),
      animator_(new Animator(config, this)),
      web_view_(nullptr),
      device_pixel_ratio_(1.0f),
      viewport_observer_binding_(this),
      weak_factory_(this) {
}

Engine::~Engine() {
  if (web_view_)
    web_view_->close();
}

base::WeakPtr<Engine> Engine::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

void Engine::Init(ServiceProviderContext* service_provider_context) {
  TRACE_EVENT0("sky", "Engine::Init");

  mojo::ServiceProviderPtr service_provider =
      CreateServiceProvider(service_provider_context);
  mojo::NetworkServicePtr network_service;
  mojo::ConnectToService(service_provider.get(), &network_service);

  DCHECK(!g_platform_impl);
  g_platform_impl = new PlatformImpl(network_service.Pass());
  blink::initialize(g_platform_impl);
}

void Engine::BeginFrame(base::TimeTicks frame_time) {
  TRACE_EVENT0("sky", "Engine::BeginFrame");

  if (sky_view_)
    sky_view_->BeginFrame(frame_time);

  if (web_view_) {
    double frame_time_sec = (frame_time - base::TimeTicks()).InSecondsF();
    double deadline_sec = frame_time_sec;
    double interval_sec = 1.0 / 60;
    blink::WebBeginFrameArgs args(frame_time_sec, deadline_sec, interval_sec);
    web_view_->beginFrame(args);
    web_view_->layout();
  }
}

skia::RefPtr<SkPicture> Engine::Paint() {
  TRACE_EVENT0("sky", "Engine::Paint");

  SkRTreeFactory factory;
  SkPictureRecorder recorder;
  auto canvas = skia::SharePtr(recorder.beginRecording(
      physical_size_.width(), physical_size_.height(), &factory,
      SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag));

  if (sky_view_) {
    skia::RefPtr<SkPicture> picture = sky_view_->Paint();
    canvas->clear(SK_ColorBLACK);
    canvas->scale(device_pixel_ratio_, device_pixel_ratio_);
    if (picture)
      canvas->drawPicture(picture.get());
  }

  if (web_view_)
    web_view_->paint(canvas.get(), blink::WebRect(gfx::Rect(physical_size_)));

  return skia::AdoptRef(recorder.endRecordingAsPicture());
}

void Engine::ConnectToViewportObserver(
    mojo::InterfaceRequest<ViewportObserver> request) {
  viewport_observer_binding_.Bind(request.Pass());
}

void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
  config_.gpu_task_runner->PostTask(
      FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable,
                            config_.gpu_delegate, widget));
  if (sky_view_)
    scheduleVisualUpdate();
  if (web_view_)
    scheduleVisualUpdate();
}

void Engine::OnOutputSurfaceDestroyed() {
  config_.gpu_task_runner->PostTask(
      FROM_HERE,
      base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate));
}

void Engine::OnViewportMetricsChanged(int width, int height,
                                      float device_pixel_ratio) {
  physical_size_.SetSize(width, height);
  device_pixel_ratio_ = device_pixel_ratio;

  if (sky_view_)
    UpdateSkyViewSize();

  if (web_view_)
    UpdateWebViewSize();
}

void Engine::UpdateSkyViewSize() {
  CHECK(sky_view_);
  blink::SkyDisplayMetrics metrics;
  metrics.physical_size = physical_size_;
  metrics.device_pixel_ratio = device_pixel_ratio_;
  sky_view_->SetDisplayMetrics(metrics);
}

void Engine::UpdateWebViewSize() {
  CHECK(web_view_);
  web_view_->setDeviceScaleFactor(device_pixel_ratio_);
  gfx::SizeF size = gfx::ScaleSize(physical_size_, 1 / device_pixel_ratio_);
  // FIXME: We should be able to set the size of the WebView in floating point
  // because its in logical pixels.
  web_view_->resize(blink::WebSize(size.width(), size.height()));
}

// TODO(eseidel): This is likely not needed anymore.
blink::WebScreenInfo Engine::screenInfo() {
  blink::WebScreenInfo screen;
  screen.rect = blink::WebRect(gfx::Rect(physical_size_));
  screen.availableRect = screen.rect;
  screen.deviceScaleFactor = device_pixel_ratio_;
  return screen;
}

void Engine::OnInputEvent(InputEventPtr event) {
  TRACE_EVENT0("sky", "Engine::OnInputEvent");
  scoped_ptr<blink::WebInputEvent> web_event =
      ConvertEvent(event, device_pixel_ratio_);
  if (!web_event)
    return;
  if (sky_view_)
    sky_view_->HandleInputEvent(*web_event);
  if (web_view_)
    web_view_->handleInputEvent(*web_event);
}

void Engine::LoadURL(const mojo::String& mojo_url) {
  GURL url(mojo_url);
  if (!blink::WebView::shouldUseWebView(url)) {
    if (web_view_) {
      web_view_->close();
      web_view_ = nullptr;
    }
    sky_view_ = blink::SkyView::Create(this);
    sky_view_->Load(url);
    UpdateSkyViewSize();
    return;
  }

  if (sky_view_)
    sky_view_ = nullptr;

  LOG(WARNING) << ".sky support is deprecated, please use .dart for main()";

  // Something bad happens if you try to call WebView::close and replace
  // the webview.  So for now we just load into the existing one. :/
  if (!web_view_)
    web_view_ = blink::WebView::create(this);
  ConfigureSettings(web_view_->settings());
  web_view_->setMainFrame(blink::WebLocalFrame::create(this));
  UpdateWebViewSize();
  web_view_->mainFrame()->load(url);
}

void Engine::frameDetached(blink::WebFrame* frame) {
  // |frame| is invalid after here.
  frame->close();
}

void Engine::initializeLayerTreeView() {
}

void Engine::scheduleVisualUpdate() {
  animator_->RequestFrame();
}

void Engine::didCreateIsolate(blink::WebLocalFrame* frame,
                              Dart_Isolate isolate) {
  Internals::Create(isolate,
                    CreateServiceProvider(config_.service_provider_context));
}

void Engine::DidCreateIsolate(Dart_Isolate isolate) {
  Internals::Create(isolate,
                    CreateServiceProvider(config_.service_provider_context));
}

void Engine::ScheduleFrame() {
  animator_->RequestFrame();
}

blink::ServiceProvider* Engine::services() {
  return this;
}

mojo::NavigatorHost* Engine::NavigatorHost() {
  return this;
}

void Engine::RequestNavigate(mojo::Target target,
                             mojo::URLRequestPtr request) {
  // Ignoring target for now.
  base::MessageLoop::current()->PostTask(FROM_HERE,
      base::Bind(&Engine::LoadURL, GetWeakPtr(), request->url));
}

void Engine::DidNavigateLocally(const mojo::String& url) {
}

void Engine::RequestNavigateHistory(int32_t delta) {
  NOTIMPLEMENTED();
}

}  // namespace shell
}  // namespace sky
