/**************************************************************************************************************/
/*                                                                                                            */
/* Orca.c - Killer whale control - TS - 13/9/98 based on Shark.c							 				  */
/*                                                                                                            */
/**************************************************************************************************************/

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

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

#include "objects.h"
#include "lara.h"
#include "laraanim.h"
#include "control.h"
#include "effect2.h"
#include "sphere.h"

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

#define ORCA_BITE 400
#define ORCA_TOUCH 0x3400

#define ORCA_FAST_RANGE SQUARE(WALL_L*3/2)
#define ORCA_ATTACK1_RANGE SQUARE(WALL_L*3/4)
#define ORCA_ATTACK2_RANGE SQUARE(WALL_L*4/3)

#define ORCA_FAST_TURN (ONE_DEGREE*2) //perhaps change depending on mood - Bored = 1degree, Attack = 3degrees?
#define ORCA_SLOW_TURN (ONE_DEGREE*2)

//Remember to up the turn speeds!

#define ORCA_ATTACK1_CHANCE 0x800

#define ORCA_DIE_ANIM 4
#define ORCA_KILL_ANIM 19

enum orca_anim {
	ORCA_SLOW,
	ORCA_FAST,
	ORCA_JUMP,
	ORCA_SPLASH,
	ORCA_SLOW_BUTT,
	ORCA_FAST_BUTT,
	ORCA_BREACH,
	ORCA_ROLL180
};

//#define DEBUG_ORCA

#ifdef DEBUG_ORCA
extern char exit_message[];
#endif

#ifdef DEBUG_ORCA
static char *OrcaStrings[] = {"SLOW", "FAST", "JUMP", "SPLASH", "SLOW_BUTT", "FAST_BUTT", "BREACH", "ROLL180"};
#endif

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

//static BITE_INFO orca_bite = { 17, -22, 344, 12 };

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

void OrcaControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *orca;
	sint16 angle, head;
	AI_INFO info;
	int lara_alive;
//sint16 *bounds;

	if (!CreatureActive(item_number))
		return;

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

	lara_alive = (lara_item->hit_points>0);

	item->hit_points = DONT_TARGET;
/*
	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != ORCA_DEATH)
		{
			item->anim_number = objects[WHALE].anim_index + ORCA_DIE_ANIM;
			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = ORCA_DEATH;
		}

		// Make dead orca float to surface
		CreatureFloat(item_number);

		return;
	}
	else
	{
*/
		CreatureAIInfo(item, &info);

		//Maybe we should change meta-mood depending on whether Lara is in the boat or not
		GetCreatureMood(item, &info, VIOLENT);
		if (!(room[lara_item->room_number].flags & UNDERWATER) && lara.skidoo == NO_ITEM)
			orca->mood = BORED_MOOD;
		CreatureMood(item, &info, VIOLENT);

		angle = CreatureTurn(item, orca->maximum_turn);

		switch (item->current_anim_state)
		{
		case ORCA_SLOW:
			orca->flags = 0;
			orca->maximum_turn = ORCA_SLOW_TURN;

			if (orca->mood == BORED_MOOD)
			{
				if (GetRandomControl() & 0xFF)
					item->goal_anim_state = ORCA_SLOW;
				else
					item->goal_anim_state = ORCA_JUMP;

				break;
			}
			else if (info.ahead && info.distance < ORCA_ATTACK1_RANGE)
				item->goal_anim_state = ORCA_SLOW_BUTT;
			else if (orca->mood == ESCAPE_MOOD)
				item->goal_anim_state = ORCA_FAST;
			else if (info.distance > ORCA_FAST_RANGE)
			{
				if (info.angle < 0x5000 && info.angle >-0x5000)
				{
					if (!(GetRandomControl() & 0x3F))
						item->goal_anim_state = ORCA_BREACH;
					else
						item->goal_anim_state = ORCA_FAST;
				}
				else
					item->goal_anim_state = ORCA_ROLL180;
			}
			break;

		case ORCA_FAST:
			orca->flags = 0;
			orca->maximum_turn = ORCA_FAST_TURN;

			if (orca->mood == BORED_MOOD)
			{
				if (GetRandomControl() & 0xFF)
					item->goal_anim_state = ORCA_SLOW;
				else
					item->goal_anim_state = ORCA_JUMP;
			}
			else if (orca->mood == ESCAPE_MOOD)
				break;
			else if (info.ahead && info.distance < ORCA_FAST_RANGE && info.zone_number==info.enemy_zone)
				item->goal_anim_state = ORCA_SLOW;
			else if (info.distance > ORCA_FAST_RANGE && !(GetRandomControl() & 0x7F))
					item->goal_anim_state = ORCA_JUMP;
			else if (info.distance > ORCA_FAST_RANGE && !info.ahead)
				item->goal_anim_state = ORCA_SLOW;
			break;

		case ORCA_ROLL180:
				orca->maximum_turn = 0;

				if (item->frame_number == anims[item->anim_number].frame_base + 59) // final frame of 180 leap - so turn it around
				{
					if (item->pos.y_rot < 0)
						item->pos.y_rot += 0x8000;
					else
						item->pos.y_rot -= 0x8000;
					item->pos.x_rot = -item->pos.x_rot;
				}
				break;

		}
