/*
 * sh_game.h -- Space Hulk turn-based game system for Quakespasm
 *
 * Copyright (C) 2026 fish fvch studios
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef SH_GAME_H
#define SH_GAME_H

/* ============================================================
 * CONSTANTS
 * ============================================================ */

#define SH_GRID_SIZE		128	/* quake units per grid cell */
#define SH_MAX_MARINES		5
#define SH_MAX_GENESTEALERS	32
#define SH_MAX_DOORS		16
#define SH_MAX_BLIP_ENTRIES	8
#define SH_MAX_LOG_MESSAGES	32
#define SH_LOG_MSG_LEN		80

#define SH_DEFAULT_AP		4
#define SH_MAX_COMMAND_POINTS	6	/* 1d6 bonus AP per round */

#define SH_GENESTEALER_MP	6	/* movement points per alien phase */

/* AP costs */
#define SH_AP_MOVE_FORWARD	1
#define SH_AP_TURN		0	/* free turns for snappy gameplay */
#define SH_AP_SHOOT		1
#define SH_AP_OVERWATCH		2
#define SH_AP_MELEE		1
#define SH_AP_DOOR		1

/* animation durations (seconds) */
#define SH_ANIM_MOVE_DURATION	0.2
#define SH_ANIM_TURN_DURATION	0.15
#define SH_ANIM_SHOOT_DURATION	0.3

#define SH_MAX_ANIMS		8

/* standing eye height above grid floor */
#define SH_EYE_HEIGHT		32

/* ============================================================
 * ENUMERATIONS
 * ============================================================ */

typedef enum {
	SH_PHASE_INACTIVE,		/* game not started */
	SH_PHASE_BRIEFING,		/* pre-mission screen */
	SH_PHASE_PLAYER,		/* player marine phase */
	SH_PHASE_ALIEN,			/* AI genestealer phase */
	SH_PHASE_OVERWATCH_REACT,	/* interrupt: marine reaction fire */
	SH_PHASE_ROUND_END,		/* cleanup, check win/lose */
	SH_PHASE_VICTORY,
	SH_PHASE_DEFEAT
} sh_phase_t;

typedef enum {
	SH_ACTION_NONE,
	SH_ACTION_MOVE_FORWARD,
	SH_ACTION_TURN_LEFT,
	SH_ACTION_TURN_RIGHT,
	SH_ACTION_TURN_180,
	SH_ACTION_SHOOT,
	SH_ACTION_OVERWATCH,
	SH_ACTION_MELEE,
	SH_ACTION_DOOR,
	SH_ACTION_END_TURN
} sh_action_t;

typedef enum {
	SH_FACING_NORTH,	/* +Y: yaw 90  */
	SH_FACING_EAST,		/* +X: yaw 0   */
	SH_FACING_SOUTH,	/* -Y: yaw 270 */
	SH_FACING_WEST		/* -X: yaw 180 */
} sh_facing_t;

typedef enum {
	SH_WEAPON_STORM_BOLTER,
	SH_WEAPON_ASSAULT_CANNON,
	SH_WEAPON_POWER_FIST,
	SH_WEAPON_FLAMER
} sh_weapon_t;

typedef enum {
	SH_LOG_INFO,
	SH_LOG_COMBAT,
	SH_LOG_ALERT,
	SH_LOG_KILL
} sh_log_type_t;

typedef enum {
	SH_AI_IDLE,
	SH_AI_ADVANCE,
	SH_AI_ATTACK,
	SH_AI_FLANK
} sh_ai_state_t;

/* ============================================================
 * DATA STRUCTURES
 * ============================================================ */

/* Sidecar data for a marine entity */
typedef struct {
	qboolean	active;
	edict_t		*ent;		/* quake edict for rendering/collision */
	int		squad_index;
	int		grid_x, grid_y;
	sh_facing_t	facing;
	int		ap;		/* action points remaining this turn */
	int		ap_max;		/* base AP (default 4) */
	sh_weapon_t	weapon;
	int		health;		/* 1 = alive in Space Hulk */
	qboolean	on_overwatch;
	int		overwatch_ap;
	qboolean	has_acted;	/* activated this phase */
	qboolean	alive;
	char		name[32];
} sh_marine_t;

