// by VienDesu! Poring Team 2023

function create_control_buttons() {

    // A-Y Buttons
    const DivBMain = document.createElement("div");
    DivBMain.className = "gamepad-buttons";
    DivBMain.id = "gamepad-div";
    const DivBRow1 = document.createElement("div");
    DivBRow1.className = "gamepad-buttons-row";
    const DivBRow2 = document.createElement("div");
    DivBRow2.className = "gamepad-buttons-row";
    const DivBRow3 = document.createElement("div");
    DivBRow3.className = "gamepad-buttons-row";

    const DivB_Y = document.createElement("div");
    DivB_Y.className = "gamepad-button Y";
    DivB_Y.id = "buttonA";
    const DivB_X = document.createElement("div");
    DivB_X.className = "gamepad-button X";
    DivB_X.id = "buttonShift";
    const DivB_B = document.createElement("div");
    DivB_B.className = "gamepad-button B";
    DivB_B.id = "buttonX";
    const DivB_A = document.createElement("div");
    DivB_A.className = "gamepad-button A";
    DivB_A.id = "buttonZ";

    // LB-RB Buttons
    const DivB_LB = document.createElement("div");
    DivB_LB.className = "gamepad-bumper LB";
    DivB_LB.id = "buttonQ";
    const DivB_RB = document.createElement("div");
    DivB_RB.className = "gamepad-bumper RB";
    DivB_RB.id = "buttonW";

    // Adding
    document.body.appendChild(DivB_LB);
    document.body.appendChild(DivB_RB);

    DivBMain.appendChild(DivBRow1);
    DivBMain.appendChild(DivBRow2);
    DivBMain.appendChild(DivBRow3);

    DivBRow1.appendChild(DivB_Y);
    DivBRow2.appendChild(DivB_X);
    DivBRow2.appendChild(DivB_B);
    DivBRow3.appendChild(DivB_A);

    document.body.appendChild(DivBMain);
}

function create_fps_button() {
    // Remove in release 
    const keys = [{ key: 'F2', keyCode: 113 }];

    const FPSBtn = document.createElement("div");
    FPSBtn.className = "fps-button";
    FPSBtn.id = "buttonF2";
    document.body.appendChild(FPSBtn); 

    for (const key of keys) {
        const elementId = key.id === undefined ? `button${key.key}` : key.id;
        console.log(`Setting up the ${elementId} key...`);
        setupKey(elementId, key.key, key.keyCode);
    }
}

function create_dpad_buttons() {
    // Скуфting elements
    const DivDMain = document.createElement("div");
    DivDMain.className = "dpad-buttons";
    DivDMain.id = "dpad-div";
    const DivDRow1 = document.createElement("div");
    DivDRow1.className = "dpad-buttons-row";
    const DivDRow2 = document.createElement("div");
    DivDRow2.className = "dpad-buttons-row";

    const DivD_L = document.createElement("div");
    DivD_L.className = "dpad-button left";
    DivD_L.id = "buttonLeft";
    const DivD_U = document.createElement("div");
    DivD_U.className = "dpad-button up";
    DivD_U.id = "buttonUp";
    const DivD_D = document.createElement("div");
    DivD_D.className = "dpad-button down";
    DivD_D.id = "buttonDown";
    const DivD_R = document.createElement("div");
    DivD_R.className = "dpad-button right";
    DivD_R.id = "buttonRight";

    // Adding
    DivDMain.appendChild(DivDRow1);
    DivDMain.appendChild(DivDRow2);

    DivDRow1.appendChild(DivD_L);
    DivDRow1.appendChild(DivD_U);
    DivDRow2.appendChild(DivD_D);
    DivDRow2.appendChild(DivD_R);

    document.body.appendChild(DivDMain);

    currentControlElement = "dpad";
}

function create_joystick() {
    const JoyDiv = document.createElement("div");
    JoyDiv.id = "joyDiv";
    document.body.appendChild(JoyDiv);
    const kbd = joyStates;
    const joy = new JoyStick('joyDiv', {internalFillColor: "#373737", internalStrokeColor: "#FFFFFF", externalStrokeColor: "#FFFFFF"}, (stickData) => {
        disableActive();
        switch (stickData.cardinalDirection) {
            case 'NE':
            case 'NW':
            case 'N':
                kbd.up.status = true;
                sendEvent(false, kbd.up.code);
                break;
            case 'E':
                kbd.right.status = true;
                sendEvent(false, kbd.right.code);
                break;
            case 'W':
                kbd.left.status = true;
                sendEvent(false, kbd.left.code);
                break;
            case 'SE':
            case 'SW':
            case 'S':
                kbd.down.status = true;
                sendEvent(false, kbd.down.code);
                break;
            case 'C':
                disableActive();
                break;
        }
    });
    currentControlElement = "joystick";
}

