import { Button } from "../../libraries/components/Button.js";
import { Point } from "../../libraries/spatial/Point.js";

export class LevelSelectState {
    constructor(fsm) {
        this.stateMachine = fsm;
        this.boundMouseEvent = {};
        this.levelData = [];
        this.playerData = {};
        this.levelButtons = [];
        this.offsetX = 0;
        this.page = 0;
        this.maxPage = 0;
        this.canvasBounds = null;
    }

    init() {
        this.boundMouseEvent['mousedown'] = this.mouseDown.bind(this);
        this.boundMouseEvent['mousemove'] = this.mouseMove.bind(this);
        for(let key in this.boundMouseEvent) {
            window.addEventListener(key, this.boundMouseEvent[key]);
        }

        this.levelButtons = [];
        for(let i = 0; i <= this.levelData.length; i++) {
            let buttonText = i+1;
            if(i == this.levelData.length) {
                buttonText = "%";
            }
            let button = new Button(0,0, 50, 50, buttonText, {fontSize: 18, textStrokeStyle: null});
            button.hoverFunction((ctx) => {
                if(this.playerData.level > i+1) {
                    ctx.fillStyle = "rgba(49, 141, 79, 0.8)";
                } else if(this.playerData.level < i+1) {
                    ctx.fillStyle = "rgba(224, 104, 78, 0.8)";
                } else {
                    ctx.fillStyle = "rgba(255,255,255,0.8)";
                }
            });
            button.backgroundDrawFunction((ctx, scaledCanvas) => {
                if(this.playerData.level > i+1) {
                    ctx.fillStyle = "rgba(49, 141, 79, 0.5)";
                } else if(this.playerData.level < i+1) {
                    ctx.fillStyle = "rgba(224, 104, 78, 0.5)";
                } else {
                    ctx.fillStyle = "rgba(255,255,255,0.5)";
                }
                
                ctx.beginPath();
                ctx.rect(-button.bounds.width / 2, -button.bounds.height / 2, button.bounds.width, button.bounds.height);
                ctx.closePath();

                if(button.isHovered) {
                    document.body.style.cursor = "pointer";
                    button.whenHovered(ctx, scaledCanvas);
                }
                ctx.fill();
            });
            button.clickFunction((event) => {
                if(this.playerData.level >= i+1) {
                    this.playerData.current = i+1;
                    this.stateMachine.transitionTo("game");
                }
            })
            this.levelButtons.push(button);
        }

        this.nextPageButton = new Button(0, 0, 100, 50, "next", {fontSize: 28, textStrokeStyle: null});
        this.nextPageButton.clickFunction((event) => {
            this.page++;
            this.page = Math.min(this.page, this.maxPage);
        });
        this.nextPageButton.hoverFunction((ctx) => {
            ctx.fillStyle = "rgba(255,255,255,0.8)";
        });
        this.prevPageButton = new Button(0, 0, 100, 50, "prev",{fontSize: 28, textStrokeStyle: null});
        this.prevPageButton.clickFunction((event) => {
            this.page--;
            this.page = Math.max(0, this.page);
        })
        this.prevPageButton.hoverFunction((ctx) => {
            ctx.fillStyle = "rgba(255,255,255,0.8)";
        });

    }

    draw(ctx, scaledCanvas) {
        ctx.fillStyle = "white";
        ctx.font = "48px Luckiest Guy";
        ctx.textAlign = "center";
        ctx.lineWidth = 4;
        this.canvasBounds = scaledCanvas.bounds;
        let center = this.canvasBounds.center;
        ctx.fillText(`Level Select`, center.x, 48);
        ctx.strokeText(`Level Select`, center.x, 48);

        let levelGridWidth = this.canvasBounds.width - 40;
        let numberOfLevelButtonsCols = Math.floor(levelGridWidth / 70);
        let numberOfLevelButtonsRows = Math.floor(this.levelButtons.length / numberOfLevelButtonsCols)
        let maxRowsInHeight = Math.max(1, Math.floor((this.canvasBounds.height - 200) / 70))
        let numberOfPages = Math.max(1, Math.floor(numberOfLevelButtonsRows / maxRowsInHeight));
        this.maxPage = numberOfPages;
        this.offsetX = (levelGridWidth - ((numberOfLevelButtonsCols-1) * 70) + 50) / 2;
        let min = this.page * (numberOfLevelButtonsCols * maxRowsInHeight)
        let max = Math.min(this.levelButtons.length, (this.page + 1) * (numberOfLevelButtonsCols * maxRowsInHeight));

        for(let i = min; i < max; i++) {
            let button = this.levelButtons[i];

            let buttonPosition = new Point((i % numberOfLevelButtonsCols) * 70 + this.offsetX, Math.floor((i / numberOfLevelButtonsCols)) * 70 + 100 - (this.page * maxRowsInHeight * 70));
            if(buttonPosition.y > Math.max(100,this.canvasBounds.height - 100)) {
                break;
            }
            button.setPosition(buttonPosition.x, buttonPosition.y);
            button.draw(ctx, scaledCanvas);
        }

        this.nextPageButton.setPosition(center.x + 105, Math.max(170, this.canvasBounds.height - 100));
        this.nextPageButton.draw(ctx, scaledCanvas);
        this.prevPageButton.setPosition(center.x - 105, Math.max(170, this.canvasBounds.height - 100));
        this.prevPageButton.draw(ctx, scaledCanvas);
    }

    setLevelData(data) {
        this.levelData = data;
    }

    setPlayerData(data) {
        this.playerData = data;
    }

    update(delta) {

    }   

    mouseDown(event) {
        let levelGridWidth = this.canvasBounds.width - 40;
        let numberOfLevelButtonsCols = Math.floor(levelGridWidth / 70);
        let maxRowsInHeight = Math.max(1, Math.floor((this.canvasBounds.height - 200) / 70))

        let min = this.page * (numberOfLevelButtonsCols * maxRowsInHeight)
        let max = Math.min(this.levelButtons.length, (this.page + 1) * (numberOfLevelButtonsCols * maxRowsInHeight));
        for(let i = min; i < max; i++) {
            let button = this.levelButtons[i];
            button.mouseDown(event);
        }

        this.nextPageButton.mouseDown(event);
        this.prevPageButton.mouseDown(event);
    }

    mouseMove(event) {
        document.body.style.cursor = "default";
        let levelGridWidth = this.canvasBounds.width - 40;
        let numberOfLevelButtonsCols = Math.floor(levelGridWidth / 70);
        let maxRowsInHeight = Math.max(1, Math.floor((this.canvasBounds.height - 200) / 70))

        let min = this.page * (numberOfLevelButtonsCols * maxRowsInHeight)
        let max = Math.min(this.levelButtons.length, (this.page + 1) * (numberOfLevelButtonsCols * maxRowsInHeight));
        for(let i = min; i < max; i++) {
            let button = this.levelButtons[i];
            button.mouseMove(event);
        }

        this.nextPageButton.mouseMove(event);
        this.prevPageButton.mouseMove(event);
    }

    enter() {
        this.init();
    }
    leave() {
        for(let key in this.boundMouseEvent) {
            window.removeEventListener(key, this.boundMouseEvent[key]);
        }
    }
}