import { GdRoot } from "../GameData/index.ts";
import { ECellType, SimCommandCreateTower, SimMain } from "../Simulation/index.ts";
import { Vector2 } from "../Util/index.ts";
import { VisMain } from "../Vis/index.ts";
import { IView, ViewManager } from "./index.ts";

export class ViewGame implements IView {
    private _div: string;
    private _viewManager: ViewManager;
    private _canvas: HTMLCanvasElement | null = null;
    private _simMain: SimMain | null = null;
    private _visMain: VisMain | null = null;
    private _gdRoot: GdRoot;
    private _buttonReload: HTMLButtonElement | null = null;
    private _buttonStart: HTMLButtonElement | null = null;

    constructor(div: string, gdRoot: GdRoot, viewManager: ViewManager) {
        this._gdRoot = gdRoot;
        this._div = div;
        this._viewManager = viewManager;
        this.canvasResized = this.canvasResized.bind(this);
        this.canvasMouseMoved = this.canvasMouseMoved.bind(this);
        this.canvasMouseDown = this.canvasMouseDown.bind(this);
        this.buttonReloadClicked = this.buttonReloadClicked.bind(this);
        this.buttonStartClicked = this.buttonStartClicked.bind(this);
    }

    public get div(): string {
        return this._div;
    }

    public activate() {
        this._canvas = document.getElementById("canvas-game") as HTMLCanvasElement;
        this._buttonReload = document.getElementById("button-reload") as HTMLButtonElement;
        this._buttonStart = document.getElementById("button-start") as HTMLButtonElement;
        this._simMain = new SimMain(this._gdRoot, 0);
        this._visMain = new VisMain(this._simMain, this._canvas);

        window.addEventListener("resize", this.canvasResized, false);
        this._canvas?.addEventListener("mousemove", this.canvasMouseMoved);
        this._canvas?.addEventListener("mousedown", this.canvasMouseDown);
        this._buttonReload?.addEventListener("click", this.buttonReloadClicked);
        this._buttonStart?.addEventListener("click", this.buttonStartClicked);
    }

    public deactivate() {
        window.removeEventListener("resize", this.canvasResized, false);
        this._canvas?.removeEventListener("mousemove", this.canvasMouseMoved);
        this._canvas?.removeEventListener("mousedown", this.canvasMouseDown);
        this._buttonReload?.removeEventListener("click", this.buttonReloadClicked);
        this._buttonStart?.removeEventListener("click", this.buttonStartClicked);
        this._canvas = null;
        this._buttonReload = null;
        this._buttonStart = null;
        this._simMain = null;
        this._visMain = null;
    }

    private canvasResized() {
         this._visMain?.onResized();
    }

    private buttonReloadClicked() {
        this._simMain?.reload();
    }

    private buttonStartClicked() {
        if (this._simMain == null) {
            return;
        }
        this._simMain.currentLevel.paused = false;
    }

    private canvasMouseMoved(e: MouseEvent) {
        const simLevel = this._simMain?.currentLevel;
        if (simLevel == null || this._visMain == null) {
            return;
        }

        const rect = this._canvas!.getBoundingClientRect();
        const hex = this._visMain.visLevel.getHexFromScreenCoords(new Vector2(e.clientX - rect.left, e.clientY - rect.top));
        const index = simLevel.getCellIndex(hex);
        if (index != -1 && simLevel.simCells[index].type != ECellType.Blocked) {
            simLevel.highlightedIndex = index;
        }
        else {
            simLevel.highlightedIndex = -1;
        }
    }

    private canvasMouseDown(e: MouseEvent) {
        const simLevel = this._simMain?.currentLevel;
        if (simLevel == null || this._visMain == null) {
            return;
        }

        const rect = this._canvas!.getBoundingClientRect();
        const hex = this._visMain.visLevel.getHexFromScreenCoords(new Vector2(e.clientX - rect.left, e.clientY - rect.top));
        this._simMain?.addCommand(new SimCommandCreateTower(this._gdRoot, simLevel, hex, 0));
    }
}