/**
 * Klasse zur Verwaltung und Steuerung eines vollstaendigen Whiteboards.
 * Dem Whiteboard koennen eine Start- und diverse weitere "Inhalts"-Tafeln hinzugefügt werden.
 * Ueber die Klasse werden zudem das Speichern und Laden des Zustands gesteuert.
 *
 * 1.2.0    2023-08-11  Markus Ehring
 *          -Feature #Anker in URL/href-Link koennen jetzt auf eine bestimmte Tafel zeigen
 * 1.1.1    2023-08-03  Markus Ehring
 *          -BugFix Querformatwarnung haelt nicht mehr das Laden der Whiteboards an
 */

var homeBoard;
var boards = [new Board()];
var activeBoard = 0;
var version;
var title;
var drawing = false;
var canvas_color = "rgb(0,0,0)";
var canvas_lineWidth = 1;
var canvas_globalCompositeOperation = "source-over";
var canvas_mode = "pen";
var json_id_counter = 0;
var boardListTitles = false;

var canvasResolutionX = 2000;
var canvasResolutionY = 1000;

// New event listener:
window.addEventListener("load", function () {
    setTimeout(function () {
        // Hide the address bar:
        window.scrollTo(0, 1);
    }, 0);

    // check if landscape or portrait
    if (window.innerHeight > window.innerWidth) {
        // portrait
        alert("Bitte drehen Sie das Gerät in die Queransicht!");
    }
});

/**
 * Generiert eine neue eindeutige ID
 * JSON ID's werden benoetigt um die Objekte eindeutig für den Import/Export zu identifizieren
 * @returns {int} Die neue ID
 */
function newJsonId() {
    json_id_counter += 1;
    return json_id_counter;
}

/**
 * Helper Funktion
 * Macht ein jquery-Element unmarkierbar und unverschiebbar
 *
 * @param {jquery-selector} rSelector Das jquery Element
 */
function makeUnselectable(rSelector) {
    $(rSelector)
        .addClass("unselectable") // All these attributes are inheritable
        .attr("unselectable", "on") // For IE9 - This property is not inherited, needs to be placed onto everything
        .attr("draggable", "false") // For moz and webkit, although Firefox 16 ignores this when -moz-user-select: none; is set, it's like these properties are mutually exclusive, seems to be a bug.
        .on("dragstart", function () {
            return false;
        }); // Needed since Firefox 16 seems to ingore the 'draggable' attribute we just applied above when '-moz-user-select: none' is applied to the CSS
    $(rSelector) // Apply non-inheritable properties to the child elements
        .find("*")
        .attr("draggable", "false")
        .attr("unselectable", "on");
}

/**
 * Init Funktion des Whiteboards
 *
 * @param {string} title Titel des Whiteboards
 * @param {string} version Version des Whiteboards
 */
