#ifndef __ANIMATION_CONTROL_H
#define __ANIMATION_CONTROL_H

// Header file for merc animation control
#include "JA2Types.h"


#define MAX_ANIMATIONS			320
#define MAX_FRAMES_PER_ANIM		100
#define MAX_RANDOM_ANIMS_PER_BODYTYPE	7

#define RANDOM_ANIM_NOTHINGINHAND	0
#define RANDOM_ANIM_RIFLEINHAND	1
#define RANDOM_ANIM_IRRELEVENTINHAND	2


#define RANDOM_ANIM_SOUND		250

#define RANDOM_ANIM_CASUAL		0x01
#define RANDOM_ANIM_SECONDBIGMERC	0x02
#define RANDOM_ANIM_FIRSTBIGMERC	0x04
#define RANDOM_ANIM_INJURED		0x08
#define RANDOM_ANIM_DRUNK		0x10


#define INJURED_CHANGE_THREASHOLD	30


#define USESTATS			0
#define FAST_TURN_ANIM_SPEED		30

#define INVALID_ANIMATION_SURFACE	32000

// FLAG DEFINES
#define ANIM_IGNORE_AUTOSTANCE		0x00000001
#define ANIM_OK_CHARGE_AP_FOR_TURN	0x00000002
#define ANIM_STATIONARY		0x00000004
#define ANIM_MOVING			0x00000008
#define ANIM_TURNING			0x00000010
#define ANIM_FASTTURN			0x00000020
#define ANIM_FIREREADY			0x00000040
#define ANIM_NONINTERRUPT		0x00000080
#define ANIM_HITFINISH			0x00000100
#define ANIM_HITSTART			0x00000200
#define ANIM_HITWHENDOWN		0x00000400
#define ANIM_NOSHOW_MARKER		0x00000800
#define ANIM_NOMOVE_MARKER		0x00001000
#define ANIM_NORESTART			0x00002000
#define ANIM_HITSTOP			0x00004000
#define ANIM_SPECIALMOVE		0x00008000
#define ANIM_MERCIDLE			0x00010000
#define ANIM_STANCECHANGEANIM		0x00020000
#define ANIM_LOWER_WEAPON		0x00040000
#define ANIM_RAISE_WEAPON		0x00080000
#define ANIM_NOCHANGE_WEAPON		0x00100000
#define ANIM_NOCHANGE_PENDINGCOUNT	0x00200000
#define ANIM_NO_EFFORT			0x00400000
#define ANIM_MIN_EFFORT		0x00800000
#define ANIM_LIGHT_EFFORT		0x01000000
#define ANIM_MODERATE_EFFORT		0x02000000
#define ANIM_RT_NONINTERRUPT		0x04000000
#define ANIM_VARIABLE_EFFORT		0x08000000
#define ANIM_FIRE			0x20000000
#define ANIM_BREATH			0x40000000
#define ANIM_IGNOREHITFINISH		0x80000000


//ANIMATION HEIGHT VALUES
enum AnimationHeight : UINT8
{
	ANIM_STAND  = 6,
	ANIM_CROUCH = 3,
	ANIM_PRONE  = 1
};
#define INVALID_ANIMATION		0xFFF0
#define FOUND_INVALID_ANIMATION	0xFFF1


struct ANIMCONTROLTYPE
{
	const char* zAnimStr;
	FLOAT       dMovementChange;
	UINT32      uiFlags;
	INT16       sSpeed;
	UINT8       ubHeight;
	UINT8       ubEndHeight;
};


struct ANI_SPEED_DEF
{
	INT16 sSpeed;
	FLOAT dMovementChange;
};


struct RANDOM_ANI_DEF
{
	UINT8       ubHandRestriction;
	INT16       sAnimID;
	UINT8       ubStartRoll;
	UINT8       ubEndRoll;
	UINT8       ubFlags;
	UINT8       ubAnimHeight;
	const char *zSoundFile;
};


