#include	"world.h"

#include	"ai.h"
#include	"ai_utils.h"

#include	"ai_move.h"
#include	"ai_weapons.h"
#include	"ai_task.h"
#include	"ai_frames.h"

#include	"skat.h"
#include	"nodelist.h"

////////////////////////////////////////////////////////////////////////////////
// exports
////////////////////////////////////////////////////////////////////////////////

DllExport	void	monster_ragemaster (userEntity_t *self);

////////////////////////////////////////////////////////////////////////////////
//	globals
////////////////////////////////////////////////////////////////////////////////

static	int	rage_count	= 0;

///////////////////////////////////////////////////////////////////////////////////
// ragemaster specific funcitons
///////////////////////////////////////////////////////////////////////////////////

void	ragemaster_attack (userEntity_t *self);
void	ragemaster_attack_left_right (userEntity_t *self);

////////////////////////////////
//	rage_init_frametable
//
////////////////////////////////

void	rage_init_frametable (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;

	ai_set_sequence_data (self, hook->frames->atak [0], -1, NULL, -1, NULL, 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [1], 9, "monsters/ragemaster/ragemasterattack1.wav", 23, "monsters/ragemaster/ragemasterattack1.wav", 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [2], 11, "monsters/ragemaster/ragemasterattack1.wav", -1, NULL, 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [4], 11, "monsters/ragemaster/ragemasterattack1.wav", 21, "monsters/ragemaster/ragemasterattack1.wav", 0, -1, 0, -1, FRAME_ONCE);

	ai_set_sequence_data (self, hook->frames->walk [0], 0, "models/ragemaster/ragesteps1.wav", 14, "models/ragemaster/ragesteps2.wav", 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->run [0], 0, "models/ragemaster/ragesteps1.wav", 14, "models/ragemaster/ragesteps2.wav", 0, -1, 0, -1, FRAME_ONCE);
}

///////////////////////////////////////////////////////////////////////////////
//	
//
///////////////////////////////////////////////////////////////////////////////

void	ragemaster_set_attack_seq (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	int				i;
	float			dist;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (dist > 80)
	{
		ai_init_sequence (self, hook->frames->atak [4], SEQUENCE_ATAK, 3);

		ragemaster_attack_left_right (self);
	}
	else
	{
		i = rand () % 2;
		if (i == 0)
			ai_init_sequence (self, hook->frames->atak [1], SEQUENCE_ATAK, 1);
		else
			ai_init_sequence (self, hook->frames->atak [2], SEQUENCE_ATAK, 2);

		self->curWeapon = gstate->InventoryFindItem (self->inventory, "wack back");
		ragemaster_attack (self);
	}
}

///////////////////////////////////////////////////////////////////////////////
//	ragemaster_attack_left_right
//
///////////////////////////////////////////////////////////////////////////////

void	ragemaster_attack_left_right (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	float			dist;
	
	//ai_face_enemy (self);
	hook->dflags |= DFL_FACEENEMY;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (hook->frame_flags & FRAME_PLAYSOUND1)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND1;

		self->curWeapon = gstate->InventoryFindItem (self->inventory, "wack left");
		ai_fire_curWeapon (self, Vector (self->s.origin), Vector (self->enemy->s.origin), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_PLAYSOUND2)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND2;
		
		self->curWeapon = gstate->InventoryFindItem (self->inventory, "wack right");
		ai_fire_curWeapon (self, Vector (self->s.origin), Vector (self->enemy->s.origin), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_STATIC)
	{
		hook->frame_flags -= FRAME_STATIC;

		ragemaster_set_attack_seq (self);

		if (self->enemy->deadflag != DEAD_NO)
		{
			//	pop off everything thru TASK_CHASE and begin wandering
			ai_killed_enemy (self);

			return;
		}
		else if (dist > hook->attack_dist || !com->Visible (self, self->enemy))
		{
			ai_should_follow (self);

			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			return;
		}
	}

	ai_set_think (self, ragemaster_attack, "ragemaster_attack");
}

///////////////////////////////////////////////////////////////////////////////
//	ragemaster_attack
//
///////////////////////////////////////////////////////////////////////////////

