"use strict";

/**
 * @author nuark (github: NuarkNoir, tg: nuark)
 */

/** @type {HTMLElement} */
let drawCommandsElement = null;

/** @type {HTMLElement} */
let errorHolderElement = null;

/** @type {HTMLElement} */
let canvasElement = null;

/** @type {Nanvas} */
let nanvas = null;

/**
 * Drawing loop
 */
const drawingLoop = function () {
    nanvas.clear();
    nanvas.grid();
    try {
        nanvas.drawStatic();
        nanvas.updateDynamics();
    } catch (e) {
        console.error(e.stack);
        errorHolderElement.textContent = `[Error] ${e.message}`;
    }

    requestAnimationFrame(drawingLoop);
}

/**
 * Checks for correct input in commands textarea
 * @returns {Error}
 */
const processInput = function () {
    try {
        const commands = JSON.parse(drawCommandsElement.value);
        nanvas.pushCommands(commands);
    } catch (e) { return e; }
    return null;
}

/**
 * Handles command input changes
 */
const onCommandsEdited = function () {
    errorHolderElement.textContent = "";
    const errored = processInput();
    if (errored !== null) {
        errorHolderElement.textContent = `[Error] ${errored.message}`;
        nanvas.clearCommands();
    }
}

/**
 * Returns position of cursor on canvas
 * @param {HTMLElement} canvas 
 * @param {Event} event 
 * @returns {Array.<Number, Number>} Position `x` and `y` in array
 */
const getCursorPosition = function (canvas, event) {
    const rect = canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    return [x, y];
}

/**
 * Spawns dynamic object on canvas
 * @param {Number} x Position of dynamic on x
 * @param {Number} y Position of dynamic on y
 */
const spawnDynamic = function (x, y) {
    const emitter = new ParticleEmmiter(
        ~~x, ~~y, 
        -1 + Math.random() * 2, -1 + Math.random() * 2
    );
    nanvas.addDynamic(emitter);
}

/**
 * Init function
 */
const init = function () {
    drawCommandsElement = document.getElementById("drawCommands");
    errorHolderElement = document.getElementById("errorHolder");
    canvasElement = document.getElementById("canvas");

    drawCommandsElement.addEventListener("input", onCommandsEdited);

    canvasElement.addEventListener("mousedown", function (e) {
        const [x, y] = getCursorPosition(canvasElement, e)
        spawnDynamic(x, y);
    });
    canvasElement.height = canvasElement.clientHeight;
    canvasElement.width = canvasElement.clientWidth;
    nanvas = Nanvas.mount(canvasElement);
    nanvas.pushCommands([
        ["circle", 50, 50, 10],
        ["square", 150, 50, 25],
        ["ellipse", 200, 200, 30, 40],
        ["bezier", 50, 100, 180, 10, 20, 10]
    ]);
    requestAnimationFrame(drawingLoop);
}

/**
 * Subscribbes `init()` for DOMContentLoaded
 */
document.addEventListener("DOMContentLoaded", init);