// Enumeration of animation states
enum AnimationStates
{
	WALKING = 0,
	STANDING,
	KNEEL_DOWN,
	CROUCHING,
	KNEEL_UP,
	SWATTING,
	RUNNING,
	PRONE_DOWN,
	CRAWLING,
	PRONE_UP,
	PRONE,
	READY_RIFLE_STAND,
	AIM_RIFLE_STAND,
	SHOOT_RIFLE_STAND,
	END_RIFLE_STAND,
	START_SWAT,
	END_SWAT,
	FLYBACK_HIT,
	READY_RIFLE_PRONE,
	AIM_RIFLE_PRONE,
	SHOOT_RIFLE_PRONE,
	END_RIFLE_PRONE,
	FALLBACK_DEATHTWICH,
	GENERIC_HIT_STAND,
	FLYBACK_HIT_BLOOD_STAND,
	FLYBACK_HIT_DEATH,
	READY_RIFLE_CROUCH,
	AIM_RIFLE_CROUCH,
	SHOOT_RIFLE_CROUCH,
	END_RIFLE_CROUCH,
	FALLBACK_HIT_STAND,
	ROLLOVER,
	CLIMBUPROOF,
	FALLOFF,
	GETUP_FROM_ROLLOVER,
	CLIMBDOWNROOF,
	FALLFORWARD_ROOF,
	GENERIC_HIT_DEATHTWITCHNB,
	GENERIC_HIT_DEATHTWITCHB,
	FALLBACK_HIT_DEATHTWITCHNB,
	FALLBACK_HIT_DEATHTWITCHB,
	GENERIC_HIT_DEATH,
	FALLBACK_HIT_DEATH,
	GENERIC_HIT_CROUCH,
	STANDING_BURST,
	STANDING_BURST_HIT,
	FALLFORWARD_FROMHIT_STAND,
	FALLFORWARD_FROMHIT_CROUCH,
	ENDFALLFORWARD_FROMHIT_CROUCH,
	GENERIC_HIT_PRONE,
	PRONE_HIT_DEATH,
	PRONE_LAY_FROMHIT,
	PRONE_HIT_DEATHTWITCHNB,
	PRONE_HIT_DEATHTWITCHB,

	ADULTMONSTER_BREATHING,
	ADULTMONSTER_WALKING,
	ADULTMONSTER_ATTACKING,

	FLYBACK_HITDEATH_STOP,
	FALLFORWARD_HITDEATH_STOP,
	FALLBACK_HITDEATH_STOP,
	PRONE_HITDEATH_STOP,

	FLYBACKHIT_STOP,
	FALLBACKHIT_STOP,
	FALLOFF_STOP,
	FALLOFF_FORWARD_STOP,
	STAND_FALLFORWARD_STOP,
	PRONE_LAYFROMHIT_STOP,

	HOPFENCE,

	ADULTMONSTER_HIT,
	ADULTMONSTER_DYING,
	ADULTMONSTER_DYING_STOP,

	PUNCH_BREATH,
	PUNCH,
	NOTHING_STAND,

	JFK_HITDEATH,
	JFK_HITDEATH_STOP,
	JFK_HITDEATH_TWITCHB,

	FIRE_STAND_BURST_SPREAD,

	FALLOFF_DEATH,
	FALLOFF_DEATH_STOP,
	FALLOFF_TWITCHB,
	FALLOFF_TWITCHNB,

	FALLOFF_FORWARD_DEATH,
	FALLOFF_FORWARD_DEATH_STOP,
	FALLOFF_FORWARD_TWITCHB,
	FALLOFF_FORWARD_TWITCHNB,

	OPEN_DOOR,
	OPEN_STRUCT,

	PICKUP_ITEM,
	DROP_ITEM,

	SLICE,
	STAB,
	CROUCH_STAB,


	START_AID,
	GIVING_AID,
	END_AID,

	DODGE_ONE,

	FATCIV_ASS_SCRATCH,

	READY_DUAL_STAND,
	AIM_DUAL_STAND,
	SHOOT_DUAL_STAND,
	END_DUAL_STAND,

	RAISE_RIFLE,
	LOWER_RIFLE,

	BODYEXPLODING,

	THROW_ITEM,
	LOB_ITEM,

	QUEEN_MONSTER_BREATHING,

	CROUCHED_BURST,
	PRONE_BURST,

	NOTUSEDANIM1,

	BIGBUY_FLEX,
	BIGBUY_STRECH,
	BIGBUY_SHOEDUST,
	BIGBUY_HEADTURN,

	MINIGIRL_STOCKING,

	GIVE_ITEM,

	CLIMB_CLIFF,

	COW_EATING,
	COW_HIT,
	COW_DYING,
	COW_DYING_STOP,

	WATER_HIT,
	WATER_DIE,
	WATER_DIE_STOP,

	CROW_WALK,
	CROW_TAKEOFF,
	CROW_LAND,
	CROW_FLY,
	CROW_EAT,

	HELIDROP,

