#include "camera.hpp"
#include <numbers>
#include <cmath>

Point CameraLOL::plan_move(Raycaster &rayview, int dir, bool strafe) {
  t = 0.0;
  if(strafe) {
    target_x = rayview.$pos_x + int(-rayview.$dir_y * 1.5 * dir);
    target_y = rayview.$pos_y + int(rayview.$dir_x * 1.5 * dir);
  } else {
    target_x = rayview.$pos_x + int(rayview.$dir_x * 1.5 * dir);
    target_y = rayview.$pos_y + int(rayview.$dir_y * 1.5 * dir);
  }

  return {size_t(target_x), size_t(target_y)};
}

void CameraLOL::plan_rotate(Raycaster &rayview, int dir) {
  t = 0.0;
  double angle_dir = std::numbers::pi * 0.25 * dir;

  target_dir_x = rayview.$dir_x * cos(angle_dir) - rayview.$dir_y * sin(angle_dir);
  target_dir_y = rayview.$dir_x * sin(angle_dir) + rayview.$dir_y * cos(angle_dir);

  target_plane_x = rayview.$plane_x * cos(angle_dir) - rayview.$plane_y * sin(angle_dir);
  target_plane_y = rayview.$plane_x * sin(angle_dir) + rayview.$plane_y * cos(angle_dir);
}

bool CameraLOL::play_rotate(Raycaster &rayview) {
  t += rot_speed;
  rayview.$dir_x = std::lerp(rayview.$dir_x, target_dir_x, t);
  rayview.$dir_y = std::lerp(rayview.$dir_y, target_dir_y, t);
  rayview.$plane_x = std::lerp(rayview.$plane_x, target_plane_x, t);
  rayview.$plane_y = std::lerp(rayview.$plane_y, target_plane_y, t);

  return t > 1.0;
}

bool CameraLOL::play_move(Raycaster &rayview) {
  t += move_speed;
  rayview.$pos_x = std::lerp(rayview.$pos_x, target_x, t);
  rayview.$pos_y = std::lerp(rayview.$pos_y, target_y, t);
  return t >= 1.0;
}

void CameraLOL::abort_plan(Raycaster& rayview) {
  target_x = rayview.$pos_x;
  target_y = rayview.$pos_y;
}