function create(title, version) {
    this.title = title;
    this.version = version;

    // resize event
    $(window).on("resize", function () {
        for (let i = 0; i < boards.length; i++) {
            boards[i].resize();
        }
        // console.log("resize");
        listScroll(0);
    });
    for (let i = 0; i < boards.length; i++) {
        boards[i].resize();
    }

    // trigget resize event after 1 second
    setTimeout(function () {
        $(window).trigger("resize");
    }, 1000);
    setTimeout(function () {
        $(window).trigger("resize");
    }, 5000);

    // hide info panel
    $("#info_panel").hide();

    var canvasButtons = $('<ul id="canvasButtons" class="buttonList"></ul>').appendTo(".buttons");
    $(canvasButtons).hide();

    var hide = $(`<button class="btn_bottom" type="button" id="btn_hide"><img src="./src/icons/TB_Hide_W.svg"></button>`).appendTo(canvasButtons);
    $(hide).click(function (e) {
        $(boards[activeBoard].rCanvas).hide();
        boards[activeBoard].pCanvasVisible = false;
        toggleDrawing();
    });

    var clear = $(`<button class="btn_bottom" type="button" id="btn_clear"><img src="./src/icons/TB_Clear_W.svg"></button>`).appendTo(canvasButtons);
    $(clear).click(function (e) {
        boards[activeBoard].rCtx.clearRect(0, 0, canvasResolutionX, canvasResolutionY);
    });

    var duenn = $(`<button class="btn_bottom" type="button" id="btn_duenn"><img src="./src/icons/TB_Bleistift_W.svg"></button>`).appendTo(canvasButtons);
    $(duenn).click(function (e) {
        canvas_lineWidth = 1;
        canvas_mode = "pen";
    });

    var dick = $(`<button class="btn_bottom" type="button" id="btn_dick"><img src="./src/icons/TB_Pinsel_W.svg"></button>`).appendTo(canvasButtons);
    $(dick).click(function (e) {
        canvas_lineWidth = 10;
        canvas_mode = "pen";
    });

    var eraser = $(`<button class="btn_bottom" type="button" id="btn_eraser"><img src="./src/icons/TB_Radierer_W.svg"></button>`).appendTo(canvasButtons);
    $(eraser).click(function (e) {
        canvas_mode = "erase";
    });

    var black = $(`<button class="btn_bottom" type="button" id="btn_black"></button>`).appendTo(canvasButtons);
    $(black).append('<div class="square" style="background-color:black"></div>');
    $(black).click(function (e) {
        canvas_color = "rgb(0,0,0)";
        canvas_mode = "pen";
    });

    var rot = $(`<button class="btn_bottom" type="button" id="btn_rot"></button>`).appendTo(canvasButtons);
    $(rot).append('<div class="square" style="background-color:red"></div>');
    $(rot).click(function (e) {
        canvas_color = "rgb(255,0,0)";
        canvas_mode = "pen";
    });

    var blau = $(`<button class="btn_bottom" type="button" id="btn_blau"></button>`).appendTo(canvasButtons);
    $(blau).append('<div class="square" style="background-color:blue"></div>');
    $(blau).click(function (e) {
        canvas_color = "rgb(0,0,255)";
        canvas_mode = "pen";
    });

    var yellow = $(`<button class="btn_bottom" type="button" id="btn_blau"></button>`).appendTo(canvasButtons);
    $(yellow).append('<div class="square" style="background-color:yellow"></div>');
    $(yellow).click(function (e) {
        canvas_color = "rgb(255,255,0)";
        canvas_mode = "pen";
    });
    var green = $(`<button class="btn_bottom" type="button" id="btn_blau"></button>`).appendTo(canvasButtons);
    $(green).append('<div class="square" style="background-color:green"></div>');
    $(green).click(function (e) {
        canvas_color = "rgb(0,255,0)";
        canvas_mode = "pen";
    });

    // make tool buttons unselectable and hover color
    $(canvasButtons)
        .find(".btn_bottom")
        .each(function (i) {
            makeUnselectable(this);
            // $(this).hover(
            //     function () {
            //         $(this).css("background-color", "rgb(242, 107, 15)");
            //     },
            //     function () {
            //         $(this).css("background-color", "rgb(51, 51, 51)");
            //     }
            // );
        });

    // info panel code
    $(document).ready(function () {
        $("#btn_info").click(function () {
            if ($("#info_panel").is(":visible")) {
                $("#info_panel").hide();
            } else {
                $("#info_panel").show();
                $("#info_panel_page").stop();
                $("#info_panel_page").animate(
                    {
                        scrollTop: Math.round($("#info_panel_page").scrollTop() + $(boards[activeBoard].rInfo).position().top),
                    },
                    1000
                );
            }
        });

        $("#info_panel_exit").click(function () {
            $("#info_panel").hide();
        });
    });

    // board navigation buttons
    $("#btn_prevBoard").click(function () {
        setActiveBoard(Math.max(0, activeBoard - 1));
    });
    $("#btn_nextBoard").click(function () {
        setActiveBoard(Math.min(boards.length - 1, activeBoard + 1));
    });

    $("#btn_toggleDrawing_disable").hide();

    // show/hide list scroll buttons
    var checkOverflow = function () {
        var overflow = $(".boardsList")[0].offsetHeight < $(".boardsList")[0].scrollHeight;
        if (overflow) {
            $("#btn_listUp").show();
            $("#btn_listDown").show();
        } else {
            $("#btn_listUp").hide();
            $("#btn_listDown").hide();
        }
    };

    // board list scroll mit mausrad
    $(".boardsList").on("wheel", function (event) {
        if (event.originalEvent.deltaY > 0) {
            listScrollDown();
        } else {
            listScrollUp();
        }
    });

    checkOverflow();
    $(window).resize(checkOverflow);
}

