#include "Player.h"

// The players in the game.
Player players[MAX_PLAYER_COUNT];

void initPlayers(u8 playerCount)
{
    u8 i = 0;
    Player* player = players;

    // Seed the random function before initialising players to ensure both players have a different set of pieces.
    srand(time(NULL));

    for (i = 0; i < playerCount; ++i)
    {
        player->x = 0;
        player->y = 0;
        player->previousX = 0;
        player->previousY = 0;
        player->id = i;

        initNextPieces(player->nextPieces);

        // Reset the score if it is a new game.
        if (currentMap == 0)
        {
            player->score = 0;
        }

        // Move to the next player in the array.
        ++player;
    }
}

void initNextPieces(u8* nextPieces)
{
    u8 i = 0;
    u8* nextPiece = nextPieces;

    // Generate random pieces for the each of the players.
    for (i = 0; i < NEXT_PIECE_COUNT; ++i)
    {
        *nextPiece = rand() % TRACK_CROSS;

        // Move to the next piece in the array.
        ++nextPiece;
    }
}

void drawPlayers()
{
    u8 i = 0;
    Player* player = players;

    for (i = 0; i < playerCount; ++i)
    {
        drawPlayer(player);

        // Move to the next player in the array.
        ++player;
    }
}

void drawPlayer(Player* player)
{
    u16 targetX = player->x * 16 * scaleFactor;
    u16 targetY = player->y * 16 * scaleFactor;

    al_draw_scaled_bitmap(allegroMiscSprites[player->id], 0, 0, TILE_WIDTH_BYTES * 2, TILE_HEIGHT, targetX, targetY, 16 * scaleFactor, 16 * scaleFactor, 0);
}

void movePlayer()
{
    u8 i = 0;
    Player* player = players;

    for (i = 0; i < playerCount; ++i)
    {
        player->previousX = player->x;
        player->previousY = player->y;

        if (i == 0)
        {
            if (gameControls.controlFlags & CONTROL_LEFT_FLAG)
            {
                if (player->x)
                {
                    --player->x;
                }
            }

            if (gameControls.controlFlags & CONTROL_RIGHT_FLAG)
            {
                if (player->x < SCREEN_TILES_X - 1)
                {
                    ++player->x;
                }
            }

            if (gameControls.controlFlags & CONTROL_UP_FLAG)
            {
                if (player->y)
                {
                    --player->y;
                }
            }

            if (gameControls.controlFlags & CONTROL_DOWN_FLAG)
            {
                if (player->y < SCREEN_TILES_Y - 1)
                {
                    ++player->y;
                }
            }

            if (gameControls.controlFlags & CONTROL_TRACK_FLAG)
            {
                // Place the track on the map at the cursor position.
                placeTrack(player);
            }

            // Clear controls to stop the cursor mover when holding down the arrows.
            gameControls.controlFlags = 0;
        }

        if (i == 1)
        {
            // TODO multiplayer.
        }

        if (player->x != player->previousX || player->y != player->previousY)
        {
            drawCellAtPosition(player->previousX, player->previousY);

            // Redraw the train if the cursor was over a train cell.
            if (cellContainsCarriage(player->previousX, player->previousY))
            {
                train.redraw = TRUE;
            }
        }

        ++player;
    }
}

void placeTrack(Player* player)
{
    u8 cell = mapCell(player->x, player->y, 0, 0);

    // Cannot place track on map features.
    if (cell & CELL_MAP_FEATURE_FLAG)
    {
        return;
    }

    // Cannot place track on scenery features.
    if (cell & CELL_ENVIRONMENT_FLAG)
    {
        return;
    }

    // You cannot place a track where the train currently resides.
    if (!cellContainsCarriage(player->x, player->y))
    {
        u8 i = 0;
        u8 weighting = 0;

        // Updates the cell in the grid at the player's cursor position with the next piece.
        updateMapCellRedraw(player->x, player->y, 0, 0, player->nextPieces[0] + 1);

        // Shuffle the pieces after the first one has been used.
        for (i = 0; i < NEXT_PIECE_COUNT - 1; ++i)
        {
            player->nextPieces[i] = player->nextPieces[i + 1];
        }

        // Use the weighting to ensure that horizontal and vertical are more common than other pieces.
        weighting = rand() % 3;

        if (weighting == 2)
        {
            // Randomly select a curve (3, 4, 5, 6).
            // Add a new piece at the end of next pieces where it will be a curve.
            player->nextPieces[NEXT_PIECE_COUNT - 1] = 3 + rand() % 4;
        }
        else if (weighting == 1)
        {
            // Add a new piece at the end of next pieces where it can be any piece.
            player->nextPieces[NEXT_PIECE_COUNT - 1] = rand() % TRACK_SPRITE_COUNT;
        }
        else
        {
            // Add a new piece at the end of next pieces where it will be horizontal or vertical.
            player->nextPieces[NEXT_PIECE_COUNT - 1] = rand() % TRACK_HORIZONTAL;
        }

        // Redraw the hud with the new next pieces.
        hudRedraw = TRUE;
    }
}