import {hamster} from "./hamster.js";
import {canvas, disableTouch, enableTouch, resetHamster} from "./canvas.js";
import {
    closeChangeSizeDialog,
    closeTerritoryTooltip,
    openAddGrainsHamsterDialog,
    openChangeSizeDialog
} from "./dialogs.js";
import {pauseCode, runCode, stopCode} from "./controls.js";
import {loadTemporaryTerritory} from "./saveAndLoad.js";

let infoBtn;
let grainBtn;
let wallBtn;
let deleteBtn;
let playBtn;
let pauseBtn;
let stopBtn;
let resetBtn;
export let activeButton;
let rightBox;
let rightBoxFixed;
let slider;
export let sliderSpeed;

/**
 * Setzt das disabled-Attribut des Play-Buttons auf falsch.
 */
export function enablePlayButton() {
    playBtn.disabled = false;
}

/**
 * Setzt das disabled-Attribut des Play-Buttons auf wahr.
 */
export function disablePlayButton() {
    playBtn.disabled = true;
}

/**
 * Setzt das disabled-Attribut des Pause-Buttons auf falsch.
 */
export function enablePauseButton() {
    pauseBtn.disabled = false;
}

/**
 * Setzt das disabled-Attribut des Pause-Buttons auf wahr.
 */
export function disablePauseButton() {
    pauseBtn.disabled = true;
}

/**
 * Setzt das disabled-Attribut des Stopp-Buttons auf falsch.
 */
export function enableStopButton() {
    stopBtn.disabled = false;
}

/**
 * Setzt das disabled-Attribut des Stopp-Buttons auf wahr.
 */
export function disableStopButton() {
    stopBtn.disabled = true;
}

/**
 * Initialisiert die Funktionen der Buttons.
 */
export function initButtons() {
    infoBtn = document.getElementById('info-button');
    grainBtn = document.getElementById('grain-button');
    wallBtn = document.getElementById('wall-button');
    deleteBtn = document.getElementById('delete-button');
    playBtn = document.getElementById('play-button');
    pauseBtn = document.getElementById('pause-button');
    stopBtn = document.getElementById('stop-button');
    resetBtn = document.getElementById('reset-button');
    rightBox = document.getElementById('right-box');
    slider = document.getElementById('slider');
    activeButton = null;
    rightBoxFixed = false;

    window.addEventListener('scroll', changeControlButtonPlacement, false);
    playBtn.addEventListener('click', handlePlayButtonClicked);
    pauseBtn.addEventListener('click', handlePauseButtonClicked);
    stopBtn.addEventListener('click', handleStopButtonClicked);
    resetBtn.addEventListener('click', handleResetButtonClicked);
    slider.addEventListener('change', changeSliderSpeed);
    changeSliderSpeed();

    // Territorium-Designer-Buttons auswählen und Event-Listener hinzufügen
    let buttons = document.querySelectorAll('.territorium-design-button');
    buttons.forEach(function (button) {
        button.addEventListener('click', evt =>  changeBackgroundColor(evt, "territorium-design-button"));
    });

    let changeDirectionBtn = document.getElementById('change-hamster-direction-button')
    changeDirectionBtn.addEventListener('click', handleChangeDirectionButtonClicked);

    let giveHamsterGrainsBtn = document.getElementById('give-hamster-grains-button');
    giveHamsterGrainsBtn.addEventListener('click', handleGiveHamsterGrainsButtonClicked);
    
    // Control-Buttons auswählen und Event-Listener hinzufügen
    let cButtons = document.querySelectorAll('.control-button');
    cButtons.forEach(function (button) {
        button.addEventListener('click', evt =>  changeBackgroundColor(evt, "control-button"));
    });

    // Button zum Ändern der Territorium-Größe
    let changeSizeButton = document.getElementById('change-size-button');
    changeSizeButton.addEventListener('click', handleChangeSizeButtonClicked);

    let dialogButtons = document.querySelectorAll('.dialog-buttons button');
    dialogButtons.forEach(function (button) {
        button.addEventListener('click', closeChangeSizeDialog);
    });
}

/**
 * Führt Aktionen aus, wenn der ChangeDirection-Button geklickt wurde.
 */
function handleChangeDirectionButtonClicked() {
    closeTerritoryTooltip();
    resetTerritoryButtons();
    hamster.turnLeft();
}

/**
 * Führt Aktionen aus, wenn der GiveHamsterGrains-Button geklickt wurde.
 */
function handleGiveHamsterGrainsButtonClicked() {
    closeTerritoryTooltip();
    resetTerritoryButtons();
    openAddGrainsHamsterDialog();
}

