/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "../g_local.h"
#include "ai_local.h"


void AI_SetUpAnimMoveFlags( edict_t *ent, usercmd_t *ucmd )
{

	int			xyspeedcheck;
	vec3_t		velocity;
	pmanim_t	*pmAnim;
	pmAnim = &ent->pmAnim;
	
	//Update anim movement flags for monsters with ppms.
	if(ent->r.svflags & SVF_FAKECLIENT)
		return;
	
	//----------------------------------------
	//splitmodels jal[start]
	//VectorSubtract( ent->s.origin, ent->s.old_origin, velocity );
	VectorCopy( ent->velocity, velocity );
	xyspeedcheck = sqrt(velocity[0]*velocity[0] + velocity[1]*velocity[1]);
	Com_Printf("XYspeed:%i\n", xyspeedcheck );
	
	pmAnim->anim_moveflags = 0;//start from 0
	
	if (ucmd->forwardmove < -1)
		pmAnim->anim_moveflags |= ANIMMOVE_BACK;
	else if (ucmd->forwardmove > 1)
		pmAnim->anim_moveflags |= ANIMMOVE_FRONT;
	
	if (ucmd->sidemove < -1)
		pmAnim->anim_moveflags |= ANIMMOVE_LEFT;
	else if (ucmd->sidemove > 1)
		pmAnim->anim_moveflags |= ANIMMOVE_RIGHT;
	
	if (xyspeedcheck > 20)
		pmAnim->anim_moveflags |= ANIMMOVE_RUN;
	else if (xyspeedcheck)
		pmAnim->anim_moveflags |= ANIMMOVE_WALK;
	
	//if (client->ps.pmove.pm_flags & PMF_DUCKED)
	//	client->pmAnim.anim_moveflags |= ANIMMOVE_DUCK;
}


//AI_HELPERS
//
//	Taken and modified (or not) from g_ai.c
//

//=============
//visible
//returns 1 if the entity is visible to self, even if not infront ()
//=============
qboolean AI_visible (edict_t *self, edict_t *other)
{
	vec3_t	spot1;
	vec3_t	spot2;
	trace_t	trace;

	VectorCopy (self->s.origin, spot1);
	spot1[2] += self->viewheight;
	VectorCopy (other->s.origin, spot2);
	spot2[2] += other->viewheight;
	trap_Trace (&trace, spot1, vec3_origin, vec3_origin, spot2, self, MASK_OPAQUE);
	//trace = gi.trace( spot1, vec3_origin, vec3_origin, spot2, self, MASK_OPAQUE );
	
	if (trace.fraction == 1.0)
		return qtrue;
	return qfalse;
}


//=============
//infront
//returns 1 if the entity is in front (in sight) of self
//=============
qboolean AI_infront (edict_t *self, edict_t *other)
{
	vec3_t	vec;
	float	dot;
	vec3_t	forward;
	
	AngleVectors( self->s.angles, forward, NULL, NULL );
	VectorSubtract( other->s.origin, self->s.origin, vec );
	VectorNormalizeFast( vec );
	dot = DotProduct( vec, forward );
	
	if(dot > 0.3)
		return qtrue;
	return qfalse;
}


//=============
//inView
//returns 1 if the entity is in view field to self (in front and not blocked)
//=============
qboolean AI_inView (edict_t *self, edict_t *other)
{
	vec3_t	vec;
	float	dot;
	vec3_t	forward;
	float	MONSTER_VIEWDISTANCE = 1000.0f;//jalfixme: make a class based field
	float	MONSTER_VIEWSIZE = 0.3f;//jalfixme: make a class based field

	//too far away for our view capabilities
	if( DistanceFast(self->s.old_origin, other->s.origin) > MONSTER_VIEWDISTANCE )
		return qfalse;

	//check if in front
	AngleVectors (self->s.angles, forward, NULL, NULL);
	VectorSubtract (other->s.origin, self->s.origin, vec);
	VectorNormalizeFast (vec);
	dot = DotProduct (vec, forward);
	if( dot < MONSTER_VIEWSIZE )
		return qfalse;

	if( !AI_visible (self, other) )	//bloqued
		return qfalse;
	
	return qtrue;
}


//=============
//AI_Sounds
//
//=============



//==========================================
// 
//			COMMANDS
// 
//==========================================

void Cmd_ShowPLinks_f( edict_t *ent )
{
	if( !sv_cheats->integer )
	{
		G_PrintMsg( ent, "Cheats are not enabled in this server\n" );
		AIDevel.showPLinks = qfalse;
		AIDevel.plinkguy = NULL;
		return;
	}

	if (AIDevel.showPLinks == qfalse)
	{
		AIDevel.showPLinks = qtrue;
		AIDevel.plinkguy = ent;
		
	} else {
		AIDevel.showPLinks = qfalse;
		AIDevel.plinkguy = NULL;
	}
}



void AITools_SaveNodes( void );
void AITools_InitEditnodes( void );
void AITools_InitMakenodes( void );
void AITools_AddBotRoamNode(void);
void M_default_Spawn( void );
/*
//==========================================
// BOT_Commands
// Special command processor
//==========================================
qboolean BOT_Commands(edict_t *ent)
{
	char	*cmd;
	cmd = trap_Cmd_Argv(0);

	// show plinks at current node
	if(Q_stricmp (cmd, "showplinks") == 0)
	{
		if (AIDevel.showPLinks == qfalse)
		{
			AIDevel.showPLinks = qtrue;
			AIDevel.plinkguy = ent;

		} else {
			AIDevel.showPLinks = qfalse;
			AIDevel.plinkguy = NULL;
		}

		return qtrue;
	}

	return qfalse;
}
*/
//==========================================
// BOT_ServerCommand
// Special server command processor
//==========================================
qboolean BOT_ServerCommand (void)
{
	char	*cmd;

	cmd = trap_Cmd_Argv (1);

	// debug
	if(Q_stricmp (cmd, "botdebug") == 0)
		AIDebug_ToogleBotDebug();

	// addbot
	else if( !Q_stricmp (cmd, "addbot") )
	{
		BOT_SpawnBot( trap_Cmd_Argv(2) );	//team "red", "blue", etc
	}
	// removebot
	else if( !Q_stricmp (cmd, "removebot"))
		BOT_RemoveBot(trap_Cmd_Argv(2));

	else if( !Q_stricmp (cmd, "editnodes") )
		AITools_InitEditnodes();

	else if( !Q_stricmp (cmd, "makenodes") )
		AITools_InitMakenodes();

	else if( !Q_stricmp (cmd, "savenodes") )
		AITools_SaveNodes();

	else if( !Q_stricmp (cmd, "addnode") || !Q_stricmp (cmd, "dropnode") )
		AITools_AddNode_Cmd();

	else if( !Q_stricmp (cmd, "addbotroam") )
		AITools_AddBotRoamNode_Cmd();

	else if( !Q_stricmp (cmd, "addmonster") )
		M_default_Spawn();

	else
		return qfalse;

	return qtrue;
}