	FEM_CLEAN,
	FEM_KICKSN,
	FEM_LOOK,
	FEM_WIPE,

	REG_SQUISH,
	REG_PULL,
	REG_SPIT,

	HATKID_YOYO,
	KID_ARMPIT,

	MONSTER_CLOSE_ATTACK,
	MONSTER_SPIT_ATTACK,
	MONSTER_BEGIN_EATTING_FLESH,
	MONSTER_EATTING_FLESH,
	MONSTER_END_EATTING_FLESH,

	BLOODCAT_RUN,
	BLOODCAT_STARTREADY,
	BLOODCAT_READY,
	BLOODCAT_ENDREADY,
	BLOODCAT_HIT,
	BLOODCAT_DYING,
	BLOODCAT_DYING_STOP,
	BLOODCAT_SWIPE,

	NINJA_GOTOBREATH,
	NINJA_BREATH,
	NINJA_LOWKICK,
	NINJA_PUNCH,
	NINJA_SPINKICK,

	END_OPEN_DOOR,
	END_OPEN_LOCKED_DOOR,

	KICK_DOOR,

	CLOSE_DOOR,

	RIFLE_STAND_HIT,

	DEEP_WATER_TRED,
	DEEP_WATER_SWIM,
	DEEP_WATER_HIT,
	DEEP_WATER_DIE,
	DEEP_WATER_DIE_STOPPING,
	DEEP_WATER_DIE_STOP,

	LOW_TO_DEEP_WATER,
	DEEP_TO_LOW_WATER,

	GOTO_SLEEP,
	SLEEPING,
	WKAEUP_FROM_SLEEP,

	FIRE_LOW_STAND,
	FIRE_BURST_LOW_STAND,

	LARVAE_BREATH,
	LARVAE_HIT,
	LARVAE_DIE,
	LARVAE_DIE_STOP,
	LARVAE_WALK,

	INFANT_HIT,
	INFANT_DIE,
	INFANT_DIE_STOP,
	INFANT_ATTACK,
	INFANT_BEGIN_EATTING_FLESH,
	INFANT_EATTING_FLESH,
	INFANT_END_EATTING_FLESH,

	MONSTER_UP,
	MONSTER_JUMP,

	STANDING_SHOOT_UNJAM,
	CROUCH_SHOOT_UNJAM,
	PRONE_SHOOT_UNJAM,
	STANDING_SHOOT_DWEL_UNJAM,
	STANDING_SHOOT_LOW_UNJAM,

	READY_DUAL_CROUCH,
	AIM_DUAL_CROUCH,
	SHOOT_DUAL_CROUCH,
	END_DUAL_CROUCH,
	CROUCH_SHOOT_DWEL_UNJAM,

	ADJACENT_GET_ITEM,

	CUTTING_FENCE,

	CRIPPLE_BEG,
	CRIPPLE_HIT,
	CRIPPLE_DIE,
	CRIPPLE_DIE_STOP,
	CRIPPLE_DIE_FLYBACK,
	CRIPPLE_DIE_FLYBACK_STOP,
	CRIPPLE_KICKOUT,

	FROM_INJURED_TRANSITION,

	THROW_KNIFE,
	KNIFE_BREATH,
	KNIFE_GOTOBREATH,
	KNIFE_ENDBREATH,

	ROBOTNW_HIT,
	ROBOTNW_DIE,
	ROBOTNW_DIE_STOP,

	CATCH_STANDING,
	CATCH_CROUCHED,

	PLANT_BOMB,
	USE_REMOTE,

	START_COWER,
	COWERING,
	END_COWER,

	STEAL_ITEM,

	SHOOT_ROCKET,

	CIV_DIE2,

	SHOOT_MORTAR,

	CROW_DIE,

	SIDE_STEP,
	WALK_BACKWARDS,
	BEGIN_OPENSTRUCT,
	END_OPENSTRUCT,
	END_OPENSTRUCT_LOCKED,

	PUNCH_LOW,
	PISTOL_SHOOT_LOW,

	DECAPITATE,

	BLOODCAT_BITE_ANIM,

	BIGMERC_IDLE_NECK,
	BIGMERC_CROUCH_TRANS_INTO,
	BIGMERC_CROUCH_TRANS_OUTOF,

	GOTO_PATIENT,
	BEING_PATIENT,
	GOTO_DOCTOR,
	BEING_DOCTOR,
	END_DOCTOR,
	GOTO_REPAIRMAN,
	BEING_REPAIRMAN,
	END_REPAIRMAN,