/**
 * Führt Aktionen aus, wenn der ChangeSize-Button geklickt wurde.
 */
function handleChangeSizeButtonClicked() {
    closeTerritoryTooltip();
    resetTerritoryButtons();
    openChangeSizeDialog();
}

/**
 * Führt Aktionen aus, wenn der Play-Button geklickt wurde.
 */
function handlePlayButtonClicked() {
    resetHamster();
    resetTerritoryButtons();
    runCode();
}

/**
 * Führt Aktionen aus, wenn der Pause-Button geklickt wurde.
 */
function handlePauseButtonClicked() {
    resetTerritoryButtons();
    pauseCode();
}

/**
 * Führt Aktionen aus, wenn der Stop-Button geklickt wurde.
 */
function handleStopButtonClicked() {
    resetTerritoryButtons();
    stopCode();
}

/**
 * Führt Aktionen aus, wenn der Reset-Button geklickt wurde.
 */
function handleResetButtonClicked() {
    resetTerritoryButtons();
    stopCode();
    loadTemporaryTerritory();
    window.setTimeout(resetControlButtons, 200);
}

/**
 * Aktualisiert den Wert von sliderSpeed, wenn der Slider bewegt wird.
 *
 */
function changeSliderSpeed() {
    let currentSpeed = slider.value;
    sliderSpeed = 100 - currentSpeed;
    slider.title = currentSpeed;
}

/**
 * Ändert den Hintergrund des Buttons.
 * 
 * @param event, das auslösende Event.
 * @param classname, Klassenname der Buttons.
 */
function changeBackgroundColor(event, classname) {
    disableTouch();
    closeTerritoryTooltip();
    resetBackgroundColor(classname);
    let element = event.target;
    let button;
    
    if (element.tagName === "IMG") {
        button = element.parentElement;
    } else {
        button = element;
    }
    
    if (activeButton === event.target || activeButton === event.target.parentElement) {
        button.style.backgroundColor = "";
        activeButton = null;
        return;
    }
    
    // button.style.backgroundColor = "#e0e0e0";
    button.style.backgroundColor = "#f0f0f0";
    button.style.borderWidth = "3px";
    button.style.borderColor = "#000000";
    activeButton = button;
}

/**
 * Setzt die Hintergrundfarbe der Kontrolle-Buttons sowie den aktiven Button auf den Standardwert zurück.
 */
export function resetControlButtons() {
    resetBackgroundColor('control-button');
    activeButton = null;
    enableTouch();
}

/**
 * Setzt die Hintergrundfarbe der Territorium-Buttons sowie den aktiven Button auf den Standardwert zurück.
 */
function resetTerritoryButtons() {
    resetBackgroundColor('territorium-design-button');
    activeButton = null;
}

/**
 * Setzt den Zustand aller Buttons auf default zurück.
 * 
 * @param classname, Klassenname der Buttons.
 */
function resetBackgroundColor(classname) {
    let buttonImages = document.querySelectorAll('.' + CSS.escape(classname) + ' img');
    // let buttonImages = document.querySelectorAll('.territorium-design-button img');
    buttonImages.forEach(function (button) {
        button.style.backgroundColor = "";
    });
    
    let buttons = document.querySelectorAll('.' + CSS.escape(classname));
    // let buttons = document.querySelectorAll('.territorium-design-button');
    buttons.forEach(function (button) {
        button.style.backgroundColor = "";
        button.style.borderWidth = "";
        button.style.borderColor = "#000000";
    });
}

/**
 * Überprüft, ob die Platzierung der Buttons verändert werden muss.
 * Dies ist der Fall, wenn die Höhe des Territoriums in der mobilen Ansicht größer als die Bildschirmhöhe ist
 * und nach unten gescrollt wird.
 */
function changeControlButtonPlacement() {
    let neededSpace = rightBox.offsetHeight + parseInt(window.getComputedStyle(canvas).marginTop) + parseInt(window.getComputedStyle(canvas).borderWidth);
    
    if (canvas.getBoundingClientRect().top <= neededSpace) {
        if (!rightBoxFixed) {
            setControlButtonsFixed();
            rightBoxFixed = true;
        }
    } else {
        if (rightBoxFixed) {
            setControlButtonsStatic();
            rightBoxFixed = false;
        }
    }
}


/**
 * Setzt die Position des rightBox-Elements auf fixed.
 */
function setControlButtonsFixed() {
    rightBox.style.position = "fixed";
}

/**
 * Setzt die Position des rightBox-Elements auf static.
 */
function setControlButtonsStatic() {
    rightBox.style.position = "static";
}