#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"


////////////////////////////////////////////////////////////////////////////////
// defines
////////////////////////////////////////////////////////////////////////////////

static	int	count;

static	int	turnFirst;
static	int	turnLast;

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

DllExport	void	monster_buboid (userEntity_t *self);

///////////////////////////////////////////////////////////////////////////////////
// prototypes
///////////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////////
// buboid specific funcitons
///////////////////////////////////////////////////////////////////////////////////

////////////////////////////////
//	buboid_init_frametable
//
////////////////////////////////

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

	ai_set_sequence_data (self, hook->frames->atak [0], 12, "monsters/buboid/buboidattack1.wav", 20, "monsters/buboid/buboidattack1.wav", 0, -1, 0, -1, FRAME_ONCE);
	ai_set_sequence_data (self, hook->frames->atak [1], 12, "monsters/buboid/buboidattack2.wav", 20, "monsters/buboid/buboidattack2.wav", 0, -1, 0, -1, FRAME_ONCE);
}

////////////////////////////////
//	buboid_set_attack_seq
//
////////////////////////////////

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

	//	FIXME: -1 because last attack is ridiculously lame... remove it from mdl
	i = (int) (rnd () * (hook->sequence_max [SEQUENCE_ATAK]));

	ai_init_sequence (self, hook->frames->atak [i], SEQUENCE_ATAK, i);
}

///////////////////////
//	buboid_attack
//
//	ai for following/approaching an enemy
///////////////////////

void	buboid_attack (userEntity_t *self)
{
	playerHook_t	*hook = (playerHook_t *) self->userHook;
	float			dist;
	
	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;
	
		if (hook->sound1)
			gstate->sound (self, CHAN_AUTO, hook->sound1, 128, ATTN_NORM);
	}
	
	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;

		buboid_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, buboid_attack, "buboid_attack");
}

//////////////////////////////
//	buboid_begin_attack
//
//	ai for following/approaching an enemy
//////////////////////////////

void	buboid_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;

	buboid_set_attack_seq (self);

	buboid_attack (self);
}

/////////////////////////////////
//	monster_buboid
//
//	spawns bubba
/////////////////////////////////

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

	hook = ai_init_monster (self, TYPE_BUBOID);

	self->className = "monster_buboid";
	self->netname = "buboid";

	// precache the little bastard's sound

	gstate->Precache_Sound ("monsters/buboid/buboidattack1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidhit1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidattack2.wav");
	gstate->Precache_Sound ("monsters/buboid/buboiddeath1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboiddeath2.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidpain1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidpain2.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidsight1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidsight2.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidsight3.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidwander1.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidwander2.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidwander3.wav");
	gstate->Precache_Sound ("monsters/buboid/buboidwander4.wav");

	self->s.modelindex = gstate->ModelIndex ("models/buboid/buboid.md2");
	gstate->SetSize (self, -16.0, -16.0, -24.0, 16.0, 16.0, 32.0);

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

	ai_get_sequences (self);

	buboid_init_frametable (self);

	com->free (hook->frames->jump [0]);
	hook->frames->jump [0] = hook->frames->death [2];

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

	hook->begin_attack = buboid_begin_attack;

	hook->run_speed = 80;
	hook->walk_speed = 30.0;
	hook->attack_dist = 80.0;

	self->mass = 0.8;
	self->ang_speed [YAW] = 100.0;

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

	self->translucent = 0;

	//////////////////////////////////////////////
	//	give the buboid his fists
	//////////////////////////////////////////////
/*
	self->curWeapon = ai_weapon_create ("punch", melee_punch, ai_weapon_command);
	i = 10;
	ai_weapon_command (self->curWeapon, "base_damage", &i);
	ai_weapon_command (self->curWeapon, "rnd_damage", &i);
*/
	self->curWeapon = ai_init_weapon (self, 10, 4, 0, 0, 0, hook->attack_dist, Vector (0, 0, 0), "punch", melee_punch, WEAPON_TRACE);
//	gstate->InventoryAddItem (self->inventory, self->curWeapon);
}
