class GameState 
{
    static GAME = 0;
    static INTRO = 1;
    static GAMEOVER = 2;
}

class Game 
{
    constructor()
    {
        this.tickRate = 1;

        this.log = new Log( engine );
        this.buildingManager = new BuildingManager( engine , this.log );

        this.restart();

        this.#recalculateConsumption();
    }

    restart()
    {
        this.state = GameState.INTRO;
        this.money = 100;
        this.population = 3;
        this.beds = 0;
        this.homeless = 3;
        this.water = 20;
        this.food = 20;
        this.waterProduction = 1;
        this.foodProduction = 1;
        this.waterConsumption = 0;
        this.foodConsumption = 0;
        this.waterStorage = 30;
        this.foodStorage = 30;

        this.crime = 0;
        this.maxCrime = 100;
        this.policeLevel = 0;

        this.waterFillLevel = (this.water/this.waterStorage)*0.12;

        this.moneyTick = 7;
        this.moneyTimer = 0;
        this.waterTick = 9;
        this.waterTimer = 0;
        this.foodTick = 11;
        this.foodTimer = 0;
        this.crimeTick = 13;
        this.crimeTimer = 0;

        this.gameTime = 0;

        this.b_buildingMode = false;
        this.selectedBuilding = -1;

        if ( this.rafts !== undefined )
        {
            for ( let i = 0 ; i < this.rafts.length ; ++i ) this.rafts[i].delete();
        }
        this.rafts = [];
        this.raftSpawnTime = 60;
        this.raftTimer = this.raftSpawnTime;
        this.raftCounter = 0;

        this.buildingManager.restart();
        this.log.restart();
    }

    removeRaft( raft )
    {
        for ( let i = 0 ; i < this.rafts.length ; ++i )
        {
            if ( this.rafts[i] === raft )
            {
                this.population += this.rafts[i].population;
                sound_raft.play();
                this.populationChanged();
                this.rafts[i].delete();
                ui.showPopup( this.rafts[i].population+" new survivors have arrived!" );
                this.rafts.splice( i , 1 );
                return;
            }
        }
    }

    update( dt )
    {
        if ( game.state === GameState.GAME )
        {
            this.gameTime += dt*this.tickRate;

            this.raftTimer += dt*this.tickRate;
            if ( this.raftTimer >= this.raftSpawnTime )
            {
                console.log( "new raft spawned" );
                this.raftCounter++;
                this.rafts.push( new Raft() );
                this.raftTimer = 0;
            }

            // MONEY
            this.moneyTimer += dt*this.tickRate;
            if ( this.moneyTimer >= this.moneyTick )
            {
                // some basic income from a random source
                this.money += 5;
                // taxes
                var housedPopulation = this.population-this.homeless;
                this.money += housedPopulation*0.36;
                ui.updateGameUI();
                this.moneyTimer = 0;
            }

            // WATER
            this.waterTimer += dt*this.tickRate;
            if ( this.waterTimer >= this.waterTick )
            {
                this.water += (this.waterProduction-this.waterConsumption);
                this.waterChanged();
                if ( this.water <= 0 )
                {
                    game.state = GameState.GAMEOVER;
                    ui.gameOver( GameOverReason.WATER );
                    return;
                }
                if ( this.water < 2 ) ui.showPopup( "Low Water Supply" );
                this.waterTimer = 0;
            }

            this.foodTimer += dt*this.tickRate;
            if ( this.foodTimer >= this.foodTick )
            {
                this.food += (this.foodProduction-this.foodConsumption);
                this.foodChanged();
                if ( this.food <= 0 )
                {
                    game.state = GameState.GAMEOVER;
                    ui.gameOver( GameOverReason.FOOD );
                    return;
                }
                if ( this.food < 2 ) ui.showPopup( "Low Food Supply" );
                this.foodTimer = 0;
            }

            // CRIME
            this.crimeTimer += dt*this.tickRate;
            if ( this.crimeTimer >= this.crimeTick )
            {
                // homeless increase crime
                this.crime += this.homeless*0.75;
                // low water increases crime
                var waterPercent = this.water/this.waterStorage;
                if ( waterPercent < 0.2 ) this.crime += 3;
                // low food increases crime
                var foodPercent = this.food/this.foodStorage;
                if ( foodPercent < 0.2 ) this.crime += 2;
                // police decreases crime
                this.crime -= this.policeLevel;
                if ( this.crime < 0 ) this.crime = 0;
                ui.updateGameUI();
                if ( this.crime >= this.maxCrime )
                {
                    game.state = GameState.GAMEOVER;
                    ui.gameOver( GameOverReason.CRIME );
                    return;
                }
                this.crimeTimer = 0;
            }

            for ( let i = 0 ; i < this.rafts.length ; ++i )
            {
                this.rafts[i].update( dt*this.tickRate );
            }
        }
    }

    draw()
    {
        this.log.draw();
        this.buildingManager.draw();

        for ( let i = 0 ; i < this.rafts.length ; ++i )
        {
            this.rafts[i].draw();
        }
    }

    populationChanged()
    {
        this.homeless = this.population-this.beds;
        if ( this.homeless < 0 ) this.homeless = 0;
        ui.updateGameUI();
        this.#recalculateConsumption();
    }

    waterChanged()
    {
        if ( this.water > this.waterStorage ) this.water = this.waterStorage;
        this.waterFillLevel = (this.water/this.waterStorage)*0.12;
        this.buildingManager.updateWaterFillLevel();
        ui.updateGameUI();
    }

    foodChanged()
    {
        if ( this.food > this.foodStorage ) this.food = this.foodStorage;
        ui.updateGameUI();
    }

    policeChanged()
    {
        ui.updateGameUI();
    }

    #recalculateConsumption()
    {
        this.waterConsumption = this.population*0.28;
        this.foodConsumption = this.population*0.2;
    }
}