#include "objects.h"
#include "message.h"

CLIENT_OBJECTS* cl_create_objects(CLIENT_OBJECTS* objects, int ship_size, int bullet_size, int comet_size, int explosion_size)
{
    if(!objects)
    {
        CLIENT_OBJECTS* objects = (CLIENT_OBJECTS*)malloc(sizeof(CLIENT_OBJECTS));
        show_message_error(objects, "Failed to allocate space for CLIENT_OBJECTS");
    }
    
    objects->ship_size = ship_size;
    objects->bullet_size = bullet_size;
    objects->comet_size = comet_size;
    objects->explosion_size = explosion_size;
    
    objects->ships = cl_create_ships(ship_size);
    objects->bullets = cl_create_bullets(bullet_size);
    objects->comets = cl_create_comets(comet_size);
    objects->explosions = cl_create_explosions(explosion_size);
    
    return objects;
}

void cl_free_objects(CLIENT_OBJECTS* objects)
{
    cl_destroy_objects(objects);
    free(objects);
}

void cl_destroy_objects(CLIENT_OBJECTS* objects)
{
    if(objects->ship_size > 0)
    {
        for(int i = 0; i < objects->ship_size; i++)
            free(objects->ships[i]);
        free(objects->ships);
    }
    
    if(objects->bullet_size > 0)
    {
        for(int i = 0; i < objects->bullet_size; i++)
            free(objects->bullets[i]);
        free(objects->bullets);
    }
    
    if(objects->comet_size > 0)
    {
        for(int i = 0; i < objects->comet_size; i++)
            free(objects->comets[i]);
        free(objects->comets);
    }
    
    if(objects->explosion_size > 0)
    {
        for(int i = 0; i < objects->explosion_size; i++)
            free(objects->explosions[i]);
        free(objects->explosions);
    }
}

static CLIENT_SHIP** cl_create_ships(int size)
{
    CLIENT_SHIP** ships = (CLIENT_SHIP**)malloc(sizeof(CLIENT_SHIP*) * size);
    show_message_error(ships, "Failed to allocate space for CLIENT_SHIP collection");
    
    for(int i = 0; i < size; i++)
    {
        ships[i] = (CLIENT_SHIP*)malloc(sizeof(CLIENT_SHIP));
        show_message_error(ships[i], "Failed to allocate space for CLIENT_SHIP");
        ships[i]->image = NULL;
    }
    
    return ships;
}

static CLIENT_BULLET** cl_create_bullets(int size)
{
    CLIENT_BULLET** bullets = (CLIENT_BULLET**)malloc(sizeof(CLIENT_BULLET*) * size);
    show_message_error(bullets, "Failed to allocate space for CLIENT_BULLET collection");
    
    for(int i = 0; i < size; i++)
    {
        bullets[i] = (CLIENT_BULLET*)malloc(sizeof(CLIENT_BULLET));
        show_message_error(bullets[i], "Failed to allocate space for CLIENT_BULLET");
    }
    
    return bullets;
}

static CLIENT_COMET** cl_create_comets(int size)
{
    CLIENT_COMET** comets = (CLIENT_COMET**)malloc(sizeof(CLIENT_COMET*) * size);
    show_message_error(comets, "Failed to allocate space for CLIENT_COMET collection");
    
    for(int i = 0; i < size; i++)
    {
        comets[i] = (CLIENT_COMET*)malloc(sizeof(CLIENT_COMET));
        show_message_error(comets[i], "Failed to allocate space for CLIENT_COMET");
        comets[i]->image = NULL;
    }
    
    return comets;
}

static CLIENT_EXPLOSION** cl_create_explosions(int size)
{
    CLIENT_EXPLOSION** explosions = (CLIENT_EXPLOSION**)malloc(sizeof(CLIENT_EXPLOSION*) * size);
    show_message_error(explosions, "Failed to allocate space for CLIENT_EXPLOSION collection");
    
    for(int i = 0; i < size; i++)
    {
        explosions[i] = (CLIENT_EXPLOSION*)malloc(sizeof(CLIENT_EXPLOSION));
        show_message_error(explosions[i], "Failed to allocate space for CLIENT_EXPLOSION");
        explosions[i]->image = NULL;
    }
    
    return explosions;
}

void cl_init_ships(CLIENT_OBJECTS* objects, int key_ship, int ID, int animation_columns, int animation_direction, int animation_row, int boundx, int boundy, int cur_frame,
        int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int lives, int max_frame, int score, int speed, int x, int y)
{
    CLIENT_SHIP* ship = objects->ships[key_ship];
    
    ship->ID = ID;
    ship->animation_columns = animation_columns;
    ship->animation_direction = animation_direction;
    ship->animation_row = animation_row;
    ship->boundx = boundx;
    ship->boundy = boundy;
    ship->cur_frame = cur_frame;
    ship->frame_count = frame_count;
    ship->frame_delay = frame_delay;
    ship->frame_height = frame_height;
    ship->frame_width = frame_width;
    ship->image = image;
    ship->lives = lives;
    ship->max_frame = max_frame;
    ship->score = score;
    ship->speed = speed;
    ship->x = x;
    ship->y = y;
    ship->active = true;
}

void cl_init_bullets(CLIENT_OBJECTS* objects, int key_bullet, int ID, int speed, int x, int y)
{
    CLIENT_BULLET* bullet = objects->bullets[key_bullet];
    
    bullet->ID = ID;
    bullet->live = false;
    bullet->speed = speed;
    bullet->x = x;
    bullet->y = y;
    bullet->active = true;
}

void cl_init_comets(CLIENT_OBJECTS* objects, int key_comet, int ID, int animation_columns, int animation_direction, int boundx, int boundy, int cur_frame,
        int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int speed, int x, int y)
{
    CLIENT_COMET* comet = objects->comets[key_comet];
    
    comet->ID = ID;
    comet->animation_columns = animation_columns;
    comet->animation_direction = animation_direction;
    comet->boundx = boundx;
    comet->boundy = boundy;
    comet->cur_frame = cur_frame;
    comet->frame_count = frame_count;
    comet->frame_delay = frame_delay;
    comet->frame_height = frame_height;
    comet->frame_width = frame_width;
    comet->image = image;
    comet->max_frame = max_frame;
    comet->speed = speed;
    comet->live = false;
    comet->x = x;
    comet->y = y;
}

void cl_init_explosions(CLIENT_OBJECTS* objects, int key_explosion, int animation_columns, int animation_direction, int cur_frame,
        int frame_count, int frame_delay, int frame_height, int frame_width, ALLEGRO_BITMAP* image, int max_frame, int x, int y)
{
    CLIENT_EXPLOSION* explosion = objects->explosions[key_explosion];
    
    explosion->animation_columns = animation_columns;
    explosion->animation_direction = animation_direction;
    explosion->cur_frame = cur_frame;
    explosion->frame_count = frame_count;
    explosion->frame_delay = frame_delay;
    explosion->frame_height = frame_height;
    explosion->frame_width = frame_width;
    explosion->image = image;
    explosion->live = false;
    explosion->max_frame = max_frame;
    explosion->x = x;
    explosion->y = y;
}
