/*
    Touch gesture
*/

// Virtual Gamepad / Joystick
// Ref: https://jsfiddle.net/aa0et7tr/5/


/*
    Left panel - Dpad
*/
const MAX_DIFF = 20; // radius of circle boundary

// vpad state, use for mouse button down
let vpadState = {
    up: false,
    down: false,
    left: false,
    right: false,
};
$(".btn, .btn-big").each(function () {
    vpadState[$(this).attr("value")] = false;
});

let vpadTouchIdx = null;
let vpadTouchDrag = null;
let vpadHolder = $("#circle-pad-holder");
let vpadCircle = $("#circle-pad");


function resetVpadState() {
    // trigger up event?
    checkVpadState("up", false);
    checkVpadState("down", false);
    checkVpadState("left", false);
    checkVpadState("right", false);

    vpadTouchDrag = null;
    vpadTouchIdx = null;
    $(".dpad").removeClass("pressed");
}


function checkVpadState(axis, state) {
    if (state !== vpadState[axis]) {
        vpadState[axis] = state;

        if (state) {
            doButtonDown(axis);
        } else {
            doButtonUp(axis);
        }
    }
}


function handleVpadJoystickDown(event) {
    vpadCircle.css("transition", "0s");
    vpadCircle.css("-moz-transition", "0s");
    vpadCircle.css("-webkit-transition", "0s");
    if (event.changedTouches) {
        resetVpadState();

        vpadTouchIdx = event.changedTouches[0].identifier;
        event.clientX = event.changedTouches[0].clientX;
        event.clientY = event.changedTouches[0].clientY;
    }
    vpadTouchDrag = {
        x: event.clientX,
        y: event.clientY,
    };
}


function handleVpadJoystickUp(event) {
    if (vpadTouchDrag === null) return;

    vpadCircle.css("transition", ".2s");
    vpadCircle.css("-moz-transition", ".2s");
    vpadCircle.css("-webkit-transition", ".2s");
    vpadCircle.css("transform", "translate3d(0px, 0px, 0px)");
    vpadCircle.css("-moz-transform", "translate3d(0px, 0px, 0px)");
    vpadCircle.css("-webkit-transform", "translate3d(0px, 0px, 0px)");

    resetVpadState();
}


function handleVpadJoystickMove(event) {
    if (vpadTouchDrag === null) return;

    if (event.changedTouches) {
        // check if moving source is from other touch?
        for (var i = 0; i < event.changedTouches.length; i++) {
            if (event.changedTouches[i].identifier === vpadTouchIdx) {
                event.clientX = event.changedTouches[i].clientX;
                event.clientY = event.changedTouches[i].clientY;
            }
        }
        if (event.clientX === undefined || event.clientY === undefined)
            return;
    }

    var xDiff = event.clientX - vpadTouchDrag.x;
    var yDiff = event.clientY - vpadTouchDrag.y;
    var angle = Math.atan2(yDiff, xDiff);
    var distance = Math.min(MAX_DIFF, Math.hypot(xDiff, yDiff));
    var xNew = distance * Math.cos(angle);
    var yNew = distance * Math.sin(angle);

    // check if screen is switched or not
    if (isLayoutSwitched) {
        tmp = xNew;
        xNew = yNew;
        yNew = -tmp;
    }

    style = `translate(${xNew}px, ${yNew}px)`;
    vpadCircle.css("transform", style);
    vpadCircle.css("-webkit-transform", style);
    vpadCircle.css("-moz-transform", style);

    var xRatio = xNew / MAX_DIFF;
    var yRatio = yNew / MAX_DIFF;
    checkVpadState("left", xRatio <= -0.5);
    checkVpadState("right", xRatio >= 0.5);
    checkVpadState("up", yRatio <= -0.5);
    checkVpadState("down", yRatio >= 0.5);
}



// touch/mouse events for dpad. mouseup events is binded to window.
vpadHolder.on('mousedown', handleVpadJoystickDown);
vpadHolder.on('touchstart', handleVpadJoystickDown);
vpadHolder.on('touchend', handleVpadJoystickUp);