/**
 * Setzt die sichtbare Tafel
 *
 * @param {int} activeBoard
 */
function setActiveBoard(activeBoard) {
    if (activeBoard < boards.length) {
        if (boardListTitles) setBoardListTitles(false);
        this.activeBoard = activeBoard;

        // Anker in URL aendern
        $(location).attr("hash", activeBoard);

        // alle Tafeln ausblenden. Aktive Tafel einblenden
        for (let i = 0; i < boards.length; i++) {
            if (activeBoard == i) {
                $(boards[i].rDiv).show();
                $(boards[i].rButtons).show();
            } else {
                $(boards[i].rDiv).hide();
                $(boards[i].rButtons).hide();
            }
        }

        // show / hide global elements (e.g. InfoSlier)
        $(".globalElement").each(function () {
            if ($(this).attr("board_id") == "board_" + activeBoard) {
                $(this).show();
            } else {
                $(this).hide();
            }
        });

        for (let i = 0; i < boards.length; i++) {
            if (activeBoard == i) {
                //boards[i].resize();
                $("head title", window.parent.document).text(boards[i].pTitle);
                $("#boardTitle").text(boards[i].pTitle);
                $(".listButton").each(function (i) {
                    $(this).css("background-color", "white");
                    $(this).css("color", "black");
                });
                $("#btn_home").css("background-color", "white");
                $("#btn_home_icon_W").hide();
                $("#btn_home_icon_BL").show();
                if (i != 0) {
                    $("#listButton_" + i).css("background-color", "black");
                    $("#listButton_" + i).css("color", "white");
                } else {
                    $("#btn_home").css("background-color", "black");
                    $("#btn_home_icon_BL").hide();
                    $("#btn_home_icon_W").show();
                }
            }
            boards[i].pIsMouseDown = false;
        }
        if (drawing) {
            toggleDrawing();
        }

        if (activeBoard == 0) {
            $("#contentFrame").addClass("homepage");
            $("#contentFrame").removeClass("content");
            $("#boardTitle_1_home").show();
            $("#boardTitle_2_home").show();
            $("#boardTitle_1_home").text("TAFELBILD");
            $("#boardTitle_2_home").text(title);
            $("#boardTitle_1_board").hide();
            $("#boardTitle_2_board").hide();
            $("#boardTitle_2_board_background").hide();

            $("#info_panel_page").stop();
            $("#info_panel_page").animate(
                {
                    scrollTop: 0,
                },
                1000
            );
            $("#btn_info").css("top", "11vh");
        } else {
            $("#contentFrame").removeClass("homepage");
            $("#contentFrame").addClass("content");

            $("#boardTitle_1_board").show();
            $("#boardTitle_2_board").show();
            $("#boardTitle_1_board").text(title);
            $("#boardTitle_2_board").text(boards[activeBoard].pTitle);

            $("#boardTitle_1_home").hide();
            $("#boardTitle_2_home").hide();

            // title 2 background element color
            $("#boardTitle_2_board_background").show();
            $("#boardTitle_2_board_background").css("background-color", $("#contentFrame").css("background-color"));

            $("#info_panel_page").stop();
            if (boards[activeBoard].rInfo != null) {
                $("#info_panel_page").animate(
                    {
                        scrollTop: Math.round($("#info_panel_page").scrollTop() + $(boards[activeBoard].rInfo).position().top),
                    },
                    1000
                );
            }
            $("#btn_info").css("top", "4vh");
        }

        for (let i = 0; i < 10; i++) {
            boards[activeBoard].resize();
        }

        // pause all videos
        $("video").each(function () {
            this.pause();
        });
    } else {
        setActiveBoard(0);
    }
}

/**
 * Setzt ein neues board
 *
 * @param pIndex {Int} Index des neuen Boards
 * @param rBoard {Board} Die Startseitentafel
 * @param pAddButton {Boolean} Option um einen Button für das Board in die Liste hinzuzufügen
 */
