#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "raylib.h"

#define PIECE_SIZE 4
#define GRID_WIDTH 10
#define GRID_HEIGHT 20

typedef struct square_s{
    int posX;
    int posY;

    Color color;

} square_s;
typedef square_s* Square;

typedef struct Grid{
    Square** grid;

    int width;
    int height;
} Grid;

typedef struct Piece{
    Square* squares;
    int size;
} Piece;

// Init functions
Grid gridInit();
Piece pieceInit();
Square squareInit();

// Copy functions
Square copySquare(Square sq);

// Set functions
void setSquareColor(Square sq, int colorIndex);
void setPieceColor(Piece p, int colorIndex);

// Piece generation and data reading
Square getSquare(char* line, int index);
Piece getPieceFromLine(char* line);
Piece* getPiecesData(char* fileName);

int randInt(int lower, int upper);
Piece spawnPiece(Piece* pieceList);

// Bool verifications for moving
bool canMoveVert(Grid g, Piece p, int moveNum);
bool canMoveHztl(Grid g, Piece p, int moveNum);

// Moving functions
void moveSquareVert(Square sq, int shift);
void movePieceVert(Piece piece, int shift);

void moveSquareHztl(Square sq, int shift);
void movePieceHztl(Piece p, int shift);

// Bool verifications for rotating
bool rotateCollideLeft(Piece p, bool rotation);
bool rotateCollideRight(Piece p, bool rotation);
bool rotateCollideTop(Piece p, bool rotation);
bool rotateCollideBottom(Piece p, bool rotation);
bool rotateCollideGrid(Grid g, Piece p, bool rotation);

// Rotating functions
void rotateSquare(Square sq, Square ref, bool rotation);
void rotatePiece(Grid g, Piece p, bool rotation);       // False makes a counterclockwise rotation and true makes a clockwise rotation

// Grid adding functions
void addSquareToGrid(Square sq, Grid g);
void addPieceToGrid(Piece piece, Grid grid);

// Line completed detection
int removeLinesIfCompleted(Grid grid);      // Returns the number of lines completed

// Game over detection
int heightColumn(Square* column, int size);
int height(Grid g);
bool gameOver(Grid grid);