/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

var platform_type = "";

var platform_theme = "md";

var app_version = "unknown";

var nw_tray = null;

/**
 * If true and animations are set to "auto", animations should be disabled.
 * @type Boolean
 */
var auto_disable_animations = false;

var openBrowser = function (url) {
    window.open(url);
}

var openSystemBrowser = function (url) {
    window.open(url);
}

var scanBarcode = function (success, error) {
    app.dialog.alert("You can't scan barcodes with this device.", "Sorry!");
}

var doHapticFeedback = function () {
    console.log("Haptics not enabled.");
}

var scanningBarcode = false;

var getLocation = function (success, error) {
    if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function (position) {
            success(position);
        }, function (err) {
            if (typeof error == "function") {
                error(err.message);
            }
        }, {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
        });
    } else {
        if (typeof error == "function") {
            error("Location is unavailable.");
        }
    }
}

var watchLocation = function (success, error) {
    if ("geolocation" in navigator) {
        navigator.geolocation.watchPosition(function (position) {
            success(position);
        }, function (err) {
            if (typeof error == "function") {
                error(err.message);
            }
        }, {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
        });
    } else {
        if (typeof error == "function") {
            error("Location is unavailable.");
        }
    }
}

function setupHTML5BarcodeScanner() {
    $("body").append('<script src="node_modules/@zxing/library/umd/index.min.js"></script>');

    scanBarcode = function (success, error) {
        scanningBarcode = true;
        $("#web-barcode-ui").removeClass("hidden");
        // Stolen from https://zxing-js.github.io/library/examples/multi-camera/
        const codeReader = new ZXing.BrowserMultiFormatReader();
        console.log("Info", 'ZXing code reader initialized');
        codeReader.getVideoInputDevices()
                .then((videoInputDevices) => {
                    if (videoInputDevices.length == 0) {
                        codeReader.reset();
                        $("#web-barcode-ui").addClass("hidden");
                        error("A camera is required to scan barcodes.");
                        return;
                    }
                    selectedDeviceId = videoInputDevices[0].deviceId;

                    codeReader.decodeFromInputVideoDeviceContinuously(selectedDeviceId, 'barcode-viewer', (result, err) => {
                        scanningBarcode = false;
                        if (result) {
                            codeReader.reset();
                            $("#web-barcode-ui").addClass("hidden");
                            success(result.text);
                            return;
                        }
                        if (err && !(err instanceof ZXing.NotFoundException)) {
                            console.error(err);
                            codeReader.reset();
                            $("#web-barcode-ui").addClass("hidden");
                            error(err);
                            return;
                        }
                    });
                })
                .catch((err) => {
                    scanningBarcode = false;
                    console.error(err);
                });
        $("#web-barcode-ui").on("click", function () {
            codeReader.reset();
            scanningBarcode = false;
            $("#web-barcode-ui").addClass("hidden");
        });
    };
}


function setupCordovaBarcodeScanner() {
    scanBarcode = function (success, error) {
        scanningBarcode = true;
        cordova.plugins.barcodeScanner.scan(
                function (result) {
                    scanningBarcode = false;
                    if (!result.cancelled) {
                        success(result.text);
                    }
                },
                function (err) {
                    scanningBarcode = false;
                    if (typeof error == "function") {
                        error(err);
                    }
                },
                {
                    showTorchButton: true,
                    showFlipCameraButton: true,
                    prompt: "Scan barcode",
                    resultDisplayDuration: 0,
                    disableSuccessBeep: true,
                    formats: "QR_CODE,DATA_MATRIX,CODE_39,CODE_93,CODE_128,CODABAR,PDF_417"
                }
        );
    };
}