function setBoard(pIndex, rBoard, pAddButton) {
    // add javascript representation
    boards[pIndex] = rBoard;
    boards[pIndex].pId = pIndex;
    boards[pIndex].pBoardId = pIndex;
    //console.log("board id: " + i);

    // add button in list
    if (pAddButton) {
        $(".boardsList").append('<li><button id="listButton_' + pIndex + '"class="listButton shadow" type="button" index="' + pIndex + '" onclick="setActiveBoard(' + pIndex + ')">' + pIndex + "</button></li>");
    }

    // hover color
    $("#listButton_" + pIndex).hover(
        function () {
            $(this).css("background-color", "var(--hoverColor)");
            if (!boardListTitles) {
                //$(".boardsList").css("width", "1000%");
                // var width = $("#listButton_" + pIndex).width();
                $("#listButton_" + pIndex).text(parseInt($(this).attr("index")) + " " + boards[parseInt($(this).attr("index"))].pTitle);
                // $("#listButton_" + pIndex).width($("#listButton_" + pIndex).width() + $("#listButton_" + pIndex).width() - width);
                $("#listButton_" + pIndex).css("width", "auto");
                $("#listButton_" + pIndex).css("padding", "0 1vw 0 1vw");
            }
        },
        function () {
            if (activeBoard == pIndex) {
                $(this).css("background-color", "black");
            } else {
                $(this).css("background-color", "white");
            }
            if (!boardListTitles) {
                // $("#listButton_" + pIndex).css("min-width", "3vw");
                //$(".boardsList").css("width", "100%");
                $("#listButton_" + pIndex).text(parseInt($(this).attr("index")));
                $(".listButton").css("width", "3vw");
                $("#listButton_" + pIndex).css("padding", "0 0 0 0");
            }
        }
    );

    // add content elements
    $("#contentFrame").append('<div class="board" id="board_' + pIndex + '"></div>');
    boards[pIndex].rDiv = $("#board_" + pIndex);
    boards[pIndex].rDiv.append('<canvas class="canvas" id="canvas_' + pIndex + '" width="' + canvasResolutionX + '" height="' + canvasResolutionY + '"></canvas> ');
    boards[pIndex].rCanvas = $("#canvas_" + pIndex);
    boards[pIndex].rCanvas.on("mousedown", function (e) {
        // console.log("mousedown");
        if (drawing && activeBoard == pIndex) {
            boards[pIndex].pIsMouseDown = true;
            var offset = boards[pIndex].rCanvas.offset();
            var posY = offset.top - $(window).scrollTop() * 0;
            var posX = offset.left - $(window).scrollLeft() * 0;
            if (canvas_mode == "pen") {
                boards[pIndex].rCtx.strokeStyle = canvas_color;
                boards[pIndex].rCtx.lineWidth = canvas_lineWidth;
                boards[pIndex].rCtx.beginPath();
                boards[pIndex].rCtx.moveTo(((e.pageX - posX) * canvasResolutionX) / parseFloat($("#canvas_" + pIndex).css("width")), ((e.pageY - posY) * canvasResolutionY) / parseFloat($("#canvas_" + pIndex).css("height")));
            } else if (canvas_mode == "erase") {
                var w = 50;
                var h = 50;
                boards[pIndex].rCtx.clearRect(((e.pageX - posX) * canvasResolutionX) / parseFloat($("#canvas_" + pIndex).css("width")) - w / 2, ((e.pageY - posY) * canvasResolutionY) / parseFloat($("#canvas_" + pIndex).css("height")) - h / 2, w, h);
            }
        }
    });
    // touch event weiterleitung
    boards[pIndex].rCanvas.on("touchstart", function (e) {
        e.preventDefault();
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        e.pageX = touch.pageX;
        e.pageY = touch.pageY;

        // boards[pIndex].rCanvas.mousedown(e);
        // trigger mousedown event of boards[pIndex].rCanvas
        e2 = new MouseEvent("mousedown", {
            bubbles: true,
            cancelable: true,
            clientX: e.pageX,
            clientY: e.pageY,
            pageX: e.pageX,
            pageY: e.pageY,
        });
        boards[pIndex].rCanvas[0].dispatchEvent(e2);
    });
    boards[pIndex].rCanvas.on("mouseup", function (e) {
        // console.log("mouseup");
        if (drawing && activeBoard == pIndex) {
            boards[pIndex].pIsMouseDown = false;
            var offset = boards[pIndex].rCanvas.offset();
            var posY = offset.top - $(window).scrollTop() * 0;
            var posX = offset.left - $(window).scrollLeft() * 0;
            if (canvas_mode == "pen") {
            }
        }
    });
    // touch event weiterleitung
    boards[pIndex].rCanvas.on("touchend", function (e) {
        e.preventDefault();
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        e.pageX = touch.pageX;
        e.pageY = touch.pageY;
        e2 = new MouseEvent("mouseup", {
            bubbles: true,
            cancelable: true,
            clientX: e.pageX,
            clientY: e.pageY,
            pageX: e.pageX,
            pageY: e.pageY,
        });
        boards[pIndex].rCanvas[0].dispatchEvent(e2);
    });

    boards[pIndex].rCanvas.on("mousemove", function (e) {
        if (drawing && activeBoard == pIndex && boards[pIndex].pIsMouseDown) {
            var offset = boards[pIndex].rCanvas.offset();
            var posY = offset.top - $(window).scrollTop() * 0;
            var posX = offset.left - $(window).scrollLeft() * 0;
            if (canvas_mode == "pen") {
                boards[pIndex].rCtx.strokeStyle = canvas_color;
                boards[pIndex].rCtx.lineWidth = canvas_lineWidth;
                boards[pIndex].rCtx.lineTo(((e.pageX - posX) * canvasResolutionX) / parseFloat($("#canvas_" + pIndex).css("width")), ((e.pageY - posY) * canvasResolutionY) / parseFloat($("#canvas_" + pIndex).css("height")));
                boards[pIndex].rCtx.stroke();
            } else if (canvas_mode == "erase") {
                var w = 50;
                var h = 50;
                boards[pIndex].rCtx.clearRect(((e.pageX - posX) * canvasResolutionX) / parseFloat($("#canvas_" + pIndex).css("width")) - w / 2, ((e.pageY - posY) * canvasResolutionY) / parseFloat($("#canvas_" + pIndex).css("height")) - h / 2, w, h);
            }
        }
    });
    // touch event weiterleitung
    boards[pIndex].rCanvas.on("touchmove", function (e) {
        e.preventDefault();
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        e.pageX = touch.pageX;
        e.pageY = touch.pageY;
        // console.log("touchmove", e.pageX, e.pageY);
        e2 = new MouseEvent("mousemove", {
            bubbles: true,
            cancelable: true,
            clientX: e.pageX,
            clientY: e.pageY,
            pageX: e.pageX,
            pageY: e.pageY,
        });
        boards[pIndex].rCanvas[0].dispatchEvent(e2);
    });

    boards[pIndex].rCanvas.on("mouseout", function (e) {
        if (drawing && activeBoard == pIndex) {
            boards[pIndex].pIsMouseDown = false;
        }
    });
    boards[pIndex].rCtx = $("#canvas_" + pIndex)[0].getContext("2d");

    // flex flow
    if (boards[pIndex].pAnordnung == "zeilenweise") {
        $(boards[pIndex].rDiv).css("flex-flow", "row wrap");
    } else if (boards[pIndex].pAnordnung == "spaltenweise") {
        $(boards[pIndex].rDiv).css("flex-flow", "column wrap");
    }

    // add individual buttons for board
    /*
	<button class="btn_bottom" type="button" id="btn_reset" onclick="reset()">RESET</button>
	<button class="btn_bottom" type="button" id="btn_solve" onclick="solve()">SOLVE</button>
	<button class="btn_bottom" type="button" id="btn_toggleDrawing" onclick="toggleDrawing()">ENABLE DRAWING</button>
	*/
    boards[pIndex].rButtons = $('<ul id="buttonList_' + pIndex + '" class="buttonList"></ul>').appendTo(".buttons");
    boards[pIndex].rSolveBtn = $(`<button class="btn_bottom shadow" type="button" id="btn_solve_${pIndex}" title="Lösen"></button>`).appendTo(boards[pIndex].rButtons);
    boards[pIndex].rSolveBtn.click(function (e) {
        boards[pIndex].solve();
    });
    boards[pIndex].rSolveBtn.hide();

    boards[pIndex].rResetBtn = $(`<button class="btn_bottom shadow" type="button" id="btn_reset_${pIndex}" title="Zurücksetzen"></button>`).appendTo(boards[pIndex].rButtons);
    boards[pIndex].rResetBtn.click(function (e) {
        boards[pIndex].reset();
    });
    if (!boards[pIndex].pForceResetBtn) {
        boards[pIndex].rResetBtn.hide();
    }
    //$("#buttons").append('<li><button id="listButton_' + i + '"class="listButton" type="button" onclick="setActiveBoard(' + (i) + ')">' + (i + 1) + '</button></li>')

    // Solve/Reset button icons
    boards[pIndex].rSolveBtn.css("background-image", 'url("src/icons/TB_Loesen(allgemein)_BL.svg")');
    boards[pIndex].rResetBtn.css("background-image", 'url("src/icons/TB_Zuruecksetzen(allgemein)_BL.svg")');

    // trigger resize für boardList overflow für ein/ausblenden scroll buttons
    $(window).resize();
    return boards[pIndex];
}