function create_switch_button() {
    const newDiv = document.createElement("div");
    newDiv.className = "switch-button";
    newDiv.id = "switch";

    document.body.appendChild(newDiv);

    newDiv.addEventListener("pointerdown", (event) => {
        if (document.getElementById("joyDiv") === null) {
            document.getElementById("dpad-div").remove();
            create_joystick();
        } else {
            document.getElementById("joyDiv").remove();
            create_dpad_buttons();
            setupDpad();
        }
    });
}

function create_show_button() {
    const newDiv = document.createElement("div");
    newDiv.className = "show-gamepad-button";
    newDiv.id = "show-gamepad";

    document.body.appendChild(newDiv);

    newDiv.addEventListener("pointerdown", (event) => {
        event.stopImmediatePropagation();
        event.preventDefault();
        var DivBMain = document.getElementById("gamepad-div");
        var DivB_LB = document.getElementById("buttonW");
        var DivB_RB = document.getElementById("buttonQ");
        var DivDMain = document.getElementById("dpad-div");
        var DivJoy = document.getElementById("joyDiv");
        var ShowB = document.getElementById("switch");

        if (DivBMain !== null) {
            DivBMain.remove();
            DivB_LB.remove();
            DivB_RB.remove();
            ShowB.remove();
            switch (currentControlElement) {
                case "dpad":
                    DivDMain.remove();
                    break;
                case "joystick":
                    DivJoy.remove();
                    break;
            }
        } else {
            create_control_buttons();
            switch (currentControlElement) {
                case "dpad":
                    create_dpad_buttons();
                    setupDpad();
                    break;
                case "joystick":
                    create_joystick();
                    break;
            }
            setupButtons();
            create_switch_button();
        }
    });
}

var currentControlElement = null;

const keys = [
    { key: 'Z', keyCode: 90 },
    { key: 'X', keyCode: 88 },
    { key: 'Shift', keyCode: 16 },
    { key: 'A', keyCode: 65 },

    { key: 'Q', keyCode: 81 },
    { key: 'W', keyCode: 87 }
];

const dpadkeys = [
    { key: "Left", keyCode: 37 },
    { key: "Up", keyCode: 38 },
    { key: "Right", keyCode: 39 },
    { key: "Down", keyCode: 40 }
];

const joyStates = {
    left: { status: false, code: 37 },
    right: { status: false, code: 39 },

    up: { status: false, code: 38 },
    down: { status: false, code: 40 }
};

function createButton(key, keyCode) {
    return { key: key, keyCode: keyCode };
}

function sendEvent(isUp, keycode) {
    document.getElementById("GameCanvas").focus();
    document.dispatchEvent(new KeyboardEvent(isUp ? 'keyup' : 'keydown', { 'key': '', keyCode: keycode }))
}

function disableActive() {
    for (const kbdKey in joyStates) {
        const kbd = joyStates[kbdKey];
        if (kbd.status) {
            sendEvent(true, kbd.code);
            kbd.status = false;
        }
    }
}

function setupButtons() {
    for (const key of keys) {
        const elementId = key.id === undefined ? `button${key.key}` : key.id;
        console.log(`Setting up the ${elementId} key...`); //Remove in release
        setupKey(elementId, key.key, key.keyCode);
    }
}

function setupDpad() {
    for (const key of dpadkeys) {
        const elementId = key.id === undefined ? `button${key.key}` : key.id;
        console.log(`Setting up the ${elementId} key...`); //Remove in release
        setupKey(elementId, key.key, key.keyCode);
    }
}

function setupKey(id, key, keyCode) {
    const element = document.getElementById(id);
    element.addEventListener("pointerdown", (event) => {
        console.log(`Pointer down for ${id}`); //Remove in release
        event.stopImmediatePropagation();
        event.preventDefault();
        sendEvent(false, keyCode);
    });

    element.addEventListener("pointerup", () => {
        sendEvent(true, keyCode);
    });
}

window.addEventListener('load', () => {
    create_fps_button(); // Remove in release 
    if (navigator.getGamepads().length == 0) {
        create_control_buttons();
        create_dpad_buttons();
        create_show_button();
        create_switch_button();
        setupButtons();
        setupDpad();
    }
});

window.addEventListener('gamepadconnected', () => {
    var DivBMain = document.getElementById("gamepad-div");
    var DivB_LB = document.getElementById("buttonW");
    var DivB_RB = document.getElementById("buttonQ");
    var DivDMain = document.getElementById("dpad-div");
    var DivJoy = document.getElementById("joyDiv");
    var ShowB = document.getElementById("switch");

    if (DivBMain !== null) {
        DivBMain.remove();
        DivB_LB.remove();
        DivB_RB.remove();
        ShowB.remove();
        switch (currentControlElement) {
            case "dpad":
                DivDMain.remove();
                break;
            case "joystick":
                DivJoy.remove();
                break;
        }
    }
});