	FALL_INTO_PIT,

	ROBOT_WALK,
	ROBOT_SHOOT,

	QUEEN_HIT,
	QUEEN_DIE,
	QUEEN_DIE_STOP,
	QUEEN_INTO_READY,
	QUEEN_READY,
	QUEEN_END_READY,
	QUEEN_CALL,
	QUEEN_SPIT,
	QUEEN_SWIPE,

	RELOAD_ROBOT,

	END_CATCH,
	END_CROUCH_CATCH,

	AI_RADIO,
	AI_CR_RADIO,

	TANK_SHOOT,
	TANK_BURST,

	QUEEN_SLAP,
	SLAP_HIT,

	TAKE_BLOOD_FROM_CORPSE,

	VEHICLE_DIE,

	QUEEN_FRUSTRATED_SLAP,

	CHARIOTS_OF_FIRE,

	AI_PULL_SWITCH,

	MONSTER_MELT,

	MERC_HURT_IDLE_ANIM,
	END_HURT_WALKING,

	PASS_OBJECT,
	DROP_ADJACENT_OBJECT,

	READY_DUAL_PRONE,
	AIM_DUAL_PRONE,
	SHOOT_DUAL_PRONE,
	END_DUAL_PRONE,
	PRONE_SHOOT_DWEL_UNJAM,

	PICK_LOCK,

	OPEN_DOOR_CROUCHED,
	BEGIN_OPENSTRUCT_CROUCHED,
	CLOSE_DOOR_CROUCHED,
	OPEN_STRUCT_CROUCHED,
	END_OPEN_DOOR_CROUCHED,
	END_OPENSTRUCT_CROUCHED,
	END_OPEN_LOCKED_DOOR_CROUCHED,
	END_OPENSTRUCT_LOCKED_CROUCHED,

	DRUNK_IDLE,
	CROWBAR_ATTACK,

	CIV_COWER_HIT,
	BLOODCAT_WALK_BACKWARDS,
	MONSTER_WALK_BACKWARDS,
	KID_SKIPPING,
	ROBOT_BURST_SHOOT,
	ATTACH_CAN_TO_STRING,
	SWAT_BACKWARDS,
	JUMP_OVER_BLOCKING_PERSON,
	REFUEL_VEHICLE,
	ROBOT_CAMERA_NOT_MOVING,
	CRIPPLE_OPEN_DOOR,
	CRIPPLE_CLOSE_DOOR,
	CRIPPLE_END_OPEN_DOOR,
	CRIPPLE_END_OPEN_LOCKED_DOOR,
	LOCKPICK_CROUCHED,

	NUMANIMATIONSTATES
};


extern UINT16                gusAnimInst[MAX_ANIMATIONS][MAX_FRAMES_PER_ANIM];
extern const ANIMCONTROLTYPE gAnimControl[NUMANIMATIONSTATES];

extern const ANI_SPEED_DEF gubAnimWalkSpeeds[];
extern const ANI_SPEED_DEF gubAnimRunSpeeds[];
extern const ANI_SPEED_DEF gubAnimSwatSpeeds[];
extern const ANI_SPEED_DEF gubAnimCrawlSpeeds[];


// OK, this array contains definitions for random animations based on
// bodytype, total # allowed, and what is in their hand....
extern RANDOM_ANI_DEF gRandomAnimDefs[][MAX_RANDOM_ANIMS_PER_BODYTYPE];

// Corpse Defines
extern UINT16 gubAnimSurfaceCorpseID[][NUMANIMATIONSTATES];


void LoadAnimationStateInstructions(void);
void InitAnimationSurfacesPerBodytype(void);
bool IsAnimationValidForBodyType(SOLDIERTYPE const&, UINT16 new_state);
UINT16 SubstituteBodyTypeAnimation(const SOLDIERTYPE* s, UINT16 anim_state);
char const* GetBodyTypePaletteSubstitution(SOLDIERTYPE const*, UINT8 ubBodyType);

BOOLEAN SetSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimState );
UINT16 DetermineSoldierAnimationSurface(const SOLDIERTYPE* pSoldier, UINT16 usAnimState);
UINT16 LoadSoldierAnimationSurface(SOLDIERTYPE&, UINT16 anim_state);

// This function could be wrapped in a debug marco, since it only returns pSoldier->ubAnimSurface but
// Also does some debug checking
UINT16 GetSoldierAnimationSurface(SOLDIERTYPE const*);

#endif
