#ifndef STEVENT_H
#define STEVENT_H

#include "stbase.h"
#include "steventbase.h"

#pragma warning(disable: 4100)


// Forward
class nc_ScriptableGameObj;
class nc_DamageableGameObj;
class nc_OffenseObjectClass;
class nc_PhysicalGameObj;
class nc_BeaconGameObj;
class nc_SoldierGameObj;
class nc_cPlayer;
class nc_cCsTextObj;
class nc_CSAnnouncement;
class EventHandler;
struct gzPurchaseDataStruct;

enum gzPlayerLeftEnum {
	LEFT_UNKNOWN = -1,
	LEFT_NORMAL,
	LEFT_DISCONNECT,
	LEFT_WOLKICK,
	LEFT_GAMESPYKICK,
	LEFT_GAMESPYEVICT,
};

class EventManager {
public:
	static bool m_eventTypeSort[EVT_COUNT_TYPE][EVT_COUNT_SUBTYPE];
	static aVector<EventHandler *> m_list;
	static EventHandler *ProcessEvent(gzEventBase &);
};

class EventNotifier {
	int m_priority;
	int m_type;
	EventHandler *m_owner;
public:
	EventNotifier();
	int GetPriority() { return this->m_priority; };
	void SetPriority(int priority) { this->m_priority = priority; };
	int GetEventType() { return this->m_type; };
	void SetEventType(int type) { this->m_type = type; };
	EventHandler *GetOwner() { return this->m_owner; };
	void SetOwner(EventHandler *owner) { this->m_owner = owner; };
};

class EventHandler : public gzBase {
	aVector<EventNotifier *> m_eventList;
public:
	EventHandler();
	virtual ~EventHandler();
	void RegisterEvent(int type, int priority = EVT_PRIORITY_DEFAULT);
	void GetEventList(aList<EventNotifier> &ref, int type);

	// Game events
	virtual void Level_Loaded()	{ };
	virtual void Level_Ended() { };
	virtual void Think() { };

	// Player events
	virtual void Player_Joined(gzEventPlayerBase &) { };
	virtual void Player_Left(gzEventPlayerBase &) { };
	virtual void Player_Purchase(gzEventPlayerPurchase &) { };
	virtual void Player_BandwidthChange(gzEventPlayerBandwidth &) { };
	virtual void Player_Suicide(gzEventPlayerBase &) { };
	virtual void Player_TeamChange(gzEventPlayerBase &) { };
	virtual void Player_Chat(gzEventPlayerChat &) { };
	virtual void Player_Radio(gzEventPlayerRadio &) { };
	virtual void Player_SerialHash(gzEventPlayerSerialHash &) { };
	virtual void Player_RawDamage(gzEventObjectDamage &) { };

	// Object events
	virtual void Object_Created(gzEventObjectCreate &) { };
	virtual void Object_Init(gzEventObjectInit &) { };
	virtual void Object_Damaged(gzEventObjectDamage &) { };
	virtual void Object_Killed(gzEventObjectKill &) { };
	virtual void Object_Transition(gzEventObjectTransition &) { };
	virtual void Object_JumpStart(gzEventObjectJump &) { };
	virtual void Object_JumpComplete(gzEventObjectJump &) { };
	virtual void Object_SoldierSquished(gzEventObjectKill &) { };
	virtual void Object_C4Creation(gzEventObjectC4Creation &) { };
	virtual void Object_C4Detonate(gzEventObjectC4Detonation &) { };
	virtual void Object_PowerupGrant(gzEventObjectPowerupGrant &) { };
	virtual void Object_Fire(gzEventObjectFire &) { };
	virtual void Object_FlipKill(gzEventObjectFlipKill &) { };

	// Network events
	virtual void Net_WolPage(gzEventNetWolPage &) { };
	virtual void Net_SerialAuth(gzEventNetSerialAuth &) { };

	// BHS.dll events
	virtual void Bhs_Poke(gzEventBhsPoke &) { };
	virtual void Bhs_Version(gzEventBhsVersion &) { };
};

class gzSettingsEvent {
public:
	virtual void Settings_Loaded() = 0;
};

class gzManagerEvent {
public:
	virtual const char *GetName() = 0;
	virtual void ChildObjCreation(gzBase *) { };
	virtual void ChildObjDeletion(gzBase *) = 0;
};

#endif
