// 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 "garnet/bin/ui/root_presenter/perspective_demo_mode.h"

// clang-format off
#include "src/ui/lib/glm_workaround/glm_workaround.h"
// clang-format on

#include <array>
#include <glm/ext.hpp>

#include "garnet/bin/ui/root_presenter/presentation.h"

namespace root_presenter {

namespace {
constexpr float kPi = glm::pi<float>();
}  // namespace

PerspectiveDemoMode::PerspectiveDemoMode() {}

bool PerspectiveDemoMode::OnEvent(const fuchsia::ui::input::InputEvent& event,
                                  Presentation* presenter) {
  if (event.is_pointer()) {
    const fuchsia::ui::input::PointerEvent& pointer = event.pointer();
    if (animation_state_ == kThreeQuarters ||
        animation_state_ == kPerspective) {
      if (pointer.phase == fuchsia::ui::input::PointerEventPhase::DOWN) {
        // If we're not already panning/rotating the camera, then start, but
        // only if the touch-down is in the bottom 10% of the screen.
        if (!trackball_pointer_down_ &&
            pointer.y > 0.9f * presenter->display_model_actual_.display_info()
                                   .height_in_px) {
          trackball_pointer_down_ = true;
          trackball_device_id_ = pointer.device_id;
          trackball_pointer_id_ = pointer.pointer_id;
          trackball_previous_x_ = pointer.x;
        }
      } else if (pointer.phase == fuchsia::ui::input::PointerEventPhase::MOVE) {
        // If the moved pointer is the one that is currently panning/rotating
        // the camera, then update the camera position.
        if (trackball_pointer_down_ &&
            trackball_device_id_ == pointer.device_id &&
            trackball_device_id_ == pointer.device_id) {
          float rate =
              -2.5f /
              presenter->display_model_actual_.display_info().width_in_px;
          float change = rate * (pointer.x - trackball_previous_x_);
          trackball_previous_x_ = pointer.x;

          if (animation_state_ == kThreeQuarters) {
            target_camera_pan_ += change;
            target_camera_pan_ = glm::clamp(target_camera_pan_, -1.f, 1.f);
          } else if (animation_state_ == kPerspective) {
            target_camera_zoom_ += change;
            target_camera_zoom_ = glm::clamp(target_camera_zoom_, 0.0f, 1.0f);
            float fov =
                360.f * ComputeHalfFov(presenter, target_camera_zoom_) / kPi;
            FXL_LOG(INFO) << "Current perspective fov is " << fov << "degrees";
          }
        }
      }
    }

    // Pointer release should be handled no matter which state we are in.
    if (pointer.phase == fuchsia::ui::input::PointerEventPhase::UP) {
      // The pointer was released.
      if (trackball_pointer_down_ &&
          trackball_device_id_ == pointer.device_id &&
          trackball_device_id_ == pointer.device_id) {
        trackball_pointer_down_ = false;
      }
    }
  } else if (event.is_keyboard()) {
    // Alt-Backspace cycles through modes.
    const fuchsia::ui::input::KeyboardEvent& kbd = event.keyboard();
    if ((kbd.modifiers & fuchsia::ui::input::kModifierAlt) &&
        kbd.phase == fuchsia::ui::input::KeyboardEventPhase::PRESSED &&
        kbd.code_point == 0 && kbd.hid_usage == 42 &&
        !trackball_pointer_down_) {
      HandleAltBackspace(presenter);
      return true;
    }
  }

  return false;
}

void PerspectiveDemoMode::HandleAltBackspace(Presentation* presenter) {
  switch (animation_state_) {
    case kOrthographic:
      target_camera_pan_ = 0.0f;
      target_camera_zoom_ = 0.0f;
      animation_state_ = kAnimateToThreeQuarters;
      animation_start_time_ = zx_clock_get_monotonic();
      break;
    case kThreeQuarters:
      animation_state_ = kAnimateToPerspective;
      animation_start_time_ = zx_clock_get_monotonic();
      break;
    case kPerspective:
      animation_state_ = kAnimateToOrthographic;
      animation_start_time_ = zx_clock_get_monotonic();
    default:
      return;
  }

  UpdateAnimation(presenter, animation_start_time_);
}

float PerspectiveDemoMode::ComputeHalfFov(Presentation* presenter,
                                          float zoom) const {
  // The default camera emulates an orthographic camera, by creating a .1-degree
  // half angle camera, at the appropriate distance.
  constexpr float kMinHalfFov = .1f * kPi / 180.f;

  // TODO(SCN-194): The maximum half fov is determined by the minimum camera
  // distance. This distance matches the hard coded behavior from
  // escher::Camera::NewOrtho() and scenic::gfx::Layer::GetViewingVolume(). For
  // a 1600px height display, this works out to ~76 degrees.
  float max_half_fov =
      atan(presenter->display_model_actual_.display_info().height_in_px * 0.5f /
           1010.f);

  return glm::lerp(kMinHalfFov, max_half_fov, zoom);
}

void PerspectiveDemoMode::UpdateCamera(Presentation* presenter, float pan_param,
                                       float zoom_param) {
  const float half_width =
      presenter->display_model_actual_.display_info().width_in_px * 0.5f;
  const float half_height =
      presenter->display_model_actual_.display_info().height_in_px * 0.5f;

  // Always look at the middle of the stage.
  const float target[3] = {half_width, half_height, 0};

  // Ease-in/ease-out for the animation.
  pan_param = glm::smoothstep(0.f, 1.f, pan_param);
  zoom_param = glm::smoothstep(0.f, 1.f, zoom_param);

  // The target camera takes into account the current authored pan and zoom
  // requests.
  float zoom = glm::lerp(0.f, target_camera_zoom_, zoom_param);
  float half_fovy = ComputeHalfFov(presenter, zoom);
  float eye_dist = half_height / tan(half_fovy);
  float eye_z = -eye_dist;
  glm::vec3 eye_start(half_width, half_height, eye_z);

  constexpr float kMaxCameraPan = kPi / 4;
  float eye_end_x =
      sin(glm::lerp(0.f, kMaxCameraPan, target_camera_pan_)) * eye_dist +
      half_width;
  float eye_end_y =
      cos(glm::lerp(0.f, kMaxCameraPan, target_camera_pan_)) * eye_dist +
      half_height;

  glm::vec3 eye_end(eye_end_x, eye_end_y, 0.75f * eye_z);

  // Halfway point for the pan animation is further out than the starting point,
  // to get a cool zoom out->zoom in effect.
  glm::vec3 eye_mid = glm::mix(eye_start, eye_end, 0.4f);
  eye_mid.z = 1.5f * eye_z;

  // Quadratic bezier.
  glm::vec3 eye = glm::mix(glm::mix(eye_start, eye_mid, pan_param),
                           glm::mix(eye_mid, eye_end, pan_param), pan_param);

  glm::vec3 glm_up =
      glm::mix(glm::vec3(0, -1.f, 0.f), glm::vec3(0, -0.1f, -0.9f), pan_param);
  glm_up = glm::normalize(glm_up);

  float up[3] = {glm_up[0], glm_up[1], glm_up[2]};
  presenter->camera_.SetTransform(glm::value_ptr(eye), target, up);
  presenter->camera_.SetProjection(2.f * half_fovy);
}

bool PerspectiveDemoMode::UpdateAnimation(Presentation* presenter,
                                          uint64_t presentation_time) {
  if (animation_state_ == kOrthographic) {
    return false;
  }

  double secs = static_cast<double>(presentation_time - animation_start_time_) /
                1'000'000'000;
  constexpr double kAnimationDuration = 1.3;
  float time_param = secs / kAnimationDuration;

  if (time_param >= 1.f) {
    time_param = 1.f;
    switch (animation_state_) {
      case kAnimateToThreeQuarters:
        animation_state_ = kThreeQuarters;
        break;
      case kAnimateToPerspective:
        animation_state_ = kPerspective;
        break;
      case kAnimateToOrthographic: {
        animation_state_ = kOrthographic;

        const float half_width =
            presenter->display_model_actual_.display_info().width_in_px * 0.5f;
        const float half_height =
            presenter->display_model_actual_.display_info().height_in_px * 0.5f;

        // Always look at the middle of the stage.
        const float target[3] = {half_width, half_height, 0};

        glm::vec3 glm_up(0, -1.f, 0.f);
        glm_up = glm::normalize(glm_up);
        float up[3] = {glm_up[0], glm_up[1], glm_up[2]};

        // Switch back to ortho view, and re-enable clipping.
        // TODO(SCN-1276): Don't hardcode Z bounds in multiple locations.
        float ortho_eye[3] = {half_width, half_height, -1010.f};
        presenter->camera_.SetTransform(ortho_eye, target, up);
        presenter->camera_.SetProjection(0.f);
        return true;
      }
      default:
        break;
    }
  }

  float pan_param;
  float zoom_param;
  switch (animation_state_) {
    case kAnimateToThreeQuarters:
      pan_param = time_param;
      zoom_param = 0.f;
      break;
    case kAnimateToPerspective:
      pan_param = 1.f - time_param;
      zoom_param = time_param;
      break;
    case kAnimateToOrthographic:
      pan_param = 0.f;
      zoom_param = 1.f - time_param;
      break;
    case kThreeQuarters:
      pan_param = 1.f;
      zoom_param = 0.f;
      break;
    case kPerspective:
      pan_param = 0.f;
      zoom_param = 1.f;
      break;
    default:
      FXL_DCHECK(false);
      return false;
  }

  UpdateCamera(presenter, pan_param, zoom_param);

  return true;
}

}  // namespace root_presenter
