/*********************************************************************************************/
/*                                                                                           */
/* Rat/Vole Control                                                                          */
/*                                                                                           */
/*********************************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION
#include "../spec_psx/typedefs.h"
#else
#include "../specific/stypes.h"
#endif

#include "objects.h"
#include "lara.h"
#include "control.h"

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define MOUSE_DAMAGE 	20
#define MOUSE_TOUCH		(0x7f)

#define MOUSE_WAIT1_CHANCE 0x500
#define MOUSE_WAIT2_CHANCE (MOUSE_WAIT1_CHANCE + 0x500)

#define MOUSE_ATTACK_RANGE SQUARE(WALL_L/3)

#define MOUSE_DIE_ANIM 9

#define MOUSE_RUN_TURN (ONE_DEGREE*6)

enum mouse_anims {
	MOUSE_EMPTY,
	MOUSE_RUN,
	MOUSE_STOP,
	MOUSE_WAIT1,
	MOUSE_WAIT2,
	MOUSE_ATTACK,
	MOUSE_DEATH
};

/*---------------------------------------------------------------------------
 *	Locals
\*--------------------------------------------------------------------------*/

static BITE_INFO mouse_bite = { 0, 0, 57, 2 };

/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

void MouseControl(sint16 item_number)
{
	/* Little tiny rat (SMALL_RAT) */
	ITEM_INFO *item;
	CREATURE_INFO *mouse;
	sint16 head, angle, random;
	AI_INFO info;

	if (!CreatureActive(item_number))
		return;

	item = &items[item_number];
	mouse = (CREATURE_INFO *)item->data;
	head = angle = 0;

	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != MOUSE_DEATH)
		{
			item->anim_number = objects[SMALL_RAT].anim_index + MOUSE_DIE_ANIM;
			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = MOUSE_DEATH;
		}
	}
	else
	{
		CreatureAIInfo(item, &info);

		if (info.ahead)
			head = info.angle;

		GetCreatureMood(item, &info, TIMID);
		CreatureMood(item, &info, TIMID);

		angle = CreatureTurn(item, MOUSE_RUN_TURN);

		switch (item->current_anim_state)
		{
		case MOUSE_WAIT2:
			/* This is effectively the mouse's stop state as stop automatically goes into this */
			if (mouse->mood == BORED_MOOD || mouse->mood == STALK_MOOD)
			{
				random =(sint16) GetRandomControl();
				if (random < MOUSE_WAIT1_CHANCE)
					item->required_anim_state = MOUSE_WAIT1;
				else if (random > MOUSE_WAIT2_CHANCE)
					item->required_anim_state = MOUSE_RUN;
			}
			else if (info.distance < MOUSE_ATTACK_RANGE)
				item->required_anim_state = MOUSE_ATTACK;
			else
				item->required_anim_state = MOUSE_RUN;

			if (item->required_anim_state)
				item->goal_anim_state = MOUSE_STOP;
			break;

		case MOUSE_STOP:
			/* Jean-Michel set this one up weirdly: goes from STOP into WAIT2 automatically, then stays there until
				it gets a request to go back to STOP. So basically, STOP is redundant, and WAIT2 is stop state */
			mouse->maximum_turn = 0;

			if (item->required_anim_state)
				item->goal_anim_state = item->required_anim_state;
			break;

		case MOUSE_RUN:
			mouse->maximum_turn = MOUSE_RUN_TURN;

			if (mouse->mood == BORED_MOOD || mouse->mood == STALK_MOOD)
			{
				random =(sint16) GetRandomControl();
				if (random < MOUSE_WAIT1_CHANCE)
				{
					item->required_anim_state = MOUSE_WAIT1;
					item->goal_anim_state = MOUSE_STOP;
				}
				else if (random < MOUSE_WAIT2_CHANCE)
					item->goal_anim_state = MOUSE_STOP;
			}
			else if (info.ahead && info.distance < MOUSE_ATTACK_RANGE)
				item->goal_anim_state = MOUSE_STOP;
			break;

		case MOUSE_ATTACK:
			if (!item->required_anim_state && (item->touch_bits & MOUSE_TOUCH))
			{
				CreatureEffect(item, &mouse_bite, DoBloodSplat);
				lara_item->hit_points -= MOUSE_DAMAGE;
				lara_item->hit_status = 1;
				item->required_anim_state = MOUSE_STOP;
			}
			break;

		case MOUSE_WAIT1:
			if (GetRandomControl() < MOUSE_WAIT1_CHANCE)
				item->goal_anim_state = MOUSE_STOP;
			break;
		}
	}

	CreatureJoint(item, 0, head);

	/* Actually do animation, allowing for LOT collisions */
	CreatureAnimation(item_number, angle, 0);
}
