import Cog from "@robotical/webapp-types/dist-types/src/application/RAFTs/Cog/Cog";
import { getConnectedCog } from "../../utils/CogManager";

class SimplePlatformerControls extends Phaser.Plugins.ScenePlugin {

    cursors: Phaser.Types.Input.Keyboard.CursorKeys | undefined;
    xbox: any;

    up: boolean;
    right: boolean;
    down: boolean;
    left: boolean;
    aDown: boolean;
    xDown: boolean;
    events: Phaser.Events.EventEmitter;
    input: Phaser.Input.InputPlugin | undefined;
    lastMobDir: string;
    prefInputMethod: string;

    selectedLeftBlock: string | undefined;
    selectedRightBlock: string | undefined;
    selectedUpBlock: string | undefined;
    selectedDownBlock: string | undefined;

    constructor(scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager, pluginKey: string) {

        super(scene, pluginManager, pluginKey);
        this.cursors = undefined;
        this.xbox = Phaser.Input.Gamepad.Configs.XBOX_360;
        this.up = false;
        this.right = false;
        this.down = false;
        this.left = false;
        this.aDown = false;
        this.xDown = false;
        this.events = new Phaser.Events.EventEmitter();
        this.input = undefined;
        this.lastMobDir = 'idle-right';
        this.prefInputMethod = 'touch';

    }

    _reset(cursors?: Phaser.Types.Input.Keyboard.CursorKeys | undefined) {
        this.up = false;
        this.right = false;
        this.down = false;
        this.left = false;
        this.aDown = false;
        this.xDown = false;

        if (cursors) {
            cursors.up.isDown = false;
            cursors.right.isDown = false;
            cursors.down.isDown = false;
            cursors.left.isDown = false;
        }
    }

    uregisterCogEvents(cog?: Cog) {
        const connectedCog = cog ? cog : getConnectedCog();
        if (connectedCog) {
            connectedCog.publishedDataAnalyser.removeAllListeners();
        }
    }

    registerCogEvents(cog?: Cog) {
        this.uregisterCogEvents(cog);
        const connectedCog = cog ? cog : getConnectedCog();
        if (connectedCog) {
            const eventsMap = connectedCog.publishedDataAnalyser.eventsMap;
            connectedCog.publishedDataAnalyser.on(eventsMap.tilt.backward, () => {
                this._reset();
                this[this.selectedDownBlock as 'up' | 'right' | 'down' | 'left'] = true;
            });
            connectedCog.publishedDataAnalyser.on(eventsMap.tilt.forward, () => {
                this._reset();
                this[this.selectedUpBlock as 'up' | 'right' | 'down' | 'left'] = true;
            });
            connectedCog.publishedDataAnalyser.on(eventsMap.tilt.left, () => {
                this._reset();
                this[this.selectedLeftBlock as 'up' | 'right' | 'down' | 'left'] = true;
            });
            connectedCog.publishedDataAnalyser.on(eventsMap.tilt.right, () => {
                this._reset();
                this[this.selectedRightBlock as 'up' | 'right' | 'down' | 'left'] = true;
            });
            connectedCog.publishedDataAnalyser.on(eventsMap.tilt.none, () => {
                this._reset();
            });
        }
    }

    start() {

        if (!this.input) {
            this.input = this.scene?.input;
        }

        this.prefInputMethod = 'touch';

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

        if (!this.cursors) {
            return;
        }

        // reset!
        this._reset(this.cursors);


        this.input?.keyboard?.on('keydown', (e: KeyboardEvent) => {
            switch (e.code) {
                case 'Space':
                    this.aDown = true;
                    break;
                case 'KeyD':
                case 'KeyX':
                    this.xDown = true;
                    break;
            }
            this.prefInputMethod = 'keyboard';
        });

        this.input?.keyboard?.on('keyup', (e: KeyboardEvent) => {
            this.events.emit('anyup');
            switch (e.code) {
                case 'Space':
                    this.aDown = false;
                    this.events.emit('aup');
                    break;
                case 'KeyD':
                case 'KeyX':
                    this.xDown = false;
                    this.events.emit('xup');
                    break;
            }
        });

        this.registerCogEvents();

        this.scene?.events.on('preupdate', this.preUpdate, this);
        this.scene?.events.on('shutdown', this.shutdown, this);
    }

    preUpdate() {
        const connectedCog = getConnectedCog();
        // if (!connectedCog) {
        if (false) { // comment in the above to use the arrow keys instead of the cog
            this.up = !!this.cursors?.up.isDown;
            this.right = !!this.cursors?.right.isDown;
            this.down = !!this.cursors?.down.isDown;
            this.left = !!this.cursors?.left.isDown;
        }
        // @ts-ignore - justUp is not in the Pointer class for some reason
        // if (this.input?.activePointer.justUp) {
        //     this.prefInputMethod = 'touch';
        // }

        // if (this.prefInputMethod == 'touch') {

        //     // @ts-ignore - justUp is not in the Pointer class for some reason
        //     if (this.input?.activePointer.justUp) {
        //         switch (this.lastMobDir) {
        //             case 'idle-right':
        //                 this.lastMobDir = 'run-right';
        //                 break;
        //             case 'idle-left':
        //                 this.lastMobDir = 'run-left';
        //                 break;
        //             case 'run-right':
        //                 this.lastMobDir = 'run-left';
        //                 break;
        //             case 'run-left':
        //                 this.lastMobDir = 'run-right';
        //                 break;
        //         }
        //     }

        //     switch (this.lastMobDir) {
        //         case 'idle-right':
        //         case 'idle-left':
        //             this.left = false;
        //             this.right = false;
        //             break;
        //         case 'run-right':
        //             this.right = true;
        //             this.left = false;
        //             break;
        //         case 'run-left':
        //             this.right = false;
        //             this.left = true;
        //             break;
        //     }

        // if (this.input?.activePointer.isDown) {
        //     this.aDown = true;
        //     this.up = true;
        //     this.down = false;
        // } else {
        //     this.aDown = false;
        //     this.up = false;
        //     this.down = true;
        // }
        // }
    }

    shutdown() {
        this.scene?.events.off('preupdate', this.preUpdate);
        this.scene?.events.off('shutdown', this.shutdown);
        this.uregisterCogEvents();
    }
}

export default SimplePlatformerControls;