function initCordova() {
    platform_type = "cordova";

    // Handle back button to close things
    document.addEventListener("backbutton", handleBackButton, false);
    document.addEventListener("deviceready", function () {

        // Make sure the status bar color is set properly
        applyColorTheme();

        if (typeof device != "undefined" && device.platform == "Android") {
            doHapticFeedback = function () {
                window.plugins.deviceFeedback.acoustic();
            }
        }

        // start watching user position after everything's done, hopefully this will make it work
        // with ios
        setupPositionWatcher();

        try {
            if (getStorage("wakelock") == "true") {
                window.powerManagement.acquire(function () {
                    console.log("Info", 'Wakelock acquired');
                }, function () {
                    console.log("Warn", 'Failed to acquire wakelock');
                });
            } else {
                window.powerManagement.release(function () {
                    console.log("Info", 'Wakelock released');
                }, function () {
                    console.log("Warn", 'Failed to release wakelock');
                });
            }
        } catch (ex) {
            console.log("Warn", 'Failed to configure wakelock', ex);
        }
    }, false);
    openBrowser = function (url) {
        cordova.InAppBrowser.open(url, '_blank', 'location=yes');
    }

    openExternalBrowser = function (url) {
        window.open(url, '_system', '');
    }

    // If initialization fails wait a few seconds and try again
    if (typeof device != "undefined" && device.platform != "browser") {
        setupCordovaBarcodeScanner();
    } else {
        setTimeout(function () {
            if (typeof device != "undefined" && device.platform != "browser") {
                setupCordovaBarcodeScanner();
            } else {
                setupHTML5BarcodeScanner();
            }
        }, 5000);
    }

    // Handle geo: urls
    $("#app").on("click", "a[href^='geo:']", function (evt) {
        if (cordova.platformId == "ios") {
            window.open($(this).attr("href").replace("geo:", "http://maps.apple.com/?q="), "_system");
        } else if (cordova.platformId == "android") {
            window.open($(this).attr("href").replace("geo:", "geo:0,0?q="), "_system");
        } else {
            window.open($(this).attr("href"), "_system");
        }
        evt.preventDefault();
    });

    window.addEventListener("batterystatus", function (status) {
        if (getStorage("animation") == "auto") {
            if (status.isPlugged || status.level > 20) {
                // Plugged in or above 20%, enable animations
                auto_disable_animations = false;
                toggleAnimations(true);
            } else {
                auto_disable_animations = false;
                toggleAnimations(true);
            }
        }
    }, false);
}

function initNW() {
    platform_type = "nw";
    platform_theme = "md";
    openBrowser = function (url) {
        nw.Window.open(url, {
            id: url
        }, function (browserwin) {
            // Add menubar so the user can navigate around if they click a link
            var browsermenu = new nw.Menu({type: 'menubar'});
            browsermenu.append(new nw.MenuItem({
                label: "Back",
                click: function () {
                    browserwin.window.history.back();
                }
            }));
            browsermenu.append(new nw.MenuItem({
                label: "Forward",
                click: function () {
                    browserwin.window.history.forward();
                }
            }));
            browsermenu.append(new nw.MenuItem({
                label: "Home",
                click: function () {
                    browserwin.window.location.href = url;
                }
            }));
            browserwin.menu = browsermenu;
        });
    }

    openExternalBrowser = function (url) {
        require('nw.gui').Shell.openExternal(url);
    }


    setupHTML5BarcodeScanner();

    // Handle geo: urls
    $("#app").on("click", ".geolink", function (evt) {
        require('nw.gui').Shell.openExternal($(this).attr("href"));
        evt.preventDefault();
    });

    setupPositionWatcher();
}

function initBrowser() {
    platform_type = "browser";
    platform_theme = "md";
    openBrowser = function (url) {
        window.open(url);
    }

    openExternalBrowser = function (url) {
        window.open(url);
    }

    setupHTML5BarcodeScanner();

    $("#app").on("click", ".geolink", function (evt) {
        window.open($(this).attr("href"), "_blank");
        evt.preventDefault();
    });

    setupPositionWatcher();
}

function initPlatform() {
    if (typeof cordova !== 'undefined') {
        initCordova();
    } else if (typeof nw !== 'undefined') {
        initNW();
    } else {
        initBrowser();
    }

    $.getJSON("package.json", function (data) {
        app_version = data.version;
    });
}