#include "map_init.h"

#include <flecs.h>

#include "buildings.h"
#include "components.h"
#include "entity_factory.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++) {
        //if (i == 1) break;
        BzTileObject object = objectGroup->objects[i];
        Position pos = (Position) { object.shape.x, object.shape.y };
        entityCreateWorker(pos, game);
        /*ecs_set(ECS, e, Animation, {
            .entityType=ENTITY_WORKER,
            .tileset = objectTileset,
            .curFrame=0,
            .frameDuration=0.6f + (i % 10) * 0.05f,
            .elapsed=i * 0.1f,
        });
         */
        //EntityArms arms = {
        //        .left=createEntity(ECS),
        //        .right=createEntity(ECS),
        //};
        //ecs_set_ptr(ECS, e, EntityArms, &arms);
    }
    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;
    BZ_ASSERT(ownershipLayer->tilesetIdx == buildingLayer->tilesetIdx);

    for (i32 y = 0; y < layer->height; y++) {
        for (i32 x = 0; x < layer->width; x++) {
            BzTile ownerRawTile = data[y * layer->width + x];
            BzTileID owner = bzTilesetGetTileID(buildingTileset, ownerRawTile);
            BzTile buildingRawTile = buildingData[y * layer->width + x];
            BzTile buildingType = bzTilesetGetTileID(buildingTileset, buildingRawTile);
            buildingType = getTileBuilding(buildingType);
            if (buildingType <= BUILDING_NONE || buildingType >= BUILDING_COUNT)
                continue;
            placeBuilding(game, buildingType, x, y, (Owner) {owner});

            i32 sizeX = 1;
            i32 sizeY = 1;
            getBuildingSize(buildingType, &sizeX, &sizeY);
            x += sizeX - 1;
            y += sizeY - 1;
        }
    }
    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 = bzTilesetGetTileID(tileset, tile);
            if (tile == -1) 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 = entityCreateEmpty();
            SpatialGridID gridID = bzSpatialGridInsert(game->entityGrid, &e, posX, posY, sizeX, sizeY);
            ecs_set(ECS, e, SpatialGridID, {gridID});
            posX += sizeX * 0.5f;
            posY += sizeY * 0.5f;
            ecs_set(ECS, e, Position, {posX, posY});
            ecs_set(ECS, e, Size, {sizeX, sizeY});
            ecs_set(ECS, e, Rotation, {0});
            BzTile tileID = bzTilesetGetTileID(tileset, layerTile);
            ecs_set(ECS, e, TextureRegion, {tileset->tiles, bzTilesetGetTileRegion(tileset, tileID)});
            ecs_set(ECS, e, Resource, {RES_WOOD, 20});
            ecs_add_id(ECS, e, Selectable);
            ecs_add_id(ECS, e, Harvestable);

        }
    }
    return true;
}
