if (!HTMLScriptElement.supports?.("importmap")) {
    console.log("Browser does NOT support import maps.");
}

import * as LimImageView from '/res/gnr_express/LimImageView.js';

const imageView = new LimImageView.LimImageView();
imageView.onzoomindexchanged = () => {
    zoomPicker.value = imageView.zoomIndex;
};

const lp = document.getElementById("load-progress");
imageView.onLoadProgressChanged = (value) => {
    lp.value = lp.value < 100 ? Math.max(lp.value, value) : value;
    lp.title = `Loading (${lp.value}%)...`;
};

document.getElementById("canvas-wrapper").appendChild(imageView.imageCanvasDomElement);
document.getElementById("pane").appendChild(imageView.statusbarDomElement);
document.getElementById("pane").appendChild(imageView.navigatorDomElement);

const lutsDialog = document.getElementById("luts-dialog");

const imageOpenButton = document.getElementById("open-image-button");
imageOpenButton.onclick = async () => {
    imageOpenButton.disabled = true;
    hideLutsDialog();
    openFile(await window.pywebview.api.open_image_file());
};

const openFile = (doc_id) => {
    imageOpenButton.disabled = false;
    if (!doc_id.length)
        return;

    imageView.clearFile();
    imageView.viewingMode = LimImageView.ViewingMode.imageView;
    imageView.clearCanvas();
    imageView.docId = doc_id;
    imageViewButton.ariaPressed = "true";
    volumeViewButton.ariaPressed = "false";

    imageView.loadFile().then(() => {
        lutsSwitch.checked = false;

        const zooms = imageView.imageZoomSizes;
        if (zooms.length) {
            zoomPicker.options = zooms.map((item, index) => ({ text: `${item.z}%`, value: index }));
            zoomPicker.hidden = false;
            zoomPicker.value = imageView.zoomIndex;
            bestfitButton.hidden = false;
            zoom100Button.hidden = false;
        }
        else {
            zoomPicker.hidden = true;
            bestfitButton.hidden = true;
            zoom100Button.hidden = true;
        }

        imageViewButton.hidden = imageView.is3d ? false : true;
        volumeViewButton.hidden = imageView.is3d ? false : true;
    });

    lutsSwitch.hidden = false;
    lutsSwitch.ariaChecked = "false";
    lutsButton.hidden = false;
    autoLutButton.hidden = false;
    infoButton.hidden = false;
    closeButton.hidden = false;
}

const imageViewButton = document.getElementById("image-view-mode-button");
imageViewButton.onclick =  (event) => {
    imageViewButton.ariaPressed = "true";
    volumeViewButton.ariaPressed = "false";
    zoomPicker.hidden = false;
    bestfitButton.hidden = false;
    zoom100Button.hidden = false;
    imageView.viewingMode = LimImageView.ViewingMode.imageView;
};

const volumeViewButton = document.getElementById("volume-view-mode-button");
volumeViewButton.onclick = (event) => {
    volumeViewButton.ariaPressed = "true";
    imageViewButton.ariaPressed = "false";
    zoomPicker.hidden = true;
    bestfitButton.hidden = true;
    zoom100Button.hidden = true;
    imageView.viewingMode = LimImageView.ViewingMode.volumeView;
};

const lutsSwitch = document.getElementById("luts-switch");
lutsSwitch.onclick = () => {
    imageView.lutsEnabled = lutsSwitch.checked;
    if (imageView.lutsEnabled && (0 === imageView.channelGains.filter(item => 1.0 < item).length)) {
        autoLutButton?.autoContrast();
    }
}

const autoLutButton = document.getElementById("auto-lut-button");
autoLutButton.onclick = () => {
    autoLutButton?.autoContrast();
};

autoLutButton.autoContrast = async () => {
    const offsets_and_gains = await imageView.autoLuts(imageView.currentSeqIndex, autoScaleUseLo ?? false, autoScalePercentLo ?? 0.0, autoScaleUseHi ?? true, autoScalePercentHi ?? 0.0);
    if (imageView.isRgb) {
        const o = Math.max(...offsets_and_gains.map(item => item.offset));
        const g = Math.min(...offsets_and_gains.map(item => item.gain));
        imageView.setLuts(offsets_and_gains.map(() => g), undefined, offsets_and_gains.map(() => o));
    }
    else
        imageView.setLuts(offsets_and_gains.map(item => item.gain), undefined, offsets_and_gains.map(item => item.offset));
    imageView.lutsEnabled = true;
    lutsSwitch.checked = true;
    if (isLutsDialogVisible()) {
        lutsDialog.updateValues(imageView.channelGains, imageView.channelGammas, imageView.channelOffsets, imageView.showSingleChannelInMono);
    }
};

lutsDialog.addEventListener("lutschanged", (e) => {
    imageView.setLuts(e.target.gains, e.target.gammas, e.target.offsets);
    imageView.lutsEnabled = true;
    lutsSwitch.checked = true;
});

lutsDialog.addEventListener("channelingraychanged", (e) => {
    imageView.showSingleChannelInMono = e.target.singleChannelInGray;
});

lutsDialog.addEventListener("settingschanged", (e) => {
    autoScaleUseLo = e.target.settings.useLo;
    autoScalePercentLo = e.target.settings.percentLo;
    autoScaleUseHi = e.target.settings.useHi;
    autoScalePercentHi = e.target.settings.percentHi;
});

lutsDialog.addEventListener("close", (e) => {
    hideLutsDialog();
});

