#include "map_init.h"

#include <flecs.h>

#include "components.h"
#include "game_state.h"
#include "map_layers.h"

bool initGameObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) {
    Game *game = ecs_singleton_get_mut(ECS, Game);
    for (i32 i = 0; i < objectGroup->objectCount; i++) {
        BzTileObject object = objectGroup->objects[i];
        if (bzStringDefaultHash("camera") == object.id) {
            game->camera.target.x = object.shape.x;
            game->camera.target.y = object.shape.y;
        }
    }
    return true;
}

bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) {
    Game *game = ecs_singleton_get_mut(ECS, Game);
    BzTileset *objectTileset = bzTileObjectGroupGetTileset(&game->map, objectGroup);
    if (!objectTileset) return true;

    for (i32 i = 0; i < objectGroup->objectCount; i++) {
        BzTileObject object = objectGroup->objects[i];
        ecs_entity_t e = ecs_new_id(ECS);
        game->entity = e;
        ecs_add(ECS, e, TextureEntities);
        ecs_set(ECS, e, Position, {object.shape.x, object.shape.y});
        ecs_set(ECS, e, Size, {object.shape.sizeX, object.shape.sizeY});
        BzSpatialGridID spatialID = bzSpatialGridInsert(game->entityGrid, &e,
                                                        object.shape.x, object.shape.y,
                                                        object.shape.sizeX, object.shape.sizeY);
        ecs_set(ECS, e, SpatialGridID, {spatialID});
        ecs_set(ECS, e, Rotation, {0.0f});
        ecs_set(ECS, e, Velocity, {});
        ecs_set(ECS, e, AngularVelocity, {0.0f});
        ecs_set(ECS, e, SteeringOutput, {});
        ecs_set(ECS, e, TextureRegion, {objectTileset->tiles, bzTilesetGetTileRegion(objectTileset, object.gid)});
        ecs_set(ECS, e, Animation, {
            .firstFrame=(TextureRegion) {
                    objectTileset->tiles,
                    bzTilesetGetTileRegion(objectTileset, object.gid + 1)
            },
            .currAnimation=ANIMATION_IDLE,
            .currFrame=0,
            .frameCount=4,
            .frameDuration=0.20f
        });
    }
    return true;

}

bool initBuildingsLayer(BzTileMap *map, BzTileLayer *layer) {
    Game *game = ecs_singleton_get_mut(ECS, Game);

    BzTileLayer *ownershipLayer = layer;
    BzTileLayer *buildingLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS);
    BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer);
    BzTile *data = layer->data;
    BzTile *buildingData = buildingLayer->data;

    for (i32 y = 0; y < layer->height; y++) {
        for (i32 x = 0; x < layer->width; x++) {
            BzTile ownerTile = data[y * layer->width + x];
            BzTile buildingRawTile = buildingData[y * layer->width + x];
            BzTile buildingTile = bzTilesetGetTile(buildingTileset, buildingRawTile);
            buildingTile = getTileBuilding(buildingTile);
            if (buildingTile == BUILDINGS_NONE || ownerTile == 0) continue;
            // We have a building
            TileSize size = {};
            getBuildingSize(buildingTile, &size.sizeX, &size.sizeY);
            bzTileLayerSetTile(ownershipLayer, 0, x, y, size.sizeX, size.sizeY);

            ecs_entity_t e = ecs_new_id(ECS);
            ecs_set(ECS, e, TilePosition, {.x=x, .y=y});
            ecs_set(ECS, e, TileSize, {.sizeX=size.sizeX, .sizeY=size.sizeY});
            ownerTile = bzTilesetGetTile(buildingTileset, ownerTile);
            ownerTile = getTileBuilding(ownerTile);
            ecs_set(ECS, e, Owner, {.playerID=ownerTile});

            //bzTileMapUpdateCollider(&GAME.map, x, y);
        }
    }
    return true;

}

bool initTreesLayer(BzTileMap *map, BzTileLayer *layer) {
    Game *game = ecs_singleton_get_mut(ECS, Game);

    BzTileset *tileset = bzTileLayerGetTileset(map, layer);

    for (i32 y = 0; y < layer->height; y++) {
        for (i32 x = 0; x < layer->width; x++) {
            BzTile tile = layer->data[y * layer->width + x];
            BzTile layerTile = tile;
            tile = bzTilesetGetTile(tileset, tile);
            if (tile != 185) continue; // Not a tree

            f32 sizeX = tileset->tileWidth;
            f32 sizeY = tileset->tileHeight;
            f32 posX = layer->offsetX + x * sizeX;
            f32 posY = layer->offsetY + y * sizeY;
            ecs_entity_t e = ecs_new_id(ECS);
            bzSpatialGridInsert(game->entityGrid, &e, posX, posY, sizeX, sizeY);;
            posX += sizeX * 0.5f;
            posY += sizeY * 0.5f;
            ecs_add(ECS, e, TextureTerrain);
            ecs_set(ECS, e, Position, {posX, posY});
            ecs_set(ECS, e, Size, {sizeX, sizeY});
            ecs_set(ECS, e, Rotation, {0});
            ecs_set(ECS, e, TextureRegion, {tileset->tiles, bzTilesetGetTileRegion(tileset, layerTile)});
            ecs_set(ECS, e, Resource, {RES_WOOD, 20});

        }
    }
    return true;
}
