// Copyright 2018 The Fuchsia 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 "src/ui/examples/simplest_embedder/example_presenter.h"

#include <lib/ui/scenic/cpp/view_token_pair.h>

#include "src/lib/fxl/logging.h"

namespace simplest_embedder {

ExamplePresenter::ExamplePresenter(fuchsia::ui::scenic::Scenic* scenic)
    : session_(scenic), layers_(&session_) {
  // This would typically be done by the root Presenter.
  scenic->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) {
    Init(static_cast<float>(display_info.width_in_px),
         static_cast<float>(display_info.height_in_px));
  });
}

void ExamplePresenter::Init(float width, float height) {
  FXL_CHECK(!compositor_);
  width_ = width;
  height_ = height;
  compositor_ = std::make_unique<scenic::DisplayCompositor>(&session_);
  compositor_->SetLayerStack(layers_);

  MaybeSetPresentationSize();
  ScenicSessionPresent();
}

void ExamplePresenter::PresentView(
    fuchsia::ui::views::ViewHolderToken view_holder_token,
    fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> /*presentation_request*/) {
  FXL_CHECK(!presentation_) << "simplest_embedder: only a single Presentation is supported.";

  FXL_LOG(INFO) << "Presenting View.";

  presentation_ = std::make_unique<Presentation>(&session_, std::move(view_holder_token));
  layers_.AddLayer(presentation_->layer());

  MaybeSetPresentationSize();
  ScenicSessionPresent();
}

void ExamplePresenter::PresentOrReplaceView(
    fuchsia::ui::views::ViewHolderToken view_holder_token,
    fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> presentation_request) {
  FXL_CHECK(!presentation_) << "simplest_embedder: clobbering presentation is not supported";
  PresentView(std::move(view_holder_token), std::move(presentation_request));
};

void ExamplePresenter::MaybeSetPresentationSize() {
  if (compositor_ && presentation_) {
    presentation_->SetSize(width_, height_);
  }
}

void ExamplePresenter::ScenicSessionPresent() {
  session_.Present(0, [this](fuchsia::images::PresentationInfo info) { ScenicSessionPresent(); });
}

ExamplePresenter::Presentation::Presentation(scenic::Session* session,
                                             fuchsia::ui::views::ViewHolderToken view_holder_token)
    : layer_(session),
      view_holder_node_(session),
      view_holder_(session, std::move(view_holder_token),
                   "simplest_embedder Presentation of ShadertoyEmbedderView") {
  scenic::Renderer renderer(session);
  scenic::Scene scene(session);
  scenic::Camera camera(scene);
  scenic::AmbientLight ambient_light(session);
  scenic::DirectionalLight directional_light(session);

  scenic::EntityNode root_node(session);

  layer_.SetRenderer(renderer);
  renderer.SetCamera(camera);

  // Set orthographic projection from viewing volume.
  camera.SetProjection(0.f);

  scene.AddLight(ambient_light);
  scene.AddLight(directional_light);
  scene.AddChild(view_holder_node_);

  view_holder_node_.Attach(view_holder_);
  view_holder_node_.SetTranslation(0, 0, -10.f);

  ambient_light.SetColor(0.3f, 0.3f, 0.3f);
  directional_light.SetColor(0.7f, 0.7f, 0.7f);
  directional_light.SetDirection(1.f, 1.f, -2.f);
}

void ExamplePresenter::Presentation::SetSize(float width, float height) {
  layer_.SetSize(static_cast<int32_t>(width), static_cast<int32_t>(height));
  // TODO(SCN-1276): Don't hardcode Z bounds in multiple locations.
  view_holder_.SetViewProperties(0.f, 0.f, -1000.f, width, height, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
                                 0.f);
}

}  // namespace simplest_embedder
