#include "Map.h"

// The map grid.
u8 mapCells[MAP_CELL_COUNT];

// Determine when a map redraw should happen.
u8 mapRedraw = TRUE;

// The map index of the current map in the maps array.
u8 currentMap = 0;

void initMap()
{
    memcpy(mapCells, level_map_uncompressed[currentMap], MAP_CELL_COUNT);

    // Enable map redraw.
    mapRedraw = TRUE;
}

void drawMap()
{
    if (mapRedraw)
    {
        // Draw the content of the map grid.
        u8 x;
        u8 y;
        u8 cell;

        // Position is determined by how much the screen has scrolled to show the current room.
        u16 position = mapCellPosition(0, 0, 0, 0);
        u8* cellPointer = mapCells + position;

        // Position is the element in the map tile array.
        for (x = 0; x < SCREEN_TILES_X; ++x)
        {
            for (y = 0; y < SCREEN_TILES_Y; ++y)
            {
                cell = *cellPointer;
                drawCell(x, y, cell);

                ++cellPointer;
            }

            // Move to the start of the next column (half the column height in a 2x2 screen map), 2/3 of the column height in a 3x3 map.
            cellPointer += 22;
        }

        mapRedraw = FALSE;
    }
}

void drawCell(u8 x, u8 y, u8 cell)
{
    u16 targetX = x * 16 * scaleFactor;
    u16 targetY = y * 16 * scaleFactor;

    ALLEGRO_BITMAP* bitmap = allegroBitmapFromCell(cell);

    if (bitmap)
    {
        al_draw_scaled_bitmap(bitmap, 0, 0, TILE_WIDTH_BYTES * 2, TILE_HEIGHT, targetX, targetY, 16 * scaleFactor, 16 * scaleFactor, 0);
    }
}

u16 mapCellPosition(u8 x, u8 y, u8 roomX, u8 roomY)
{
    return (x + (SCREEN_TILES_X * roomX)) * MAP_TILES_Y + (y + (SCREEN_TILES_Y * roomY));
}

u8 mapCell(u8 x, u8 y, u8 roomX, u8 roomY)
{
    return mapCells[mapCellPosition(x, y, roomX, roomY)];
}

ALLEGRO_BITMAP* allegroBitmapFromCell(u8 cell)
{
    // The cell type without the flag.
    u8 cellType = cell & CELL_GFX_RANGE;

    if (cell & CELL_MAP_FEATURE_FLAG)
    {
        return allegroFeatureSprites[cellType - 1];
    }
    else if (cell & CELL_ENVIRONMENT_FLAG)
    {
        return allegroEnvironmentSprites[cellType - 1];
    }
    else if (cell)
    {
        return allegroTrackSprites[cellType - 1];
    }
    else
    {
        // Default to grass cells.
        return allegroEnvironmentSprites[1];
    }
}

void drawCellAtPosition(u8 x, u8 y)
{
    u8 cell = mapCell(x, y, 0, 0);

    drawCell(x, y, cell);
}

void updateMapCellRedraw(u8 x, u8 y, u8 roomX, u8 roomY, u8 cell)
{
    mapCells[mapCellPosition(x, y, roomX, roomY)] = cell;

    // We will assume it is in the current room and if not it will draw something else.
    drawCellAtPosition(x, y);
}