import './style.css'

import {docReady} from "canvas-common";
import {World} from "./World.ts";
import {Player} from "./Player.ts";
import {Vector} from "./base.ts";
import {BasicEnemy, ContainerEnemy, HealthEnemy, ShootingEnemy} from "./Enemies.ts";
import {HUD} from "./ui.ts";
import {Pistol} from "./weapons.ts";
import {ItemManagement} from "./items.ts";


let hud: HUD;
let world: World;
let config: Config;
let state: WorldState;
let ctx: CanvasRenderingContext2D;
let canvas;

export class Config {
    private _fps: number = 60;

    get fps(): number {
        return this._fps;
    }
}

export class WorldState {
    private _ended: boolean = false;


    get ended(): boolean {
        return this._ended;
    }
}


function updateCanvas() {
    ctx.clearRect(0, 0, world.size.x, world.size.y);
    hud.draw(ctx)
    if(!state.ended) {
        world.enemiesAct()
        world.player.act()
        world.draw()
        for(let key in keys) {
            if(keys[key].state) {
                keys[key].fun(keys[key].intensity)
            }
        }
    } else {
        ctx.fillText('End', 15, 15)
    }

    setTimeout(function () {
        requestAnimationFrame(updateCanvas);
    }, 1000 / config.fps)

}

function makeKey(char, fun) {
    keys[char] = {
        state: false,
        fun: fun
    }
}

let keys = {};
makeKey('w', function (intensity: number) {
    world.movePlayer(new Vector(0, -world.player.stats.speed * intensity))
})
makeKey('s', function (intensity: number) {
    world.movePlayer(new Vector(0, world.player.stats.speed * intensity))
})
makeKey('a', function (intensity: number) {
    world.movePlayer(new Vector(-world.player.stats.speed * intensity, 0))
})
makeKey('d', function (intensity: number) {
    world.movePlayer(new Vector(world.player.stats.speed * intensity, 0))
})


function keyUp(event) {
    if(event.key in keys) {
        keys[event.key].state = false;
        keys[event.key].intensity = 0;
    }
}

function keyDown(event) {
    if(event.key in keys) {
        keys[event.key].state = true;
        keys[event.key].intensity = 1;
    }
}

document.onkeyup = keyUp;
document.onkeydown = keyDown;
docReady(function () {
    canvas = document.getElementById('canvas');

    canvas.width = window.innerWidth;

    canvas.height =  window.innerHeight;


    ctx = canvas.getContext("2d");
    config = new Config();
    let player = Player.generatePlayer(new Vector(window.innerWidth /2, window.innerHeight / 2));

    world = new World(player, ctx, new Vector(window.innerWidth,  window.innerHeight));
    state = new WorldState();

    setInterval(() => {
        BasicEnemy.spawnBasicEnemy(world)
    }, 1_000)

    setInterval(() => {
        ShootingEnemy.spawnShootingEnemy(world)
    }, 3_000)

    setInterval(() => {
        HealthEnemy.spawnHealthEnemy(world)
    }, 15_000)

    setInterval(() => {
        ContainerEnemy.spawnContainerEnemy(world)
    }, 10_000)

    player.addWeapon(Pistol.generatePistol(world))
    hud = new HUD(world, keys);

    canvas.onmousedown = (event) => {
        event.preventDefault()
        let pos = new Vector(event.x, event.y)
        hud.mouseDown(pos)
    }
    canvas.onmouseup = (event) => {
        event.preventDefault()
        let pos = new Vector(event.x, event.y)
        hud.mouseUp(pos)
    }

    canvas.onmousemove = (event) => {
        event.preventDefault()
        let pos = new Vector(event.x, event.y)
        hud.mouseMove(pos)
    }

    canvas.addEventListener("touchstart", (event) => {
        event.preventDefault()
        let touch = event.touches[0]
        let pos = new Vector(touch.clientX, touch.clientY)
        hud.mouseDown(pos)
    });

    canvas.addEventListener("touchend",  (event) => {
        event.preventDefault()
        let pos = new Vector(event.clientX, event.clientY)
        hud.mouseUp(pos)
    });

    canvas.addEventListener("touchmove",  (event) => {
        event.preventDefault()
        let touch = event.touches[0]
        let pos = new Vector(touch.clientX, touch.clientY)
        hud.mouseMove(pos)
    });

    ItemManagement.initializeItems()

    requestAnimationFrame(updateCanvas);

})

