#ifndef __A_ARTIFACTS_H__
#define __A_ARTIFACTS_H__

#include "a_pickups.h"

class player_t;

// A powerup is a pseudo-inventory item that applies an effect to its
// owner while it is present.
class APowerup : public AInventory
{
	DECLARE_CLASS (APowerup, AInventory)
public:
	virtual void Tick () override;
	virtual void OnDestroy() override;
	virtual bool HandlePickup (AInventory *item) override;
	virtual AInventory *CreateCopy (AActor *other) override;
	virtual AInventory *CreateTossable () override;
	virtual void Serialize(FSerializer &arc) override;
	virtual void OwnerDied () override;
	virtual PalEntry GetBlend () override;
	virtual bool DrawPowerup (int x, int y) override;
	bool IsActiveRune(); // [TP]

	int EffectTics;
	PalEntry BlendColor;
	FNameNoInit Mode;
	double Strength;

public:
	virtual void InitEffect ();
	virtual void DoEffect () override;
	virtual void EndEffect ();
	bool isBlinking() const;

protected:
	void CallInitEffect();
	void CallEndEffect();

	friend void EndAllPowerupEffects(AInventory *item);
	friend void InitAllPowerupEffects(AInventory *item);
};

// An artifact is an item that gives the player a powerup when activated.
class APowerupGiver : public AInventory
{
	DECLARE_CLASS (APowerupGiver, AInventory)
	HAS_OBJECT_POINTERS
public:
	virtual bool Use (bool pickup) override;
	virtual void Serialize(FSerializer &arc) override;


	// [TP] For runes
	virtual void PowerupGranted ( APowerup* ) {}
	virtual void ModifyPowerup ( APowerup* ) {}

	PClassActor *PowerupType;
	int EffectTics;			// Non-0 to override the powerup's default tics
	PalEntry BlendColor;	// Non-0 to override the powerup's default blend
	FNameNoInit Mode;		// Meaning depends on powerup - used for Invulnerability and Invisibility
	double Strength;		// Meaning depends on powerup - currently used only by Invisibility
};

class APowerInvulnerable : public APowerup
{
	DECLARE_CLASS (APowerInvulnerable, APowerup)
protected:
	virtual void InitEffect () override;
	virtual void DoEffect () override;
	virtual void EndEffect () override;
	virtual int AlterWeaponSprite (visstyle_t *vis) override;
};

class APowerStrength : public APowerup
{
	DECLARE_CLASS (APowerStrength, APowerup)
public:
	PalEntry GetBlend ();
protected:
	virtual void InitEffect () override;
	virtual void Tick () override;
	virtual bool HandlePickup (AInventory *item) override;
};

class APowerInvisibility : public APowerup
{
	DECLARE_CLASS (APowerInvisibility, APowerup)
protected:
	virtual bool HandlePickup (AInventory *item) override;
	virtual void InitEffect () override;
	virtual void DoEffect () override;
	virtual void EndEffect () override;
	virtual int AlterWeaponSprite (visstyle_t *vis) override;
};

class APowerIronFeet : public APowerup
{
	DECLARE_CLASS (APowerIronFeet, APowerup)
public:
	virtual void AbsorbDamage (int damage, FName damageType, int &newdamage) override;
	virtual void DoEffect () override;
};

class APowerMask : public APowerIronFeet
{
	DECLARE_CLASS (APowerMask, APowerIronFeet)
public:
	virtual void AbsorbDamage (int damage, FName damageType, int &newdamage) override;
	virtual void DoEffect () override;
};

class APowerLightAmp : public APowerup
{
	DECLARE_CLASS (APowerLightAmp, APowerup)
protected:
	virtual void DoEffect () override;
	virtual void EndEffect () override;
};

class APowerTorch : public APowerLightAmp
{
	DECLARE_CLASS (APowerTorch, APowerLightAmp)
public:
	
	virtual void Serialize(FSerializer &arc) override;
protected:
	virtual void DoEffect () override;
	int NewTorch, NewTorchDelta;
};

class APowerFlight : public APowerup
{
	DECLARE_CLASS (APowerFlight, APowerup)
public:
	virtual bool DrawPowerup (int x, int y) override;
	virtual void Serialize(FSerializer &arc) override;

protected:
	virtual void InitEffect () override;
	virtual void Tick () override;
	virtual void EndEffect () override;

private:
	bool HitCenterFrame;
};

class APowerWeaponLevel2 : public APowerup
{
	DECLARE_CLASS (APowerWeaponLevel2, APowerup)
protected:
	virtual void InitEffect () override;
	virtual void EndEffect () override;
};

class APowerSpeed : public APowerup
{
	DECLARE_CLASS (APowerSpeed, APowerup)
protected:
	virtual void DoEffect () override;
	
	virtual void Serialize(FSerializer &arc) override;
public:
	int SpeedFlags;
};

#define PSF_NOTRAIL		1

class APowerTargeter : public APowerup
{
	DECLARE_CLASS (APowerTargeter, APowerup)
protected:
	virtual void InitEffect () override;
	virtual void DoEffect () override;
	virtual void EndEffect () override;
	void PositionAccuracy ();
	virtual void Travelled () override;
	virtual void AttachToOwner(AActor *other) override;
	virtual bool HandlePickup(AInventory *item) override;
};

class APowerMorph : public APowerup
{
	DECLARE_CLASS( APowerMorph, APowerup )
	HAS_OBJECT_POINTERS
public:
	
	virtual void Serialize(FSerializer &arc) override;

	// Variables
	PClassPlayerPawn *PlayerClass;
	PClassActor *MorphFlash, *UnMorphFlash;
	int MorphStyle;
	player_t *MorphedPlayer;
};

// [BC] Start of new Skulltag powerup types.
class APowerPossessionArtifact : public APowerup
{
	DECLARE_CLASS( APowerPossessionArtifact, APowerup )
protected:
	void InitEffect( );
	void DoEffect( );
	void EndEffect( );
};

class APowerTerminatorArtifact : public APowerup
{
	DECLARE_CLASS( APowerTerminatorArtifact, APowerup )
protected:
	void InitEffect( );
	void DoEffect( );
	void EndEffect( );
	virtual void ModifyDamage( int damage, FName damageType, int &newdamage, bool passive );
};

class APowerTranslucency : public APowerInvisibility
{
	DECLARE_CLASS (APowerTranslucency, APowerInvisibility)
protected:
	void InitEffect ();
};

// [BC] A rune is like a powerup, except its effect lasts until a new rune is picked up,
// or the owner dies. Only one rune may be carried at once.
class ARuneGiver : public APowerupGiver
{
	DECLARE_CLASS( ARuneGiver, APowerupGiver )
public:
	void PowerupGranted ( APowerup* power );
	void ModifyPowerup ( APowerup* power );
};

class APowerSpread : public APowerup
{
	DECLARE_CLASS( APowerSpread, APowerup )
protected:
	void InitEffect();
	void EndEffect();
};

class APowerProsperity : public APowerup
{
	DECLARE_CLASS( APowerProsperity, APowerup )
protected:
	void InitEffect();
	void EndEffect();
};

class APowerReflection : public APowerup
{
	DECLARE_CLASS( APowerReflection, APowerup )
protected:
	void InitEffect();
	void EndEffect();
};


class player_t;

#endif //__A_ARTIFACTS_H__
