#include "world.h"
#include "chasecam.h"

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

DllExport	void	func_monitor (userEntity_t *self);
DllExport	void	info_camera (userEntity_t *self);

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


/////////////////////////////////////////////////////////////////////
//	typedefs
/////////////////////////////////////////////////////////////////////

typedef	struct	monitorHook_s
{
	userEntity_t	*lock_ent;
	
	vec3_t			camera_origin;
	
	float			fov;
} monitorHook_t;

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


////////////////////////////////////
//	info_camera
//
//	this is entity where the camera will look from
//	if info_camera has a target, then the view will
//	follow that target.
////////////////////////////////////

void	info_camera (userEntity_t *self)
{
	int				i;

	// get memory for userHook
//	self->userHook = com->malloc_hook (sizeof (animHook_t), MEM_HUNK);
//	hook = (animHook_t *) self->userHook;

	self->className = "info_camera";

	//	default 0.1 second delay before using target
	self->delay = 0.1;

	for (i = 0; self->epair [i].key; i++)
	{
		if (!stricmp (self->epair [i].key, "targetname"))
			self->targetname = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "target"))
			self->target = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "killtarget"))
			self->killtarget = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "delay"))
				self->delay = atof (self->epair [i].value);
	}

	self->modelName = NULL;
	gstate->SetSize (self, 0, 0, 0, 0, 0, 0);
	gstate->SetOrigin2 (self, self->s.origin);
}

////////////////////////////////////
//	monitor_find_target
//
//
////////////////////////////////////

void	monitor_find_target (userEntity_t *self)
{
	userEntity_t	*target;
	monitorHook_t	*hook = (monitorHook_t *) self->userHook;
	
	target = com->FindTarget (self->target);
	
	if (!target)
	{
		gstate->Con_Printf ("monitor could not find target.\n");
//		gstate->RemoveEntity (self);
		
		return;
	}

	com->CopyVector (hook->camera_origin, target->s.origin);

	//	find the target of the camera
	if (target->target)
	{
		hook->lock_ent = com->FindTarget (target->target);

		//	don't need actual info_camera any longer
		gstate->RemoveEntity (target);
	}
	else
		hook->lock_ent = NULL;
}

////////////////////////////////////
//	monitor_use
//
//
//////////////////////////////////

//	Q2FIXME:	activator?!!?
void	monitor_use (userEntity_t *self, userEntity_t *other, userEntity_t *activator)
{
	monitorHook_t	*mhook = (monitorHook_t *) self->userHook;
	playerHook_t	*phook;

	if (!(gstate->activator->flags & FL_CLIENT))
		return;

	phook = (playerHook_t *) gstate->activator->userHook;

	if (!phook->camera)
		camera_start (gstate->activator);
	camera_set_target (phook->camera, mhook->lock_ent);
	camera_mode (gstate->activator, 2);

	gstate->activator->flags |= FL_CAMERAMODE;

	gstate->SetOrigin2 (phook->camera, mhook->camera_origin);
}

////////////////////////////////////
//	func_monitor
//
//
////////////////////////////////////

void func_monitor (userEntity_t *self)
{
	int					i;
	monitorHook_t	*hook;

	// get memory for userHook
	self->userHook = com->malloc_hook (sizeof (monitorHook_t), MEM_HUNK);
	hook = (monitorHook_t *) self->userHook;

	self->className = "func_monitor";

	//	FIXME: find actual player's default FOV and keep it instead
	hook->fov = 90.0;

	for (i = 0; self->epair [i].key; i++)
	{
		if (!stricmp (self->epair [i].key, "targetname"))
			self->targetname = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "target"))
			self->target = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "killtarget"))
			self->killtarget = self->epair [i].value;
		else if (!stricmp (self->epair [i].key, "delay"))
				self->delay = atof (self->epair [i].value);
		else if (!stricmp (self->epair [i].key, "fov"))
				hook->fov = atof (self->epair [i].value);
	}

	self->solid = SOLID_BSP;
	self->movetype = MOVETYPE_PUSH;

	gstate->SetOrigin2 (self, self->s.origin);
	gstate->SetModel (self, self->modelName);

	self->use = monitor_use;

	self->nextthink = gstate->time + 0.2;
	self->think = monitor_find_target;
}
