#include <StdAfx.h>
#include "crow.h"
#include <trng_core.h>
#include "utility.h"
#include "Class/TRClass.h"
#include "TR3_Functions.h"

extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureActive CreatureActive;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;

#define HP_CROW (15)
#define CROW_STAND_ANIM 14
#define CROW_DAMAGE 20
#define CROW_TURN_SPEED (546)
#define CROW_ATTACK_RANGE (0x40000)
#define CROW_OCB_TIMID   0x0
#define CROW_OCB_VIOLENT 0x1

static BITE_INFO crow_bite = { 2, 10, 60, 14 };

enum CROW_STATE {
    ST_CROW_EMPTY,
    ST_CROW_FLY,
    ST_CROW_STOP,
    ST_CROW_PLANE,
    ST_CROW_FALL,
    ST_CROW_DEATH,
    ST_CROW_ATTACK,
    ST_CROW_EAT
};

void CtrlTR2_Crow(short item_number)
{
    if (!CreatureActive(item_number))
        return;

    ITEM_INFO* item;
    CREATURE_INFO* crow;
    AI_INFO info;
    short angle;
    short dmg1;

    item = &Ptr_VetItems[item_number];
    crow = (CREATURE_INFO*)item->data;
    angle = 0;
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);

    if (item->hit_points <= 0)
    {
        OBJECT_INFO* slots = &Ptr_VetObjects[item->object_number];

        switch (item->current_anim_state)
        {
            case ST_CROW_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 = ST_CROW_DEATH;
                }
                break;

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

            default:
                item->anim_number = slots->anim_index + 1;
                item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
                item->current_anim_state = ST_CROW_FALL;
                item->gravity_status = 1;
                item->speed = 0;
                break;
        }

        item->pos.x_rot = 0;
    }
    else
    {
        CreatureAIInfo(item, &info);
        GetCreatureMood(item, &info, VIOLENT);
        CreatureMood(item, &info, VIOLENT);
        angle = CreatureTurn(item, CROW_TURN_SPEED);

        switch (item->current_anim_state)
        {
        case ST_CROW_STOP:
            item->pos.y_pos = item->floor;

            if (crow->mood != MOOD_BORED)
                item->goal_anim_state = ST_CROW_FLY;
            break;

        case ST_CROW_FLY:
            crow->flags = 0;

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

            if (crow->mood != MOOD_BORED)
            {
                if (info.ahead && info.distance < CROW_ATTACK_RANGE)
                    item->goal_anim_state = ST_CROW_ATTACK;
                else
                    item->goal_anim_state = ST_CROW_PLANE;
            }
            else
            {
                item->goal_anim_state = ST_CROW_STOP;
            }
            break;

        case ST_CROW_PLANE:
            if (crow->mood == MOOD_BORED)
            {
                item->required_anim_state = ST_CROW_STOP;
                item->goal_anim_state = ST_CROW_FLY;
            }
            else if (info.ahead && info.distance < CROW_ATTACK_RANGE)
            {
                item->goal_anim_state = ST_CROW_ATTACK;
            }
            break;

        case ST_CROW_ATTACK:
            if (!crow->flags && item->touch_bits)
            {
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, CROW_DAMAGE);
                LaraItem->hit_status = 1;
                CreatureEffect(item, &crow_bite, DoBloodSplat_2);
                crow->flags = 1;
            }
            break;

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

            if (crow->mood != MOOD_BORED)
                item->goal_anim_state = ST_CROW_FLY;
            break;
        }
    }

    CreatureAnimation(item_number, angle, 0);
}

void InitTR2_Crow(short ItemIndex)
{
    ITEM_INFO* item = &Ptr_VetItems[ItemIndex];
    InitialiseCreature(ItemIndex);
    item->anim_number = Ptr_VetObjects[item->object_number].anim_index + CROW_STAND_ANIM;
    ANIM_STRUCT* anims = &Ptr_VetAnimations[item->anim_number];
    item->frame_number = anims->frame_base;
    item->current_anim_state = anims->current_anim_state;
    item->goal_anim_state = anims->current_anim_state;
}

void InitialiseTR2_Crow()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_CROW1 + index].set_name("Crow");
        tomb[TR2_CROW1 + index].initialise(TR2_CROW1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR2_CROW1 + index].set_shadow_size(128);
        tomb[TR2_CROW1 + index].set_func_initialise(InitTR2_Crow);
        tomb[TR2_CROW1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_CROW1 + index].set_func_control(CtrlTR2_Crow);
        tomb[TR2_CROW1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_CROW1 + index].set_health(HP_CROW);
        tomb[TR2_CROW1 + index].set_radius_and_pivot(204, 0);
        tomb[TR2_CROW1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_CROW1 + index].set_creature(TRUE);
        tomb[TR2_CROW1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}