// Copyright 2024 SquareBlock Inc. All Rights Reserved.
// Author: tianlei.richard@qq.com (tianlei.richard)

#include "camera.h"

#include "spdlog/spdlog.h"

Camera::Camera(const Vector3d &up)
    : gaze_(Vector3d::Identity()), up_(up), camera_speed_(0.3) {}

Camera::Camera(const Vector3d &up, const float camera_speed)
    : gaze_(Vector3d{0, 0, 1}), up_(up), camera_speed_(camera_speed) {
  spdlog::debug("Gaze: ({}, {}, {}), Up: ({}, {}, {})", gaze_.x(), gaze_.y(),
                gaze_.z(), up_.x(), up_.y(), up_.z());
}

void Camera::move(const Point3d &offset) {
  position_ = (offset * camera_speed_);
}

void Camera::set_gaze(const Vector3d &gaze) { gaze_ = gaze.normalized(); }

TransformMatrix Camera::get_view_transform() const {
  // Move camera to origin
  TransformMatrix m{{1, 0, 0, -position_.x()},
                    {0, 1, 0, -position_.y()},
                    {0, 0, 1, -position_.z()},
                    {0, 0, 0, 1}};
  // Adjust to fit xyz
  const Vector3d &x_camera{(gaze_.cross(up_)).normalized()};
  m = TransformMatrix{{x_camera.x(), x_camera.y(), x_camera.z(), 0},
                      {up_.x(), up_.y(), up_.z(), 0},
                      {-gaze_.x(), -gaze_.y(), -gaze_.z(), 0},
                      {0, 0, 0, 1}} *
      m;

  return m;
}