const showLutsDialog = () => {
    lutsDialog.setupChannels(imageView.channelNames, imageView.channelColors, imageView.isRgb, {
        useLo: autoScaleUseLo, percentLo: autoScalePercentLo,
        useHi: autoScaleUseHi, percentHi: autoScalePercentHi,
    });
    lutsDialog.updateValues(imageView.channelGains, imageView.channelGammas, imageView.channelOffsets, imageView.showSingleChannelInMono);
    lutsDialog.hidden = false;
    lutsButton.ariaPressed = "true";
};

const hideLutsDialog = () => {
    lutsDialog.hidden = true;
    lutsButton.ariaPressed = "false";
};

const isLutsDialogVisible = () => {
    return lutsDialog.hidden !== true;
};

const lutsButton = document.getElementById("luts-button");
lutsButton.onclick = async () => {
    if (isLutsDialogVisible()) {
        hideLutsDialog();
    }
    else {
        showLutsDialog();
    }
};


const infoButton = document.getElementById("info-button");
infoButton.onclick = () => {
    window.pywebview.api.show_image_info();
};

const zoomPicker = document.getElementById("zoom-picker");
zoomPicker.onchange = () => {
    imageView.zoomIndex = zoomPicker.value;
}

const bestfitButton = document.getElementById("best-fit-button");
bestfitButton.onclick = () => {
    imageView.bestFit();
};

const zoom100Button = document.getElementById("zoom-100-button");
zoom100Button.onclick = () => {
    const zooms = imageView.imageZoomSizes;
    for (let i = 0; i < (zooms?.length ?? 0); i++) {
        if (zooms[i].z === '100') {
            imageView.zoomIndex = i;
        }
    }
};

const helpButton = document.getElementById("help-button");

helpButton.onclick = () => {
    window.pywebview.api.show_help();
};

const closeButton = document.getElementById("close-button");
closeButton.onclick = () => {
    hideLutsDialog();
    imageView.clearFile();
    imageViewButton.hidden = true;
    volumeViewButton.hidden = true;
    lutsSwitch.hidden = true;
    lutsButton.hidden = true;
    autoLutButton.hidden = true;
    infoButton.hidden = true;
    zoomPicker.hidden = true;
    bestfitButton.hidden = true;
    zoom100Button.hidden = true;
    closeButton.hidden = true;
    window.pywebview.api.update_title_bar()
};

var shiftKeyState = false;

document.onkeydown = document.onkeyup = document.onclick = (e) => {
    shiftKeyState = e.shiftKey;

    if (e.key == "Escape") {
        hideLutsDialog();
        imageView.playingLoop = "";
    }

    if (e.target.tagName === "INPUT")
        return;

    if (e.type === "keydown" && e.key === "o") {
        imageOpenButton.onclick();
    }

    if (!imageView.valid) {
        return
    }

    if (e.type === "keydown" && e.key === "+") {
        if (imageView.viewingMode == LimImageView.ViewingMode.imageView)
            imageView.zoomIndex = imageView.zoomIndex + 1;
        e.stopPropagation();
    }
    else if (e.type === "keydown" && e.key === "-") {
        if (imageView.viewingMode == LimImageView.ViewingMode.imageView)
            imageView.zoomIndex = imageView.zoomIndex - 1;
        e.stopPropagation();
    }
    else if (e.type === "keydown" && e.key === "/") {
        if (imageView.viewingMode == LimImageView.ViewingMode.imageView)
            bestfitButton.onclick();
        e.stopPropagation();
    }
    else if (e.type === "keydown" && e.key === "ArrowLeft") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("t", -1);
    }
    else if (e.type === "keydown" && e.key === "ArrowRight") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("t", 1);
    }
    else if (e.type === "keydown" && e.key === "Home") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("z", 0);
    }
    else if (e.type === "keydown" && e.key === "ArrowUp") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("z", 1);
    }
    else if (e.type === "keydown" && e.key === "ArrowDown") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("z", -1);
    }
    else if (e.type === "keydown" && e.key === "PageUp") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("m", -1);
    }
    else if (e.type === "keydown" && e.key === "PageDown") {
        imageView.playingLoop = "";
        imageView.moveCurrentLoopIndex("m", 1);
    }
    else if (e.type === "keydown" && "0123456789".includes(e.key)) {
        const ch = "0123456789".indexOf(e.key);
        if (0 <= ch && ch <= imageView.channelNames.length) {
            imageView.channelIndex = ch - 1;
        }
    }
    else if (e.type === "keydown" && e.key === "`") {
        imageView.channelIndex = -1;
    }
    else if (e.type === "keydown" && (e.key === "." || e.key === ",")) {
        imageView.showSingleChannelInMono = !imageView.showSingleChannelInMono;
        lutsDialog.updateValues(imageView.channelGains, imageView.channelGammas, imageView.channelOffsets, imageView.showSingleChannelInMono);
    }
    else if (e.type === "keydown" && e.key === "l" && !e.ctrlKey) {
        lutsSwitch.checked = !lutsSwitch.checked;
        lutsSwitch.onclick();
    }
    else if (e.type === "keydown" && e.key === "a") {
        autoLutButton.onclick();
        e.stopPropagation();
    }
    else if (e.type === "keydown" && e.key === "l" && e.ctrlKey) {
        lutsButton.onclick();
    }
    else if (e.type === "keydown" && e.key === "i") {
        infoButton.onclick();
    }
};

let autoScaleUseLo = true;
let autoScalePercentLo = 0.01;
let autoScaleUseHi = true;
let autoScalePercentHi = 0.01;

const viewportSizeObserver = new ResizeObserver((entries) => {
    let w = 0, h = 0;
    for (const entry of entries) {
        w = Math.floor(entry.contentRect.width);
        h = Math.floor(entry.contentRect.height);
    }
    imageView.updateCanvasSize(w, h);
});

viewportSizeObserver.observe(document.getElementById("viewport"));