/*
    Right side - Control buttons
*/

function handleButtonDown(event) {
    checkVpadState($(this).attr("value"), true);
    // add touchIdx?
}

function handleButtonUp(event) {
    checkVpadState($(this).attr("value"), false);
}


// touch/mouse events for control buttons. mouseup events is binded to window.
$(".btn").on("mousedown", handleButtonDown);
$(".btn").on("touchstart", handleButtonDown);
$(".btn").on("touchend", handleButtonUp);



/*
    Touch menu
*/

let menuTouchIdx = null;
let menuTouchDrag = null;
let menuTouchTime = null;

function handleMenuDown(event) {
    // Identify of touch point
    if (event.changedTouches) {
        menuTouchIdx = event.changedTouches[0].identifier;
        event.clientX = event.changedTouches[0].clientX;
        event.clientY = event.changedTouches[0].clientY;
    }

    menuTouchDrag = {
        x: event.clientX,
        y: event.clientY,
    };

    menuTouchTime = Date.now();
}

function handleMenuMove(event) {
    if (menuTouchDrag === null) return;

    if (event.changedTouches) {
        // check if moving source is from other touch?
        for (var i = 0; i < event.changedTouches.length; i++) {
            if (event.changedTouches[i].identifier === menuTouchIdx) {
                event.clientX = event.changedTouches[i].clientX;
                event.clientY = event.changedTouches[i].clientY;
            }
        }
        if (event.clientX == undefined || event.clientY == undefined)
            return;
    }

    var listbox = $("#menu-container");
    listbox.css("transition", "");
    listbox.css("-moz-transition", "");
    listbox.css("-webkit-transition", "");
    if (isLayoutSwitched) {
        listbox.css("top", `${menuTop - (-menuTouchDrag.x + event.clientX)}px`);
    } else {
        listbox.css("top", `${menuTop - (menuTouchDrag.y - event.clientY)}px`);
    }
    
}

function handleMenuUp(event) {
    if (menuTouchDrag === null) return;
    if (event.changedTouches) {
        if (event.changedTouches[0].identifier !== menuTouchIdx)
            return;
        event.clientX = event.changedTouches[0].clientX;
        event.clientY = event.changedTouches[0].clientY;
    }

    var interval = Date.now() - menuTouchTime; // 100ms?
    if (isLayoutSwitched) {
        newY = -menuTouchDrag.x + event.clientX;
    } else {
        newY = menuTouchDrag.y - event.clientY;
    }
    
    if (interval < 200) {
        // calc velo
        newY =  newY/ interval * 250;
    }
    // current item?
    menuTop -= newY;
    idx = Math.round((menuTop - MENU_TOP_POSITION) / -36);
    pickGame(idx);

    menuTouchDrag = null;
}


// Bind events for menu
$("#menu-screen").on("mousedown", handleMenuDown);
$("#menu-screen").on("touchstart", handleMenuDown);
$("#menu-screen").on("touchend", handleMenuUp);



/*
    Common events
*/

function handleWindowMove(event) {
    event.preventDefault();
    handleVpadJoystickMove(event);
    handleMenuMove(event);
    
    // moving touch
    if (event.changedTouches) {
        for (var i = 0; i < event.changedTouches.length; i++) {
            if (event.changedTouches[i].identifier !== menuTouchIdx && event.changedTouches[i].identifier !== vpadTouchIdx) {
                // check class
                
                var elem = document.elementFromPoint(event.changedTouches[i].clientX, event.changedTouches[i].clientY);
                if (elem.classList.contains("btn")) {
                    $(elem).trigger("touchstart");
                } else {
                    $(".btn").trigger("touchend");
                }
            }
        }
    }
}

function handleWindowUp(event) {
    handleVpadJoystickUp(event);
    handleMenuUp(event);
    $(".btn").trigger("touchend");
}



// Bind events for window
$(window).on("mousemove", handleWindowMove);
window.addEventListener("touchmove", handleWindowMove, {passive: false});
$(window).on("mouseup", handleWindowUp);