// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use glam::Vec2;
use strum::EnumCount;

use crate::app::config::action::{Action, ActionEvent};

use crate::world::player::{update::PlayerUpdate, input_state::{InputState, Movement}, direction::Direction};

#[derive(Default)]
pub struct PlayerController {
	movement_states: [bool; Movement::COUNT],
	shooting: bool,
	dropping_flag: bool,
	dir: Direction,
}

impl PlayerController {
	pub fn new() -> PlayerController { PlayerController::default() }

	pub fn action(&mut self, action: ActionEvent) {
		match action {
			ActionEvent::Action(action, state) => {
				let pressed = state.pressed();
				match action {
					Action::MoveLeft => self.movement_states[Movement::Left as usize] = pressed,
					Action::MoveRight => self.movement_states[Movement::Right as usize] = pressed,
					Action::MoveUp => self.movement_states[Movement::Up as usize] = pressed,
					Action::MoveDown => self.movement_states[Movement::Down as usize] = pressed,
					Action::Shoot => self.shooting = pressed,
					Action::DropFlag => self.dropping_flag = pressed,
					_ => (),
				}
			},
			ActionEvent::AllReleased => self.reset_action_state(),
		}
	}

	pub fn reset_action_state(&mut self) {
		self.movement_states = Default::default();
		self.shooting = false;
		self.dropping_flag = false;
	}

	pub fn mouse_move_event(&mut self, cursor_pos: Vec2) {
		self.dir = Direction::from(cursor_pos);
	}

	pub fn get_update(&self) -> PlayerUpdate {
		PlayerUpdate { dir: self.dir, input_state: InputState::new(self.movement_states.into(), self.shooting, self.dropping_flag) }
	}

	pub fn get_move_dir(&self) -> Vec2 {
		InputState::new(self.movement_states.into(), false, false).get_move_dir()
	}
}