/**
 * Setzt die Startseite
 *
 * @param rBoard {Board} Die Startseitentafel
 */
function setHome(rBoard) {
    return setBoard(0, rBoard, false);
}

/**
 * Fuegt eine neue Tafel hinzu
 *
 * @param rBoard {Board} Die neue Tafel
 */
function addBoard(rBoard) {
    // add javascript representation
    boards.push(rBoard);
    return setBoard(boards.length - 1, rBoard, true);
}

/**
 * Schaltet die Zeichenfunktion ein oder aus
 */
function toggleDrawing() {
    // console.log("TOOGLE");
    drawing = !drawing;
    if (drawing) {
        $(boards[activeBoard].rCanvas).show();
        boards[activeBoard].pCanvasVisible = true;
        $("#btn_toggleDrawing_enable").hide();
        $("#btn_toggleDrawing_disable").show();
        $(".canvas").each(function (i) {
            boards[i].rCanvas.css("pointer-events", "all");
            $(boards[i].rCanvas).appendTo(boards[i].rDiv);
        });
        $("#canvasButtons").show();
        $(boards[activeBoard].rButtons).hide();

        // hide navigation buttons
        $("#btn_prevBoard").hide();
        $("#btn_nextBoard").hide();
    } else {
        $("#btn_toggleDrawing_enable").show();
        $("#btn_toggleDrawing_disable").hide();
        $(".board").each(function (i) {
            boards[i].rCanvas.css("pointer-events", "none");
        });
        $("#canvasButtons").hide();
        $(boards[activeBoard].rButtons).show();

        // show navigation buttons
        $("#btn_prevBoard").show();
        $("#btn_nextBoard").show();
    }
}