/* Sidecar data for a genestealer entity */
typedef struct {
	qboolean	active;
	edict_t		*ent;
	int		grid_x, grid_y;
	sh_facing_t	facing;
	int		mp;		/* movement points remaining this phase */
	sh_ai_state_t	ai_state;
	int		target_marine;	/* index into marines[], or -1 */
	qboolean	alive;
	qboolean	is_blip;
	int		blip_count;	/* 1-3 genestealers per blip */
} sh_genestealer_t;

/* Door entity */
typedef struct {
	qboolean	active;
	edict_t		*ent;
	int		grid_x, grid_y;
	qboolean	is_open;
} sh_door_t;

/* Blip spawn entry point */
typedef struct {
	int		grid_x, grid_y;
	sh_facing_t	entry_facing;
	qboolean	active;
} sh_blip_entry_t;

/* Message log (adapted from ideas/turn_manager.c) */
typedef struct {
	char		text[SH_LOG_MSG_LEN];
	sh_log_type_t	type;
	int		round;
	int		stack_count;
} sh_log_msg_t;

typedef struct {
	sh_log_msg_t	messages[SH_MAX_LOG_MESSAGES];
	int		write_index;
	int		count;
	qboolean	updated;
} sh_message_log_t;

/* Animation lerp for smooth grid movement in 3D */
typedef struct {
	qboolean	active;
	edict_t		*ent;
	vec3_t		start_pos;
	vec3_t		end_pos;
	float		start_yaw;
	float		end_yaw;
	double		start_time;
	double		duration;
} sh_anim_t;

/* ============================================================
 * MASTER GAME STATE
 * ============================================================ */

typedef struct {
	/* phase management */
	sh_phase_t	phase;
	sh_phase_t	phase_before_interrupt;
	int		round_number;
	int		command_points;
	int		command_points_used;

	/* marines */
	sh_marine_t	marines[SH_MAX_MARINES];
	int		num_marines;
	int		selected_marine;

	/* genestealers */
	sh_genestealer_t genestealers[SH_MAX_GENESTEALERS];
	int		num_genestealers;
	int		current_alien;

	/* doors */
	sh_door_t	doors[SH_MAX_DOORS];
	int		num_doors;

	/* spawn points */
	sh_blip_entry_t	blip_entries[SH_MAX_BLIP_ENTRIES];
	int		num_blip_entries;

	/* animation queue */
	sh_anim_t	anims[SH_MAX_ANIMS];
	int		num_anims;

	/* message log */
	sh_message_log_t log;

	/* camera (follows selected marine for now) */
	int		camera_marine;
} sh_gamestate_t;

extern sh_gamestate_t sh_game;

/* ============================================================
 * PUBLIC API -- sh_game.c
 * ============================================================ */

void		SH_Init (void);
void		SH_Shutdown (void);
void		SH_NewGame (void);
void		SH_Frame (void);
qboolean	SH_Active (void);

/* coordinate conversion */
void		SH_GridToWorld (int gx, int gy, vec3_t out);
void		SH_WorldToGrid (vec3_t pos, int *gx, int *gy);

/* facing helpers */
float		SH_FacingToYaw (sh_facing_t facing);
sh_facing_t	SH_YawToFacing (float yaw);
void		SH_FacingToDir (sh_facing_t facing, int *dx, int *dy);

/* grid collision */
qboolean	SH_GridBlocked (int gx, int gy, edict_t *ignore);

/* animation */
void		SH_AnimPush (edict_t *ent, vec3_t start, vec3_t end,
			float start_yaw, float end_yaw, double duration);
qboolean	SH_AnimBusy (void);

/* logging */
void		SH_Log (sh_log_type_t type, const char *fmt, ...) FUNC_PRINTF(2,3);

/* ============================================================
 * PUBLIC API -- sh_marine.c
 * ============================================================ */

void		SH_Marine_Spawn (int index, int gx, int gy,
			sh_facing_t facing, sh_weapon_t weapon, const char *name);
qboolean	SH_Marine_TryAction (int marine_index, sh_action_t action);
void		SH_Marine_BeginPlayerPhase (void);
qboolean	SH_Marine_AllDone (void);
void		SH_Marine_SelectNext (void);
void		SH_Marine_SelectPrev (void);

/* ============================================================
 * PUBLIC API -- sh_input.c
 * ============================================================ */

void		SH_Input_Init (void);
qboolean	SH_Input_KeyEvent (int key, qboolean down);

#endif /* SH_GAME_H */
