#ifndef STWEAPON_H
#define STWEAPON_H

// Forward
class gzWeaponDropClass;
struct gzBackpackSoldierData;
struct gzWeaponLevelStruct;
struct gzWeaponBan;


/************/
/* Settings */
/************/
struct gzPowerupWeaponStruct {
	aString powerup;
	aString weapon;
};

struct gzSettingsWeaponC4 {
	bool Output[3][3];
	int Limit[3];
	int TeamLimit[2][3];
	bool CanFlaming;
};
struct gzSettingsWeaponBackpackStruct {
	float OwnTime;
	float Live;
	aVector<gzBackpackSoldierData *> DropData;
};
struct gzSettingsWeaponStruct {
	aVector<gzWeaponBan *> Ban;
	aVector<gzWeaponLevelStruct *> Level;
	bool	CarryOverOnCharacterPurchase;
	bool	DropOnDeath;
	float	DropDelay;
};
class gzSettingsWeaponClass : public stSettingsBase {
public:
	const char *GetName()
	{
		return "gzSettingsWeaponClass";
	};
	void Delete();
	void Load();

	int m_BeaconLimit;

	gzSettingsWeaponC4 C4;
	gzSettingsWeaponBackpackStruct Backpack;
	gzSettingsWeaponStruct Weapons;

	int m_pedWinMinScoreDiff;
};


/******************/
/* Weapon manager */
/******************/
class gzWeaponManager : public EventHandler, public gzSettingsEvent {
public:
	const char *GetName()
	{
		return "gzWeaponManager";
	};
	gzWeaponManager();
	void Delete() { };
	void Settings_Loaded() { };
	void Object_C4Detonate(gzEventObjectC4Detonation &);

	gzSettingsWeaponClass *m_settings;
};
extern gzWeaponManager *gzWeaponMgr;


/************/
/* Backpack */
/************/
struct gzBackpackSoldierPercentData {
	aString powerup;
	unsigned int percent;
	aString sound;
};
struct gzBackpackSoldierData {
	aString preset;
	aVector<gzBackpackSoldierPercentData *> m_weapons;
	int totalpercent;
};

class gzWeaponPackClass;
class gzBackpackClass : public EventHandler, public gzManagerEvent {
	gzWeaponPackClass *m_pack;
	nc_cPlayer *m_owner; // Backpack owner - other players can't pick it until it times out
	float m_ownerExpireCounter;
	unsigned int m_effectId;
	bool m_canExpire;
	float m_liveCounter;
	unsigned int m_backpackId;
	nc_Vector3 m_pos;
public:
	const char *GetName()
	{
		return "gzBackpackClass";
	};
	gzBackpackClass();
	void Delete();
	void Think();
	void Object_PowerupGrant(gzEventObjectPowerupGrant &);
	void ChildObjDeletion(gzBase *);
	void Create();
	gzWeaponPackClass *GetWeaponPack();
	void SetWeaponPack(gzWeaponPackClass *);
	nc_cPlayer *GetOwner();
	void SetOwner(nc_cPlayer *);
	void SetCanExpire(bool);
	void SetLive(float);
	unsigned int GetBackpackId();
	nc_Vector3 &GetPosition();
};

class gzBackpackManager : public EventHandler, public gzManagerEvent {
	aVector<gzBackpackClass *> m_backpackList;
public:
	const char *GetName()
	{
		return "gzBackpackManager";
	};
	gzBackpackManager();
	void Delete();
	void ChildObjDeletion(gzBase *);
	void Level_Ended();
	gzBackpackClass *Add(gzWeaponPackClass *WeaponPack, const nc_Vector3 &Position);
};
extern gzBackpackManager *gzBackpackMgr;