/**
 * Startet den Downloadprozess
 */
function download() {
    try {
        var isFileSaverSupported = !!new Blob();
        if (isFileSaverSupported) {
            var blob = new Blob([createJSON()], {
                type: "text/plain;charset=utf-8",
            });

            //var text = document.querySelector("#" + $(boards[activeBoard].rCanvas).attr("id")).toDataURL(1)
            //var blob = new Blob([text], {type: "text/plain;charset=utf-8"});

            var currentdate = new Date();
            var datetime = currentdate.getFullYear() + "-" + (currentdate.getMonth() + 1) + "-" + currentdate.getDate() + " " + currentdate.getHours() + "-" + currentdate.getMinutes();
            saveAs(blob, "Whiteboard " + datetime + ".json");
        } else {
            alert("Downloading not supported");
        }
    } catch (e) {
        console.log("ERROR WITH FileSaver.js");
    }
}

/**
 * Startet den Hochladeprozess
 */
function upload() {
    let files = $("#btn_browse").prop("files");

    if (files.length == 0) return;

    const file = files[0];

    let reader = new FileReader();

    reader.onload = (e) => {
        const file = e.target.result;
        //console.log(file);
        parseJSON(file);
        /*
		var img = new Image;
		img.onload = function() {
			var canvas = document.querySelector("#" + $(boards[activeBoard].rCanvas).attr("id"));
			var ctx = canvas.getContext('2d');
			ctx.clearRect(0,0,canvas.width, canvas.height);
			ctx.drawImage(img,0,0);
		};
		img.src = file;
		*/
    };

    reader.readAsText(file);
}

/**
 * Setzt die aktive Tafel in den Ausgangszustand zurück
 */
function reset() {
    boards[activeBoard].reset();
}

