#ifndef PLAYER_H
#define PLAYER_H

#include <cpctelera.h>
#include "Actor.h"
#include "Difficulty.h"
#include "GameState.h"
#include "GameTypes.h"
#include "Enemy.h"
#include "Hud.h"
#include "Interactable.h"
#include "Interrupt.h"
#include "Inventory.h"
#include "Item.h"
#include "Keys.h"
#include "Map.h"
#include "Object.h"
#include "Objective.h"
#include "Projectile.h"
#include "Water.h"
#include "sprites/PlayerSprites.h"

// Player movement states.
#define PLAYER_STATE_WATER 0
#define PLAYER_STATE_WALKING 1
#define PLAYER_STATE_JUMPING 2
#define PLAYER_STATE_FALLING 3

typedef struct Player Player;

struct Player
{
    // Actor variables.
    Object object;
    u8 health;

    // Player variables.

    // The projectile that has been fired by the player's projectile weapon.
    Projectile projectile;

    // The current movement of the player (land or water).
    u8 movementMode;

    // The current movement action state (walking, jumping, falling) that the player is in.
    u8 state;

    // The amount of ammo that the player has for their projectile weapon.
    u8 projectileAmmo;

    // The amount of oxygen the player has left.
    u8 oxygen;

    // The graphic representing the player in game.
    u8 playerSprite[64];

    // The number of picks that the player is carrying (for destroying cracked blocks).
    u8 pickCount;

    // Flag to indicate if a spike has been detected when processing a cell.
    u8 spikeDetected;
};

// Global player object.
extern Player player;

// Initialises the player with initial values.
void initPlayer(u8 x, u8 y);

// Draws the player on the screen as positioned in the player object.
void drawPlayer();

// Moves the player position based on user input.
void movePlayer();

// Runs any logic required for the player function such as interactions and velocity/position.
void logicPlayer();

// Processes the cell in the specified room that the player is potentially occupying.
u8 processCellInRoom(u8 x, u8 y, u8 roomX, u8 roomY);

// Processes the cell in the current room that the player is potentially occupying.
u8 processCell(u8 x, u8 y);

// Test whether the player is colliding with any enemy.
void playerEnemyCollision();

// Player has been damaged and will lose health and possible lives as a result.
void playerLoseHealth(u8 amount);

// Depletes player oxygen the longer the player is in the water (rate depends on the type of water).
void depleteOxygen(u8 waterType);

// Moves the screen to a room on the x axis (left or right).
void moveRoomX(u8 newX, i8 roomDeltaX);

// Flips the player sprite horizontally based on the direction chosen (x velocity).
void flipPlayerSprite(i8 xVelocity);

// Updates the player sprite based on the player movement mode.
void updatePlayerSprite(u8 mode);

// Moves the player to a new location on the map.
void teleportPlayer(u8 destinationX, u8 destinationY, u8 destinationRoomX, u8 destinationRoomY);

// Play game over sound and display black on screen.
void playGameOverSound();

// Reduces the objective count when an objective action is completed and updates the score.
void reduceObjectiveActionCount();

#endif