void	ragemaster_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	float			dist;
	
	//ai_face_enemy (self);
	hook->dflags |= DFL_FACEENEMY;

	dist = qv_dist (self->s.origin, self->enemy->s.origin);

	if (hook->frame_flags & FRAME_PLAYSOUND1)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND1;
				
		ai_fire_curWeapon (self, Vector (self->s.origin), Vector (self->enemy->s.origin), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_PLAYSOUND2)
	{
		hook->frame_flags = hook->frame_flags - FRAME_PLAYSOUND2;
				
		ai_fire_curWeapon (self, Vector (self->s.origin), Vector (self->enemy->s.origin), 0, 0);
	}
	
	if (hook->frame_flags & FRAME_STATIC)
	{
		hook->frame_flags -= FRAME_STATIC;

		ragemaster_set_attack_seq (self);

		if (self->enemy->deadflag != DEAD_NO)
		{
			//	pop off everything thru TASK_CHASE and begin wandering
			ai_killed_enemy (self);

			return;
		}
		else if (dist > hook->attack_dist || !com->Visible (self, self->enemy))
		{
			ai_should_follow (self);

			//	leaving, so pop off TASK_ATTACK
			task_pop (&hook->task_stack);

			return;
		}
	}

	ai_set_think (self, ragemaster_attack, "ragemaster_attack");
}

///////////////////////////////////////////////////////////////////////////////
//	ragemaster_begin_attack
//
///////////////////////////////////////////////////////////////////////////////

void	ragemaster_begin_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;

	com->ZeroVector (self->velocity);

	hook->th_state = TH_ATTACK;
	hook->attack_finished = gstate->time + 1.0;

	ragemaster_set_attack_seq (self);
}

///////////////////////////////////////////////////////////////////////////////
//	monster_ragemaster
//
//	spawns a skeleton during level load
///////////////////////////////////////////////////////////////////////////////

void	monster_ragemaster (userEntity_t *self)
{
	playerHook_t		*hook;
	int					i;

	rage_count++;

	hook = ai_init_monster (self, TYPE_RAGEMASTER);

	self->className = "monster_ragemaster";
	self->netname = "Roboco RageMaster 5000";

	gstate->SoundIndex ("monsters/ragemaster/ragesteps1.wav");
	gstate->SoundIndex ("monsters/ragemaster/ragesteps2.wav");

	self->s.modelindex = gstate->ModelIndex ("models/ragemaster/ragemaster.md2");
	gstate->SetSize (self, -24.0, -24.0, -24.0, 24.0, 24.0, 64.0);

	////////////////////////////////////////////////////////////////
	// set up animation stuff
	////////////////////////////////////////////////////////////////

	ai_get_sequences (self);
	rage_init_frametable (self);

	///////////////////////////////////////////////////////////
	// set up pointers to this creature's ai functions
	///////////////////////////////////////////////////////////

	hook->begin_attack = ragemaster_begin_attack;
	hook->dflags |= DFL_MECHANICAL;

	hook->run_speed = 100;
	hook->walk_speed = 50;
	hook->attack_speed = 100;

	hook->attack_dist = 128;

	self->health = 200;
	hook->max_health = 200;
	hook->pain_chance = 10;
	self->mass = 2.0;

	self->think = ai_get_spawn_node;
	self->nextthink = gstate->time + 0.2;	// node links are set up 0.2 secs after map load

	self->translucent = 0;

	///////////////////////////////////////////////////////////////////////////
	//	give ragemaster a weapon
	///////////////////////////////////////////////////////////////////////////

	self->inventory = gstate->InventoryNew ();

	self->curWeapon = ai_init_weapon (self, 20, 40, 0.024, 0, 0, hook->attack_dist, Vector (24, 16, 24), "wack right", wack_right, WEAPON_TRACE);
	gstate->InventoryAddItem (self->inventory, self->curWeapon);

	self->curWeapon = ai_init_weapon (self, 20, 40, 0.024, 0, 0, hook->attack_dist, Vector (-24, 16, 24), "wack left", wack_left, WEAPON_TRACE);
	gstate->InventoryAddItem (self->inventory, self->curWeapon);	

	self->curWeapon = ai_init_weapon (self, 20, 40, 0.024, 0, 0, hook->attack_dist, Vector (0,  16, 24), "wack back", wack_back, WEAPON_TRACE);
	gstate->InventoryAddItem (self->inventory, self->curWeapon);	
}

