var contentArray;
var projectfileName;
var reader;
var spinner = document.querySelector("#qtspinner");
var canvas = document.querySelector("#qtcanvas");
var uploadform = document.querySelector("#uploadform");
var fileinput = document.querySelector("#fileinput");
var dropzone = document.querySelector("#dropzone");
var projectsmenu = document.querySelector("#projectsmenu");
var footer = document.querySelector("#footer");
var launchstatus = document.querySelector("#launchstatus");
var launchstatustext = document.querySelector("#launchstatustext");
var downloadProgress = document.querySelector("#downloadprogress");
var appheader = document.querySelector("#appheader");
var appname = document.querySelector("#appname");
var alertBox = document.querySelector("#alertBox");
var passwordDialog = document.querySelector("#passwordDialog");
var alertText = document.querySelector("#alertText");
var passwordInput = document.querySelector("#passwordInput");
var qtLoader;
var versionInfo = undefined;

function showAlert(text) {
    alertText.innerHTML = text;
    alertBox.style.display = "block";
}

function hideMainPage() {
    uploadform.style.display =
        dropzone.style.display =
        projectsmenu.style.display =
        footer.style.display =
        "none";
}

function showDownloader() {
    hideMainPage();
    launchstatustext.innerHTML = "Downloading application";
}

function baseName(str) {
    var base = new String(str).substring(str.lastIndexOf("/") + 1);
    if (base.lastIndexOf(".") != -1)
        base = base.substring(0, base.lastIndexOf("."));
    return base;
}

function loadFileInHash() {
    var filename = location.hash.split("#")[1];
    appname.innerHTML = baseName(filename);
    launchstatus.style.display = "block";
    loadFromServer(filename, passwordInput.value);
}

window.addEventListener(
    "hashchange",
    function () {
        if (location.hash == "") {
            location.reload(); // E.g. when browsing back
            return;
        }
        loadFileInHash();
    },
    false
);

function handleFileSelection(event) {
    reader = new FileReader();
    var file = fileinput.files[0];
    reader.onload = function () {
        contentArray = new Uint8Array(reader.result);
        projectfileName = file.name;
        hideMainPage();
        loadProjector();
    };
    reader.readAsArrayBuffer(file);
}

function loadFromServer(fileName, password) {
    var request = new XMLHttpRequest();
    request.responseType = "arraybuffer";
    request.onload = function () {
        hidePasswordDialog();
        if (this.status == 404) {
            alert(this.status + " " + this.statusText);
            location.hash = "";
            return;
        }
        if (this.status == 403) {
            showPasswordDialog();
            return;
        }
        contentArray = new Uint8Array(request.response);
        projectfileName = fileName;
        loadProjector();
    };

    request.onprogress = (event) => {
        showDownloader();
        var percentage = (100 * event.loaded) / event.total;
        console.log(
            `Downloaded ${event.loaded} of ${event.total} bytes`,
            "- ",
            percentage,
            "%"
        );
        downloadProgress.style = "width: " + percentage + "%";
    };

    downloadProgress.style = "width: 0%";
    request.open("GET", "qmlprojects/" + fileName, true);
    request.setRequestHeader("authorization", password);
    request.send(null);
}

function listExamples() {
    var request = new XMLHttpRequest();
    request.responseType = "json";
    request.onload = function (oEvent) {
        var json = request.response;
        if (json.projects.length > 0) {
            var projectsmenulist = document.querySelector("#projectsmenulist");
            for (project in json.projects) {
                var li = document.createElement("li");
                var a = document.createElement("a");
                var filename = json.projects[project].file;
                a.setAttribute("href", "#" + filename);
                a.innerHTML = filename;
                li.appendChild(a);
                projectsmenulist.appendChild(li);
            }
            projectsmenu.style.display = "block";
        }
    };
    request.open("GET", "resources/meta-data/qmlprojects.json", true);
    request.send(null);
}

