#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "effects.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "aura.h"
#include "classes.h"
#include "gamerules.h"
#include "chargedattack.h"
#include "magicattack.h"
#include "explodingattack.h"
#include "player.h"
#include "../common/particletypes.h"
#define FLAMETHROWER_ATTACKINTERVAL 0.01
extern int gmsgAddEffect;
extern int gmsgUpdateEffect;
extern int gmsgRemoveEffect;

/**
* Flamethrower
* @version 14-4-2004
* @author Herwin 'harSens' van Welbergen
*/
class CFlameThrower:public CBasePlayerWeapon
{	
public:
	/**
	* Init function
	*/
	void Spawn( void );

	/**
	* Precaches sprites and sounds
	*/
	void Precache( void );

	/**
	* Get  flamethrower slot
	* return int: the slot, is 7 for flamethrower
	*/
	int iItemSlot( void ) { return 7; }

	/**
	 * Deploys the flamethrower
	 */
	BOOL Deploy();

	/**
	* Get flamthrower item info
	* @param ItemInfo *p: The ItemInfo gets stored here
	* @return int: Always returns 1 (why???)
	*/
	int GetItemInfo(ItemInfo *p);

	void PrimaryAttack();
	void SecondaryAttack();
	void WeaponIdle();	
	void Holster(int skiplocal);
private:
	/**
	 * Creates the flamethrower flame
	 */
	void CreateFlame();

	/**
	 * Disables the flame
	 */
	void DisableFlame();
	
	/**
	 * Grow the flame
	 */
	void GrowFlame();
	int m_iRadius;
	bool m_fShooting;
	int m_iDamageCounter;
};

LINK_ENTITY_TO_CLASS( weapon_flamethrower, CFlameThrower );

void CFlameThrower::Spawn( void )
{	Precache();
	m_iId = WEAPON_FLAMETHROWER;
	m_iDefaultAmmo = 0;
	m_iClip = -1;

	FallInit();// get ready to fall down.
}

void CFlameThrower::Precache( void )
{	
}

int CFlameThrower::GetItemInfo(ItemInfo *p)
{	p->pszName = STRING(pev->classname);
	p->pszAmmo1 = "ki";
	p->iMaxAmmo1 = -1;	//max ammo is weapon independent
	p->pszAmmo2 = NULL;
	p->iMaxAmmo2 = -1;
	p->iMaxClip = WEAPON_NOCLIP;
	p->iSlot = 6;
	p->iPosition = 5;
	p->iId = m_iId = WEAPON_FLAMETHROWER;
	p->iWeight = FLAMETHROWER_WEIGHT;
	p->iFlags = 0;
	return 1;
}

BOOL CFlameThrower::Deploy()
{
	m_fShooting = false;
	m_iDamageCounter =0;
	return DefaultDeploy("flamethrower");
}

void CFlameThrower::Holster(int skiplocal)
{
	if(m_fShooting)
	{
		DisableFlame();
	}
}

void CFlameThrower::WeaponIdle()
{
	if(m_fShooting)
	{
		DisableFlame();
	}
}

void CFlameThrower::PrimaryAttack()
{
	if(m_fShooting)
	{
		if(m_iDamageCounter==0)
		{
			GrowFlame();
		}
		//find players in cone
		UTIL_MakeVectors(m_pPlayer->pev->v_angle);
		Vector vecForward = gpGlobals->v_forward;

		CBaseEntity *pEnt = NULL;	
		while ((pEnt = UTIL_FindEntityInSphere( pEnt, m_pPlayer->pev->origin, m_iRadius)) != NULL)
		{
			if(pEnt->IsPlayer())
			{
				CBasePlayer *pPlayer = (CBasePlayer*)pEnt;
				double angle = acos(DotProduct(vecForward,(pPlayer->pev->origin-m_pPlayer->pev->origin).Normalize()));
				if(angle<FLAMETHROWER_ANGLE && pPlayer!= m_pPlayer)
				{
					pPlayer->m_fBurning = true;
					pPlayer->m_pBurner = m_pPlayer;
					//ALERT(at_console,"Burning\n");
					if(m_iDamageCounter==0)
					{
						pPlayer->TakeDamage(m_pPlayer->pev,m_pPlayer->pev,(double)m_iRadius/(double)FLAMETHROWER_MAXRADIUS*FLAMETHROWER_DAMAGE*GetPowerRatio(),DMG_MAGIC);
					}
				}
			}
			
		
		}	
		m_iDamageCounter++;
		if(m_iDamageCounter>10)
		{
			m_iDamageCounter=0;
		}
	}
	else
	{
		ALERT(at_console,"Creating flame");
		CreateFlame();		
	}
	m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + FLAMETHROWER_ATTACKINTERVAL;
}

void CFlameThrower::SecondaryAttack()
{
	WeaponIdle();
}

void CFlameThrower::DisableFlame()
{
	m_fShooting = false;
	MESSAGE_BEGIN( MSG_ALL, gmsgRemoveEffect);
		WRITE_BYTE(FLAMETHROWER);
		WRITE_SHORT(m_pPlayer->entindex());		
	MESSAGE_END();
}

void CFlameThrower::GrowFlame()
{
	if(m_iRadius<FLAMETHROWER_MAXRADIUS)
	{
		//update radius
		m_iRadius += 10* FLAMETHROWER_ATTACKINTERVAL * ((FLAMETHROWER_MAXRADIUS-FLAMETHROWER_MINRADIUS)/FLAMETHROWER_MAXCHARGETIME);
		if(m_iRadius > FLAMETHROWER_MAXRADIUS) 
		{
			m_iRadius = FLAMETHROWER_MAXRADIUS;
		}
		MESSAGE_BEGIN( MSG_ALL, gmsgUpdateEffect);
			WRITE_BYTE(FLAMETHROWER);
			WRITE_SHORT(m_pPlayer->entindex());
			WRITE_SHORT(m_iRadius);		
		MESSAGE_END();	
	}
	else
	{	//just burn lots of ki
	}
}

void CFlameThrower::CreateFlame()	
{	
	m_iDamageCounter=0;
	m_fShooting = true;
	UTIL_MakeVectors( m_pPlayer->pev->v_angle );
	Vector vecSrc = m_pPlayer->GetGunPosition() + gpGlobals->v_right * 10 + gpGlobals->v_forward * 10;
	
	m_iRadius = FLAMETHROWER_MINRADIUS; 
	MESSAGE_BEGIN( MSG_ALL, gmsgAddEffect);
		WRITE_BYTE(FLAMETHROWER);
		WRITE_SHORT(m_pPlayer->entindex());
		WRITE_SHORT(m_iRadius);		
	MESSAGE_END();		
}