import { ClientMessageNewClient, ClientMessageSendCoordinates, ServerMessage } from "../Data.js";
import { WebSocketController, WebsocketMessageListener } from "./WebSocketController.js";

type ClientData = {
    id: number,
    color: number,
    x: number,
    y: number,
    graphicObject: Phaser.GameObjects.Graphics
}

export class MainScene extends Phaser.Scene implements WebsocketMessageListener {

    webSocketController: WebSocketController;
    
    otherPlayers: ClientData[] = [];
    idToClientDataMap: Map<number, ClientData> = new Map();

    ownData: ClientData;

    cursors: Phaser.Types.Input.Keyboard.CursorKeys;

    constructor() {
        super({
            key: "MainScene"
        });
    }

    init(params: any): void {
    }

    preload(): void {
    }

    create(): void {

        let color: number = Phaser.Display.Color.RandomRGB(128).color;
        this.ownData = this.createPlayer(400, 300, color, -1);

        this.cursors = this.input.keyboard.createCursorKeys();

        this.webSocketController = new WebSocketController(this, (controller: WebSocketController) => {
            let message: ClientMessageNewClient = {
                type: "newClient",
                x: this.ownData.x,
                y: this.ownData.y,
                color: this.ownData.color
            }
            controller.send(message);    
        });

    }

    createPlayer(x: number, y: number, color: number, id: number): ClientData {
        let circle = new Phaser.Geom.Circle(x, y, 10);
        let graphics = this.add.graphics({ fillStyle: { color: color } });
        graphics.fillCircleShape(circle);

        return {
            color: color,
            x: x,
            y: y,
            graphicObject: graphics,
            id: id
        }
    }


    update(time: number, delta: number): void {

        let oldX = this.ownData.x;
        let oldY = this.ownData.y;
        let d: number = 10;

        if (this.cursors.left.isDown) {
            this.ownData.x -= d;
        }
        else if (this.cursors.right.isDown) {
            this.ownData.x += d;
        }

        if (this.cursors.up.isDown) {
            this.ownData.y -= d;
        }
        else if (this.cursors.down.isDown) {
            this.ownData.y += d;
        }

        if (this.ownData.x != oldX || this.ownData.y != oldY) {
            this.movePlayer(this.ownData.graphicObject, this.ownData.x - oldX, this.ownData.y - oldY);
            let message: ClientMessageSendCoordinates = {
                type: "sendCoordinates",
                x: this.ownData.x,
                y: this.ownData.y
            }
            this.webSocketController.send(message);
        }

    }

    movePlayer(graphicObject: Phaser.GameObjects.Graphics, dx: number, dy: number) {

        graphicObject.setPosition(graphicObject.x + dx, graphicObject.y + dy);

    }

    onMessage(serverMessage: ServerMessage) {

        let clientData: ClientData;

        if(serverMessage.id != null){
            clientData = this.idToClientDataMap.get(serverMessage.id);
        }

        switch (serverMessage.type) {
            case "newClient":
                clientData = this.createPlayer(serverMessage.x, serverMessage.y, serverMessage.color, serverMessage.id);
                this.otherPlayers.push(clientData);
                this.idToClientDataMap.set(serverMessage.id, clientData);
                break;
            case "sendCoordinates":
                this.movePlayer(clientData.graphicObject, serverMessage.x - clientData.x, serverMessage.y - clientData.y);
                clientData.x = serverMessage.x;
                clientData.y = serverMessage.y;
                break;
            case "clientGone":
                clientData.graphicObject.destroy();
                this.otherPlayers.splice(this.otherPlayers.indexOf(clientData), 1);
                this.idToClientDataMap.delete(clientData.id);
                break;
        }

    }



}