/**
 * Löst alle interaktiven Elemente auf
 */
function solve() {
    boards[activeBoard].solve();
}

/**
 * Gibt an ob alle Elemente der aktiven Tafel korrekt gelöst sind
 *
 * @return {Bool}
 */
function isSolved() {
    return boards[activeBoard].isSolved();
}

/**
 * Generiert die JSON-Datei für den download
 * @return {String} JSON-Datei
 */
function createJSON() {
    var whiteboard = {
        boards: [],
        activeBoard: activeBoard,
        version: version,
        title: title,
    };

    for (let i = 0; i < boards.length; i++) {
        whiteboard.boards.push(boards[i].export());
    }

    return JSON.stringify(whiteboard);
}

/**
 * Liest die JSON-Datei beim Upload
 *
 * @param rJson {String} JSON Datei
 */
function parseJSON(rJson) {
    var whiteboard = JSON.parse(rJson);

    if (whiteboard.version != version) {
        alert("Die ausgewählte Datei hat eine andere Version!");
    }

    if (whiteboard.title != title) {
        alert("Die ausgewählte Datei hat einen anderen Titel!");
    }

    for (let i = 0; i < whiteboard.boards.length; i++) {
        var board = whiteboard.boards[i];
        boards[i].import(board);
    }

    setActiveBoard(whiteboard.activeBoard);
}

/**
 * Scrollt die Liste der Tafeln nach oben
 */
function listScrollUp() {
    listScroll(-1);
}

/**
 * Scrollt die liste der Tafeln nach unten
 *
 * @param {int} pOffset - Offset um den gescrollt werden soll
 */
function listScrollDown() {
    listScroll(1);
}

var listScrollIndex = 1;

function listScroll(pOffset) {
    if (pOffset == 0) return;
    var top1 = parseFloat($("#listButton_" + 1).position().top);
    var top2 = parseFloat($("#listButton_" + 2).position().top);
    var delta = Math.abs(top1 - top2);

    var scrollTop = parseFloat($(".boardsList").scrollTop());
    var newScrollTop = scrollTop + delta * pOffset;
    $(".boardsList").scrollTop(newScrollTop);
}

/**
 * Toggle Anzeige der Tafelnamen in der Tafelliste
 */
function toggleBoardTitles() {
    setBoardListTitles(!boardListTitles);
}

/**
 * Setzt die Anzeige der Tafelnamen in der Tafelliste
 *
 * @param {boolean} pExpand - true wenn die Tafelnamen angezeigt werden sollen
 */
function setBoardListTitles(pExpand) {
    boardListTitles = pExpand;
    if (boardListTitles) {
        $("#btn_hamburger_icon_BL").hide();
        $("#btn_hamburger_icon_W").show();
        $(".listButton").each(function (i) {
            var width = $(this).width();
            $(this).text(parseInt($(this).attr("index")) + " " + boards[parseInt($(this).attr("index"))].pTitle);
            $(this).css("width", "auto");
            $(this).css("text-align", "center");
            $(this).css("padding", "0 1vw 0 1vw");
        });
    } else {
        $("#btn_hamburger_icon_W").hide();
        $("#btn_hamburger_icon_BL").show();
        $(".listButton").each(function (i) {
            $(this).text($(this).attr("index"));
            $(this).css("text-align", "center");
            $(this).css("width", "3vw");
            $(this).css("padding", "0 0 0 0");
        });
        $(".listButton").css("width", "3vw");
    }
}

/**
 * Debug Funktion
 * Setzt die Hintergrundfarbe aller Boxen
 *
 * @param {CSS Color} pColor
 */
function setBoxesBackground(pColor) {
    $(".box").css("background-color", pColor);
}

function endLoad() {
    $(window).resize();

    var checkHash = function () {
        // Tafel aus anchor URL laden (url#1) => Tafel 1
        var hash = $(location).attr("hash").substring(1);
        if (!isNaN(hash)) {
            var number = Number(hash);
            if (Number.isInteger(number) && hash == String(number)) {
                setActiveBoard(number);
            } else {
                setActiveBoard(0);
            }
        } else {
            setActiveBoard(0);
        }
    };
    checkHash();

    // Anker Aenderung Event
    window.addEventListener("hashchange", function () {
        checkHash();
    });
}