//	}	//Uncomment if hit_points < 0 clause put back in
/*
	// Is Lara dead? We've killed her!
	if (lara_alive && lara_item->hit_points <= 0)
	{
		CreatureKill(item, ORCA_KILL_ANIM, ORCA_KILL, EXTRA_ORCAKILL);
		return;
	}
*/
//bounds = GetBestFrame(item);
//Log("%d:%d Bounds%d,%d %d,%d %d,%d", item->current_anim_state, item->frame_number, bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);

	#ifdef DEBUG_ORCA
	sprintf(exit_message, "Bx:%d, LBx:%d, Z:%d, LZ:%d", item->box_number, lara_item->box_number, info.zone_number, info.enemy_zone);
	PrintDbug(2, 1, exit_message);
	sprintf(exit_message, "Mood: %d", orca->mood);
	PrintDbug(2, 2, exit_message);
	sprintf(exit_message, "%s", OrcaStrings[item->current_anim_state]);
	PrintDbug(2, 3, exit_message);
	sprintf(exit_message, "%s", OrcaStrings[item->goal_anim_state]);
	PrintDbug(2, 4, exit_message);
	sprintf(exit_message, "LRoom:%d, LRmFlags:%d", lara_item->room_number, room[lara_item->room_number].flags);
	PrintDbug(2, 5, exit_message);

//	sprintf(exit_message, "%s", WillbossStrings[item->required_anim_state]);
//	PrintDbug(2, 6, exit_message);
//	sprintf(exit_message, "Anim Number; %d", item->anim_number - objects[WILLARD_BOSS].anim_index);
//	PrintDbug(2, 6, exit_message);
//	sprintf(exit_message, "Alert:%d, Goal:%d, Hurt:%d", willboss->alerted, willboss->reached_goal, willboss->hurt_by_lara);
//	PrintDbug(2,6, exit_message);

//	sprintf(exit_message, "AI Bits: %d", item->ai_bits);
//	PrintDbug(2,7, exit_message);
	#endif

//	if (item->current_anim_state != ORCA_KILL)
//	{
//		CreatureHead(item, head);

		CreatureAnimation(item_number, angle, 0);

		// We *want* orca to get above the water surface when doing the boat flip anims
		//Experiment with different values for param 2 (it was WALL_L/3 for shark)
		CreatureUnderwater(item, WALL_L/5);
//	}
//	else
//		AnimateItem(item);

	if (wibble&4)
	{
		PHD_VECTOR	pos;
		FLOOR_INFO	*floor;
		sint16 		room_number;
		long			wh;

		room_number = item->room_number;
		pos.x = -32;
		pos.y = 16;			//Before I scaled the bugger up - oops! Maybe these need tweaking
		pos.z = -300;
		GetJointAbsPosition(item,&pos,5);
		floor = GetFloor(pos.x, pos.y, pos.z, &room_number);

		if ((wh = GetWaterHeight(pos.x, pos.y, pos.z, room_number)) != NO_HEIGHT)
		{
			if (pos.y < wh)
			{
				RIPPLE_STRUCT *r;
				r = SetupRipple(pos.x, wh, pos.z, -2-(GetRandomControl()&1), 0);
				r->init = 0;
			}
		}
	}

}
