// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::collections::BTreeSet;

use glam::Vec2;

use super::{Player, PlayerId, bullet::Bullet, powerup::PowerupType, effects::{Effect, Effects, EffectInfo}, event::MoveType, team::TeamId};

/*
 * Both the client and server need to know certain things that have changed
 * after updating the world. However, the exact information that's relevant to
 * them differs.
 *
 * As an optimisation, generics are used to avoid performing unnecessary
 * operations when calling `update`.
 */
pub trait Changes {
	/*
	 * For the client, prevents changes reported to old players from being
	 * visualised on players (in case if a player rapidly exits and joins).
	 *
	 * For the server, probably not needed for now but I'm adding it for good
	 * practice to clean things up when players are removed.
	 */
	fn removed_players(&mut self, _old_ids: BTreeSet<PlayerId>) {}

	fn update(&mut self, _dt: f32) {}
	fn new_player(&mut self, _id: PlayerId) {}
	fn bullet_shot(&mut self, _id: PlayerId, _player: &Player, _effects: &Effects) {}
	fn add_hit(&mut self, _bullet: Bullet, _player: &Player, _player_id: PlayerId, _killed: bool) {}
	fn block_bullet_collision(&mut self, _bullet: Bullet) {}
	fn pos_changed(&mut self, _id: PlayerId, _typ: MoveType, _prev_pos: Vec2) {}
	fn ammo_crate_collected(&mut self, _id: PlayerId, _pos: Vec2) {}
	fn clear_powerups(&mut self) {}
	fn powerup_collected(&mut self, _id: PlayerId, _player: &Player, _typ: PowerupType, _pos: Vec2) {}
	fn effect_event(&mut self, _id: PlayerId, _effect: Effect, _old_info: EffectInfo, _new_info: EffectInfo, _player_pos: Vec2, _play_sound: bool) {}
	fn flag_captured(&mut self, _pos: Vec2) {}
	fn flag_dropped(&mut self, _pos: Vec2) {}
	fn player_reset(&mut self, _id: PlayerId) {}
	fn player_team_change(&mut self, _player_id: PlayerId, _team_id: Option<TeamId>) {}
	fn items_reset(&mut self) {}
	fn checkpoint_activated(&mut self, _pos: Vec2) {}
}

pub struct IgnoreChanges;

impl Changes for IgnoreChanges {}
