/*********************************************************************************************/
/*                                                                                           */
/* Bird Control                                                               G.Rummery 1997 */
/*                                                                                           */
/*********************************************************************************************/

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

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

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

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

#define BIRD_DAMAGE 20
#define BIRD_TURN (ONE_DEGREE*3)
#define BIRD_ATTACK_RANGE SQUARE(WALL_L/2)

#define BIRD_TAKEOFF_CHANCE 0x100

#define BIRD_DIE_ANIM 8
#define CROW_DIE_ANIM 1

#define BIRD_START_ANIM 5
#define CROW_START_ANIM 14

enum bird_anims {
	BIRD_EMPTY,
	BIRD_FLY,
	BIRD_STOP,
	BIRD_GLIDE,
	BIRD_FALL,
	BIRD_DEATH,
	BIRD_ATTACK,
	BIRD_EAT
};

//#define DEBUG_BIRD

#ifdef DEBUG_BIRD
extern char exit_message[];
#endif

#ifdef DEBUG_BIRD
static char *BirdStrings[] = {
	"EMPTY",
	"FLY",
	"STOP",
	"GLIDE",
	"FALL",
	"DEATH",
	"ATTACK",
	"EAT"
};
#endif

/*---------------------------------------------------------------------------
 *	Globals
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION

void InitialiseVulture(sint16 item_number);
void VultureControl(sint16 item_number);

void *VFunc[] = {
	&InitialiseVulture,
	&VultureControl
};

#endif

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

static BITE_INFO bird_bite = { 15,46,21, 6 };
static BITE_INFO crow_bite = { 2,10,60, 14 };

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

void InitialiseVulture(sint16 item_number)
{
	ITEM_INFO *item;

	InitialiseCreature(item_number);

	item = &items[item_number];
	if (item->object_number == CROW)
	{
		item->anim_number = objects[CROW].anim_index + CROW_START_ANIM;
		item->frame_number = anims[item->anim_number].frame_base;
		item->current_anim_state = item->goal_anim_state = BIRD_EAT;
	}
	else
	{
		item->anim_number = objects[VULTURE].anim_index + BIRD_START_ANIM;
		item->frame_number = anims[item->anim_number].frame_base;
		item->current_anim_state = item->goal_anim_state = BIRD_STOP;
	}
}

void VultureControl(sint16 item_number)
{
	ITEM_INFO *item;
	CREATURE_INFO *bird;
	AI_INFO info;
	sint16 angle=0;

	if (!CreatureActive(item_number))
		return;

	item = &items[item_number];
	bird = (CREATURE_INFO *)item->data;

	if (item->hit_points <= 0)
	{
		/* Make bird fall to the ground when it dies */
		switch (item->current_anim_state)
		{
		case BIRD_FALL:
			if (item->pos.y_pos > item->floor)
			{
				item->pos.y_pos = item->floor;
				item->gravity_status = 0;
				item->fallspeed = 0;
				item->goal_anim_state = BIRD_DEATH;
			}
			break;

		case BIRD_DEATH:
			item->pos.y_pos = item->floor;
			break;

		default:
			/* Different death anims for Crow and Vulture */
			if (item->object_number == CROW)
				item->anim_number = objects[CROW].anim_index + CROW_DIE_ANIM;
			else
				item->anim_number = objects[VULTURE].anim_index + BIRD_DIE_ANIM;

			item->frame_number = anims[item->anim_number].frame_base;
			item->current_anim_state = BIRD_FALL;
			item->gravity_status = 1;
			item->speed = 0;
			break;
		}
		item->pos.x_rot = 0;
	}
	else
	{
		CreatureAIInfo(item, &info);

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

		angle = CreatureTurn(item, BIRD_TURN);

		/* Decide on bat action based on currently not a lot */
		switch (item->current_anim_state)
		{
		case BIRD_EAT:
			item->pos.y_pos = item->floor;

			if (bird->mood != BORED_MOOD)
				item->goal_anim_state = BIRD_FLY;
			break;

		case BIRD_STOP:
			item->pos.y_pos = item->floor;

			if (bird->mood == BORED_MOOD )//&& GetRandomControl() > BIRD_TAKEOFF_CHANCE)
				break;
			else
				item->goal_anim_state = BIRD_FLY;
			break;

		case BIRD_FLY:
			bird->flags = 0;

			if (item->required_anim_state)
				item->goal_anim_state = item->required_anim_state;
			if (bird->mood == BORED_MOOD )//&& GetRandomControl() < BIRD_TAKEOFF_CHANCE)
				item->goal_anim_state = BIRD_STOP;
			else if (info.ahead && info.distance < BIRD_ATTACK_RANGE)
				item->goal_anim_state = BIRD_ATTACK;
			else
				item->goal_anim_state = BIRD_GLIDE;
			break;

		case BIRD_GLIDE:
			if (bird->mood == BORED_MOOD )//&& GetRandomControl() < BIRD_TAKEOFF_CHANCE)
			{
				item->required_anim_state = BIRD_STOP;
				item->goal_anim_state = BIRD_FLY;
			}
			else if (info.ahead && info.distance < BIRD_ATTACK_RANGE)
				item->goal_anim_state = BIRD_ATTACK;
			break;

		case BIRD_ATTACK:
			if (!bird->flags && item->touch_bits)
			{
				lara_item->hit_points -= BIRD_DAMAGE;
				lara_item->hit_status = 1;

				if (item->object_number == CROW)
					CreatureEffect(item, &crow_bite, DoBloodSplat);
				else
					CreatureEffect(item, &bird_bite, DoBloodSplat);

				bird->flags = 1;
			}
			break;
		}
	}
#ifdef DEBUG_BIRD
	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", bird->mood);
	PrintDbug(2, 2, exit_message);
	sprintf(exit_message, "%s", BirdStrings[item->current_anim_state]);
	PrintDbug(2, 3, exit_message);
	sprintf(exit_message, "%s", BirdStrings[item->goal_anim_state]);
	PrintDbug(2, 4, exit_message);
	sprintf(exit_message, "Distance: %d", info.distance);
	PrintDbug(2, 5, exit_message);
//	sprintf(exit_message, "BF:%d, LBF:%d", boxes[item->box_number].flags, boxes[lara_item->box_number].flags);
//	PrintDbug(2, 6, exit_message);
//	sprintf(exit_message, "Alert:%d, Goal:%d, Hurt:%d", bird->alerted, bird->reached_goal, bird->hurt_by_lara);
//	PrintDbug(2,6, exit_message);
//	sprintf(exit_message, "AI Bits: %d", item->ai_bits);
//	PrintDbug(2,7, exit_message);
#endif

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