function showVersionInfo() {
    var request = new XMLHttpRequest();
    request.responseType = "json";
    request.onload = function (oEvent) {
        if (request.status == 404) {
            console.log("Unable to load version info");
            return;
        }
        var json = request.response;
        versionInfo = request.response;
        var appVersion = json.appVersion;
        var qtVersion = json.qtVersion;
        var qtQuickComponentsVersion = json.qtQuickComponentsVersion;
        var emsdkVersion = json.emsdkVersion;
        var webServiceVersion = json.webServiceVersion;
        var versionText =
            "Design Viewer " + appVersion +
            "<br>Qt Quick Components " + qtQuickComponentsVersion +
            "<br>Emscripten SDK " + emsdkVersion +
            "<br>Built with Qt " + qtVersion
        document.querySelector("#versioninfo_main").innerHTML = versionText;
    };
    request.open("GET", "resources/meta-data/version.json", true);
    request.send(null);
}

function showPasswordDialog() {
    passwordDialog.style.display = "block";
}
function hidePasswordDialog() {
    passwordDialog.style.display = "none";
}

function verifyWebGL() {
    const gl = canvas.getContext("webgl2");
    if (!gl) {
        if (typeof WebGL2RenderingContext !== "undefined") {
            showAlert(
                "Your browser appears to support WebGL2 but it might be disabled. Try updating your OS and/or video card drivers."
            );
        } else {
            showAlert("Your browser has no support for WebGL2.");
        }
        return false;
    } else {
        return true;
    }
}

function init() {
    if (!verifyWebGL()) {
        return;
    }

    if (location.hash == "") listExamples();
    else loadFileInHash();

    showVersionInfo();

    fileinput.onchange = handleFileSelection;
    dropzone.ondragover = dropzone.ondragenter = function (event) {
        event.preventDefault();
    };
    dropzone.ondrop = function (event) {
        fileinput.files = event.dataTransfer.files;
        handleFileSelection(event);
        event.preventDefault();
    };
}

function restart() {
    qtLoader.loadEmscriptenModule("qtdesignviewer");
}

function loadProjector() {
    qtLoader = QtLoader({
        canvasElements: [canvas],
        showLoader: function (loaderStatus) {
            spinner.style.display = "block";
            canvas.style.display = "none";
            if (loaderStatus === "Downloading/Compiling")
                loaderStatus = "Starting";
            launchstatustext.innerHTML = loaderStatus;
        },
        showError: function (errorText) {
            launchstatustext.innerHTML = errorText;
            spinner.style.display = "block";
            canvas.style.display = "none";
        },
        showExit: function () {
            launchstatustext.innerHTML = "Application exit";
            if (qtLoader.exitCode !== undefined)
                launchstatustext.innerHTML += " with code " + qtLoader.exitCode;
            if (qtLoader.exitText !== undefined)
                launchstatustext.innerHTML += " (" + qtLoader.exitText + ")";
            spinner.style.display = "block";
            canvas.style.display = "none";
        },
        showCanvas: function () {
            spinner.style.display = "none";
            canvas.style.display = "block";
            launchstatus.style.display = "none";
            appheader.style.display = "block";
        },
    });

    // workaround for making sure that self.module is set up before
    // running setScreenSize
    self.moduleConfig.preRun = [];
    self.moduleConfig.preRun.push(function (module) {
        self.module = module;
    });

    qtLoader.loadEmscriptenModule("qtdesignviewer");
}

function setScreenSize(width, height) {
    if (width > 1 && height > 1) {
        canvas.style.width = `${width}px`;
        canvas.style.height = `${height}px`;
    } else {
        // undefined root size
        canvas.style.width = canvas.style.height = "100%";
        document.documentElement.style.height = document.body.style.height =
            "100%";
        document.documentElement.style.overflow =
            document.body.style.overflow = "hidden";
    }
    qtLoader.resizeCanvasElement(canvas);
}