/***************/
/* Weapon pack */
/***************/
struct gzWeaponLevelStruct;
struct gzWeaponBan {
	aString Preset;
	aStringArray WeaponList;
	bool m_all;
};
struct gzWeaponLevelStruct {
	aString Name;
	aStringArray Weapons;
};
struct gzWeaponPackData {
	gzWeaponPackData()
	{
		this->powerup	= NULL;
		this->weapon	= NULL;
	};
	nc_PowerUpGameObjDef *powerup;
	nc_WeaponDefinitionClass *weapon;
};

class gzWeaponPackClass : public gzBase {
public:
	const char *GetName()
	{
		return "gzWeaponPackClass";
	};
	gzWeaponPackClass(bool AddToManager = true);
	gzWeaponPackClass(gzPlayer *owner);
	void Delete();
	void Add_Weapon(const char *);
	void Add_Weapon(nc_DefinitionClass *);
	void Grant();
	void Append(gzWeaponPackClass *, bool giveNow = false);
	void Copy(gzWeaponPackClass *, bool giveNow = false);
	int GetWeaponsCount();
	int Id;
	aVector<gzWeaponPackData> m_list;
	gzPlayer *m_owner;
	gzBackpackSoldierPercentData *m_backpackData;
};

class gzWeaponPackManager : public EventHandler, public gzManagerEvent {
	aVector<gzWeaponPackClass *> m_packList;
	int nextPackId;
public:
	const char *GetName()
	{
		return "gzWeaonPackManager";
	}
	gzWeaponPackManager();
	void Delete();
	void ChildObjDeletion(gzBase *);
	void Level_Ended();
	void Add(gzWeaponPackClass *);
	gzWeaponPackClass *Find(nc_cPlayer *);
};
extern gzWeaponPackManager *gzWeaponPack;


/***************/
/* Weapon drop */
/***************/

class gzWeaponDropClass : public gzBackpackClass {
	float m_dropDelayCounter;
public:
	gzWeaponDropClass();
	void Delete();
	void Level_Ended();
	void Think();
	void Player_Left(gzEventPlayerBase &);
	void Object_PowerupGrant(gzEventObjectPowerupGrant &);
	void Init(gzPlayer *);
	bool Halt();
	unsigned int m_soldierId;
};

class gzWeaponDropManager : public EventHandler {
public:
	const char *GetName()
	{
		return "gzWeaponDropManager";
	};
	void Delete();
	gzWeaponDropClass *Find(nc_cPlayer *);
	aVector<gzWeaponDropClass *> m_list;
};
extern gzWeaponDropManager *gzWeaponDropMgr;


/**********/
/* Beacon */
/**********/
class gzObserverBeacon : public nc_ScriptImpClass {
	void Created(nc_ScriptableGameObj *obj);
	void Custom(nc_ScriptableGameObj *obj, int message, int param, nc_ScriptableGameObj *sender);
	void Damaged(nc_ScriptableGameObj *obj, nc_ScriptableGameObj *damager, float damage);
	void Killed(nc_ScriptableGameObj *obj, nc_ScriptableGameObj *shooter);
	void Timer_Expired(nc_ScriptableGameObj *obj, int number);
	nc_BeaconGameObj *m_Beacon;
	float m_score;
	float m_playerDamage[128];
};


/******/
/* C4 */
/******/
class gzObserverC4 : public nc_ScriptImpClass {
	void Created(nc_ScriptableGameObj *obj);
	void Custom(nc_ScriptableGameObj *obj, int message, int param, nc_ScriptableGameObj *sender);
	void Damaged(nc_ScriptableGameObj *obj, nc_ScriptableGameObj *damager, float damage);
	void Killed(nc_ScriptableGameObj *obj, nc_ScriptableGameObj *shooter);
	void Timer_Expired(nc_ScriptableGameObj *obj, int number);
	nc_C4GameObj *m_C4;
	float m_score;
	float m_playerDamage[128];
	nc_BaseControllerClass *m_base;
};


/********/
/* Misc */
/********/
bool IsBeaconPedApproved(int attemptTeam);

#endif
