// Copyright 2017 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/scenic/lib/gfx/resources/camera.h"

#include "src/ui/lib/escher/util/type_utils.h"
#include "src/ui/scenic/lib/gfx/util/unwrap.h"

namespace scenic_impl {
namespace gfx {

const ResourceTypeInfo Camera::kTypeInfo = {ResourceType::kCamera, "Camera"};

Camera::Camera(Session* session, SessionId session_id, ResourceId id, ScenePtr scene)
    : Resource(session, session_id, id, Camera::kTypeInfo), scene_(std::move(scene)) {}

Camera::Camera(Session* session, SessionId session_id, ResourceId id, ScenePtr scene,
               const ResourceTypeInfo& type_info)
    : Resource(session, session_id, id, type_info), scene_(std::move(scene)) {}

void Camera::SetTransform(const glm::vec3& eye_position, const glm::vec3& eye_look_at,
                          const glm::vec3& eye_up) {
  eye_position_ = eye_position;
  eye_look_at_ = eye_look_at;
  eye_up_ = eye_up;
}

void Camera::SetProjection(const float fovy) { fovy_ = fovy; }

void Camera::SetClipSpaceTransform(const glm::vec2& translation, float scale) {
  if (translation == glm::vec2() && scale == 1) {
    has_clip_space_transform_ = false;
  } else {
    has_clip_space_transform_ = true;

    // clang-format off
    clip_space_transform_ = {
      scale, 0, 0, 0,
      0, scale, 0, 0,
      0, 0, 1, 0,
      translation.x, translation.y, 0, 1
    };
    // clang-format on
  }
}

void Camera::SetPoseBuffer(fxl::RefPtr<Buffer> buffer, uint32_t num_entries, zx::time base_time,
                           zx::duration time_interval) {
  pose_buffer_ = buffer;
  num_entries_ = num_entries;
  base_time_ = base_time;
  time_interval_ = time_interval;
}

escher::Camera Camera::GetEscherCamera(const escher::ViewingVolume& volume) const {
  escher::Camera camera(glm::mat4(1), glm::mat4(1));
  if (fovy_ == 0.f) {
    camera = escher::Camera::NewOrtho(volume,
                                      has_clip_space_transform_ ? &clip_space_transform_ : nullptr);
  } else {
    camera = escher::Camera::NewPerspective(
        volume, glm::lookAt(eye_position_, eye_look_at_, eye_up_), fovy_,
        has_clip_space_transform_ ? &clip_space_transform_ : nullptr);
  }
  return camera;
}

escher::hmd::PoseBuffer Camera::GetEscherPoseBuffer() const {
  return pose_buffer_ ? escher::hmd::PoseBuffer(pose_buffer_->escher_buffer(), num_entries_,
                                                base_time_.get(), time_interval_.get())
                      : escher::hmd::PoseBuffer();  // NOTE: has operator bool
}

std::pair<escher::ray4, escher::mat4> Camera::ProjectRay(
    const escher::ray4& ray, const escher::ViewingVolume& viewing_volume) const {
  auto camera = GetEscherCamera(viewing_volume);

  // This screen transform shifts the x, y from [-1, 1] to [0, 1]. Therefore,
  // when we invert it below, it takes the input coords into Vulkan normalized
  // device coordinates.
  auto scale = glm::scale(glm::vec3(0.5f, 0.5f, -1.f));
  auto translate = glm::translate(glm::vec3(1.f, 1.f, 0.f));
  auto device_transform = scale * translate;

  // This operation can be thought of as constructing the ray originating at the
  // camera's position, that passes through a point on the near plane.
  //
  // First the constructed near/mid points get passed through the inverse of the
  // device transform. After that the projection gets "undone," and finally the
  // camera transform is taken into account.
  //
  // For more information about world, view, and projection matrices, and how
  // they can be used for ray picking, see:
  // http://www.codinglabs.net/article_world_view_projection_matrix.aspx
  // https://stackoverflow.com/questions/2093096/implementing-ray-picking
  auto inverse_vp = glm::inverse(device_transform * camera.projection() * camera.transform());

  return {inverse_vp * ray, inverse_vp};
}

}  // namespace gfx
}  // namespace scenic_impl
