import { PoseLandmarker, FilesetResolver, DrawingUtils } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@0.10.0";

const demosSection = document.getElementById("demos");
let poseLandmarker = undefined;
let runningMode = "IMAGE";
let enableWebcamButton;
let enableCounter;
let webcamRunning = false;
const videoHeight = "360px";
const videoWidth = "480px";
let shoulder = [];
let elbow = [];
let wrist = [];
let hip = [];
let ankle = [];
let knee = [];
let stage;
let angle;
let counter = 0;
let starter = 0;

const createPoseLandmarker = async () => {
    const vision = await FilesetResolver.forVisionTasks("https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm");
    poseLandmarker = await PoseLandmarker.createFromOptions(vision, {
        baseOptions: {
            modelAssetPath: `https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task`,
            delegate: "GPU"
        },
        runningMode: runningMode,
        numPoses: 2
    });
    demosSection.classList.remove("invisible");
};
createPoseLandmarker();


const video = document.getElementById("webcam");
const canvasElement = document.getElementById("output_canvas");
const canvasCtx = canvasElement.getContext("2d");
const drawingUtils = new DrawingUtils(canvasCtx);


const hasGetUserMedia = () => { var _a; return !!((_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia); };

if (hasGetUserMedia()) {
    enableWebcamButton = document.getElementById("webcamButton");
    enableWebcamButton.addEventListener("click", enableCam);
}
else {
    console.warn("getUserMedia() is not supported by your browser");
}

function enableCam(event) {
    if (!poseLandmarker) {
        console.log("Wait! poseLandmaker not loaded yet.");
        return;
    }
    if (webcamRunning === true) {
        webcamRunning = false;
        enableWebcamButton.innerText = "ENABLE PREDICTIONS";
    }
    else {
        webcamRunning = true;
        enableWebcamButton.innerText = "DISABLE PREDICTIONS";
    }
    
    const constraints = {
        video: true
    };
    
    navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
        video.srcObject = stream;
        video.addEventListener("loadeddata", predictWebcam);
    });
}
let lastVideoTime = -1;
async function predictWebcam() {
    canvasElement.style.height = videoHeight;
    video.style.height = videoHeight;
    canvasElement.style.width = videoWidth;
    video.style.width = videoWidth;
    
    if (runningMode === "IMAGE") {
        runningMode = "VIDEO";
        await poseLandmarker.setOptions({ runningMode: "VIDEO" });
    }
    let startTimeMs = performance.now();
    if (lastVideoTime !== video.currentTime) {
        lastVideoTime = video.currentTime;
        poseLandmarker.detectForVideo(video, startTimeMs, (result) => {
            canvasCtx.save();
            canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
            for (const landmark of result.landmarks) {
                shoulder = [landmark[11].x, landmark[11].y]
                elbow = [landmark[13].x, landmark[13].y]
                wrist = [landmark[15].x, landmark[15].y]              
                hip = [landmark[23].x, landmark[23].y]
                knee = [landmark[25].x, landmark[25].y]
                ankle = [landmark[27].x, landmark[27].y]

                drawingUtils.drawLandmarks(landmark, {
                    radius: (data) => DrawingUtils.lerp(data.from.z, -0.15, 0.1, 5, 1)
                });
                drawingUtils.drawConnectors(landmark, PoseLandmarker.POSE_CONNECTIONS);
            }
            canvasCtx.restore();
        });
    }

    function calculateAngle(a, b, c) {
        const vecA = new Array(a[0], a[1]); // First
        const vecB = new Array(b[0], b[1]); // Mid
        const vecC = new Array(c[0], c[1]); // End
      
        const radians = Math.atan2(vecC[1] - vecB[1], vecC[0] - vecB[0]) - Math.atan2(vecA[1] - vecB[1], vecA[0] - vecB[0]);
        let angle = Math.abs(radians * (180.0 / Math.PI));
      
        if (angle > 180.0) {
          angle = 360 - angle;
        }
      
        return angle;
      }

    const startButton = document.getElementById('startButton');
    startButton.addEventListener('click', () => {
        starter = 1
    });

    const stopButton = document.getElementById('stopButton');
    stopButton.addEventListener('click', () => {
        starter = 0
    });

    const restartButton = document.getElementById('restartButton');
    restartButton.addEventListener('click', () => {
        counter = 0
    });

    if (starter == 1){
        if(document.getElementById('curl').checked) {
            angle = calculateAngle(shoulder,elbow,wrist)

            if (angle > 160){
                stage = "down"
            }
            if (angle < 30 & stage =='down'){
                stage="up"
                counter +=1
            }
          }
          if(document.getElementById('squat').checked) {
            angle = calculateAngle(hip,knee,ankle)

            if (angle > 169){
                stage = "up"
            }
            if (angle < 90 & stage =='up'){
                stage="down"
                counter +=1
            }
          }
    }

    const landmarkValuesDiv = document.getElementById('counter');
    landmarkValuesDiv.innerHTML = `stage: ${stage}, count: ${counter}`;

    
    if (webcamRunning === true) {
        window.requestAnimationFrame(predictWebcam);
    }
}