#include "gameDefines.h"

extern Meteos*game;

Board::Board()
:colorHandler({}){}

Board::Board(vi2d boardSize,float gravity,float maxGravity,float launchSpd,float spawnRate,std::array<int,10> colorRates,Renderable&tileset)
:boardSize(boardSize),gravity(gravity),maxGravity(maxGravity),launchSpd(launchSpd),spawnRate(spawnRate),colorHandler(colorRates),tileset(tileset.Decal()){
    drawOffset={(float)game->ScreenWidth()/2-boardSize.x/2*12,(float)game->ScreenHeight()/2-boardSize.y/2*12};
    yBottom=(boardSize.y-1)*12;
    for (int i=0;i<boardSize.x;i++) {
        cols.push_back(std::vector<Block>());
    }
}

void Board::spawnBlock(int col){
    BlockClump c=BlockClump();
    c.y-=128;
    c.addBlock(col,0,colorHandler.getRandomColor());
    clumps.push_back(c);
}

void Board::addClump(BlockClump&c){
    clumps.push_back(c);
}

std::vector<Block>&Board::getBlocks(int col){
    return cols[col];
}

std::vector<BlockClump>&Board::getBlockClumps(){
    return clumps;
}

void Board::removeClump(int ind){
    clumps.erase(clumps.begin()+ind);
}

void Board::convertClump(int ind){
    BlockClump&c=clumps[ind];
    for (Block&b:c.getBlocks()){
        if (b.markedForDeletion) continue;
        bool emptyAirBelow=true;
        for (int i=0;i<cols[b.pos.x/12].size();i++) {
            Block&b2=cols[b.pos.x/12][i];
            if (c.getBlockPosition(b).y+12>=b2.pos.y&&c.getBlockPosition(b).y<=b2.pos.y+12) {
                emptyAirBelow=false;
                break;
            }
        }
        if (c.getBlockPosition(b).y>=yBottom) {
            emptyAirBelow=false;
        }
        if (emptyAirBelow) {
            BlockClump c2;
            for (int i=0;i<c.getBlocks().size();i++) {
                Block&b2=c.getBlocks()[i];
                if (c.getBlockPosition(b).x==b2.pos.x) {
                    b2.markedForDeletion=true;
                    c2.addBlock(b2.pos,b2.col);
                }
                c2.y=c.y;
            }
            clumps.push_back(c2);
        } else {
            b.pos=c.getBlockPosition(b);
            cols[b.pos.x/12].push_back(b);
        }
    }
    removeClump(ind);
}

BlockColor ColorDistributor::getRandomColor(){
    int val=range(game->gen);
    for (int i=0;i<10;i++) {
        if (rangeTable[i].first!=-1&&
            rangeTable[i].first<=val&&
            rangeTable[i].second>val) {
            return (BlockColor)i;
        }
    }
    return BlockColor::WHITE;
}

void Board::removeBlock(int col,int ind){
    cols[col].erase(cols[col].begin()+ind);
}