var alreadyStarted = false;

function MachineBarcodeHandler() {

    var uo = null;
    var testSwitch = true;
    var moveToInfoPageRequested = false;
    var navigationAlreadyRequested = false;

    var resultCollector = Quagga.ResultCollector.create({
        capture: true,
        capacity: 20,
        blacklist: [{
            code: "WIWV8ETQZ1", format: "code_93"
        }, {
            code: "EH3C-%GU23RK3", format: "code_93"
        }, {
            code: "O308SIHQOXN5SA/PJ", format: "code_93"
        }, {
            code: "DG7Q$TV8JQ/EN", format: "code_93"
        }, {
            code: "VOFD1DB5A.1F6QU", format: "code_93"
        }, {
            code: "4SO64P4X8 U4YUU1T-", format: "code_93"
        }],
        filter: function (codeResult) {
            // only store results which match this constraint
            // e.g.: codeResult
            return true;
        }
    });

    var MachineBarcodeReader = {

        //setUser: function (_uo)
        //{
        //    uo = _uo; 
        //},

        init: function () {
            

            var self = this;

            
            Quagga.init(this.state, function (err) {
                if (err) {
                    return self.handleError(err);
                }
                //Quagga.registerResultCollector(resultCollector);
                //MachineBarcodeReader.attachListeners();
                MachineBarcodeReader.checkCapabilities();

                decoder: {
                        readers: ["code_128_reader"]
                }

                Quagga.start();
                alreadyStarted = true;


                //$('#cam_start').css('margin-top', $('video').offset().top + $('video').height());
                //$('#cam_stop').css('margin-top', $('video').offset().top + $('video').height());

            });

        },

        handleError: function (err) {
            console.log(err);
        },

        checkCapabilities: function () {
            var track = Quagga.CameraAccess.getActiveTrack();
            var capabilities = {};
            if (typeof track.getCapabilities === 'function') {
                capabilities = track.getCapabilities();
            }
            this.applySettingsVisibility('zoom', capabilities.zoom);
            this.applySettingsVisibility('torch', capabilities.torch);
        },

        updateOptionsForMediaRange: function (node, range) {
            var NUM_STEPS = 6;
            var stepSize = (range.max - range.min) / NUM_STEPS;
            var option;
            var value;
            while (node.firstChild) {
                node.removeChild(node.firstChild);
            }
            for (var i = 0; i <= NUM_STEPS; i++) {
                value = range.min + (stepSize * i);
                option = document.createElement('option');
                option.value = value;
                option.innerHTML = value;
                node.appendChild(option);
            }
        },

        applySettingsVisibility: function (setting, capability) {
            // depending on type of capability
            if (typeof capability === 'boolean') {
                var node = document.querySelector('input[name="settings_' + setting + '"]');
                if (node) {
                    node.parentNode.style.display = capability ? 'block' : 'none';
                }
                return;
            }
            if (window.MediaSettingsRange && capability instanceof window.MediaSettingsRange) {
                var node = document.querySelector('select[name="settings_' + setting + '"]');
                if (node) {
                    this.updateOptionsForMediaRange(node, capability);
                    node.parentNode.style.display = 'block';
                }
                return;
            }
        },

        initCameraSelection: function () {

            var streamLabel = Quagga.CameraAccess.getActiveStreamLabel();

            return Quagga.CameraAccess.enumerateVideoDevices()
                .then(function (devices) {
                    //function pruneText(text) {
                    //    return text.length > 30 ? text.substr(0, 30) : text;
                    //}
                    //var $deviceSelection = document.getElementById("deviceSelection");
                    //while ($deviceSelection.firstChild) {
                    //    $deviceSelection.removeChild($deviceSelection.firstChild);
                    //}
                    //devices.forEach(function (device) {
                    //    var $option = document.createElement("option");
                    //    $option.value = device.deviceId || device.id;
                    //    $option.appendChild(document.createTextNode(pruneText(device.label || device.deviceId || device.id)));
                    //    $option.selected = streamLabel === device.label;
                    //    $deviceSelection.appendChild($option);
                    //});
                });
        },

        attachListeners: function () {
            var self = this;

            self.initCameraSelection();
            $(".controls").on("click", "button.stop", function (e) {
                e.preventDefault();
                Quagga.stop();
                self._printCollectedResults();
            });

            $("#cam_start").unbind().click(function () {
                $(".video").show();
                $(".drawingBuffer").show();
                $(".spac").show();
                //$("#cam_start").css('margin-top', '399px');
                //$("#cam_stop").css('margin-top', '399px');
                //$('#cam_start').css('margin-top', $('video').offset().top + $('video').height() - (70));
                //$('#cam_stop').css('margin-top', $('video').offset().top + $('video').height() - (70));

                MachineBarcodeReader.init();

                document.getElementsByClassName('video')[0].play();
            });

            $("#cam_stop").unbind().click(function () {
                MachineBarcodeReader.detachListeners();
                Quagga.stop();
                document.getElementsByClassName('video')[0].pause();
                document.getElementsByClassName('video')[0].currentTime = 0;

                $(".video").hide();
                $(".drawingBuffer").hide();

                //$('#cam_start').css('margin-top', 'inherit');
                //$('#cam_stop').css('margin-top', 'inherit');
            });

            $(".controls .reader-config-group").on("change", "input, select", function (e) {
                e.preventDefault();
                var $target = $(e.target),
                    value = $target.attr("type") === "checkbox" ? $target.prop("checked") : $target.val(),
                    name = $target.attr("name"),
                    state = self._convertNameToState(name);

                self.setState(state, value);
            });
        },

        ShutdownCamera : function () {
            MachineBarcodeReader.detachListeners();
            Quagga.stop();
            //document.getElementsByClassName('video')[0].pause();
            //document.getElementsByClassName('video')[0].currentTime = 0;

            $(".video").hide();
            $(".drawingBuffer").hide();

            alreadyStarted = false;

        },

        StartCamera : function() {
            $(".video").show();
            $(".drawingBuffer").show();
            $(".spac").show();

            MachineBarcodeReader.init();

            document.getElementsByClassName('video')[0].play();

        },

        _printCollectedResults: function () {
            //var results = resultCollector.getResults(),
            //    $ul = $("#result_strip ul.collector");

            //results.forEach(function (result) {
            //    var $li = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');

            //    $li.find("img").attr("src", result.frame);
            //    $li.find("h4.code").html(result.codeResult.code + " (" + result.codeResult.format + ")");
            //    $ul.prepend($li);
            //});
        },

        _accessByPath: function (obj, path, val) {
            var parts = path.split('.'),
                depth = parts.length,
                setter = (typeof val !== "undefined") ? true : false;

            return parts.reduce(function (o, key, i) {
                if (setter && (i + 1) === depth) {
                    if (typeof o[key] === "object" && typeof val === "object") {
                        Object.assign(o[key], val);
                    } else {
                        o[key] = val;
                    }
                }
                return key in o ? o[key] : {};
            }, obj);
        },

        _convertNameToState: function (name) {
            return name.replace("_", ".").split("-").reduce(function (result, value) {
                return result + value.charAt(0).toUpperCase() + value.substring(1);
            });
        },

        detachListeners: function () {
            $(".controls").off("click", "button.stop");
            $(".controls .reader-config-group").off("change", "input, select");
        },

        applySetting: function (setting, value) {
            var track = Quagga.CameraAccess.getActiveTrack();
            if (track && typeof track.getCapabilities === 'function') {
                switch (setting) {
                    case 'zoom':
                        return track.applyConstraints({ advanced: [{ zoom: parseFloat(value) }] });
                    case 'torch':
                        return track.applyConstraints({ advanced: [{ torch: !!value }] });
                }
            }
        },

        setState: function (path, value) {
            var self = this;

            if (typeof self._accessByPath(self.inputMapper, path) === "function") {
                value = self._accessByPath(self.inputMapper, path)(value);
            }

            if (path.startsWith('settings.')) {
                var setting = path.substring(9);
                return self.applySetting(setting, value);
            }
            self._accessByPath(self.state, path, value);

            //console.log(JSON.stringify(self.state));
            MachineBarcodeReader.detachListeners();
            Quagga.stop();
            MachineBarcodeReader.init();
        },

        inputMapper: {
            inputStream: {
                constraints: function (value) {
                    if (/^(\d+)x(\d+)$/.test(value)) {
                        var values = value.split('x');
                        return {
                            width: { min: parseInt(values[0]) },
                            height: { min: parseInt(values[1]) }
                        };
                    }
                    return {
                        deviceId: value
                    };
                }
            },

            numOfWorkers: function (value) {
                return parseInt(value);
            },

            decoder: {
                readers: function (value) {
                    if (value === 'ean_extended') {
                        return [{
                            format: "ean_reader",
                            config: {
                                supplements: [
                                    'ean_5_reader', 'ean_2_reader'
                                ]
                            }
                        }];
                    }
                    return [{
                        format: value + "_reader",
                        config: {}
                    }];
                }
            }
        },
        state: {
            inputStream: {
                type: "LiveStream",
                target: document.getElementById("m_scan"),
                constraints: {
                    width: { min: 200 },
                    height: { min: 200 },
                    //width: 200,
                    //height: 400,

                    facingMode: "environment",
                    aspectRatio: { min: 1, max: 2 }
                }
            },
            locator: {
                patchSize: "medium",
                halfSample: true
            },
            numOfWorkers: 1,
            frequency: 5,
            decoder: {
                readers: [
                {
                    format: "code_128_reader",
                    config: {}
                },
                 
                //{
                //    format: "code_39_reader",
                //    config: {}
                //},
                //{
                //    format: "ean_reader",
                //    config: {}
                //}
                ]
            },
            locate: true
        },
        lastResult: null,


        //PM5 Mobile section

        checkForMachineExistenceOnBarcode : function () {
            var machine_search_param = this.lastResult;
            var current_session_token = $.cookie("session_token");
            var user_id = $.cookie("user_id");



            var requester = new AjaxRequest({
                data: { "machine_search_param": machine_search_param, "user_id": user_id, "session_token": current_session_token }, // This is for the json request
                success: function (data, status, xhr) {

                    var checkValidation = data.d.SessionTokenValid;
                    var machinesPresent = data.d.TrueOrFalse;
                    if (checkValidation == false) {

                        //$.mobile.navigate("#dialog_tokenexpired", { role: "dialog" });

                        $("#scanwithcamera_generic_popup_header").html(ReturnPhraseOnKey("dialogue_tokenexpired_message1"));
                        $("#scanwithcamera_generic_popup_text").html(ReturnPhraseOnKey("dialogue_tokenexpired_message1"));

                        $("#scanwithcamera_generic_popup").off().on("popupafterclose", function (event, ui) {
                            $(":mobile-pagecontainer").pagecontainer("change", "#page_login", { role: "page", reverse: false, changeHash: false });
                            e1('scanwithcamera row 389');
                        });

                        $("scanwithcamera_generic_popup_button").unbind("click").click(function () {
                            $("#scanwithcamera_generic_popup").popup("close");
                        });

                        $("#scanwithcamera_generic_popup").popup().popup("open");

                    }
                    else if (machinesPresent == false) {

                        $("#errormessage_flash").text(ReturnPhraseOnKey("machineselect_message_nomachine_with_bacode") + ' ' + machine_search_param);
                        //setTimeout(function () { $("#errormessage_flash").text(ReturnPhraseOnKey("barcodecam_info_text")) }, 3000);
                        //$("#errormessage_flash").show().delay(3000).fadeOut(300);
                        $("#info_camBarcodeScanner").hide();

                        MachineBarcodeReader.lastResult = '';
                        MachineBarcodeReader.moveToInfoPageRequested = true;

                        Quagga.stop();
                        if ($("#scanwithcamera_scanagain").is(":hidden")) {
                            $("#scanwithcamera_scanagain").show();
                        }

                    }

                    else if (machinesPresent == true) {
                        //if ($("#scanwithcamera_errormessage").is(":visible")) {
                        //    $("#scanwithcamera_errormessage").hide();
                        //}

                        if (data.d.StringToPass !== undefined) {
                            $.cookie("currently_selected_machine", data.d.StringToPass);
                        }

                        //Set barcode reading from text fields to nothing - otherwise scanning will continue after each enter button entry
                        initScanner(undefined);
                        //$.mobile.navigate("#page_machinedetail", { role: "page" });
                        if (MachineBarcodeReader.moveToInfoPageRequested == false) {
                            if (testSwitch == true) {
                                MachineBarcodeReader.moveToInfoPageRequested = true;
                            }
                            $.mobile.navigate("#page_machinedetail", { role: "page" });
                            e5('scanwithcamera row 432');
                        }
                    }

                },
                error: function (data, status, xhr) {
                    console.log("Unable to reach web service. Can't verify presence of machine search result.");
                    DbCommunicationErrorHandler(WEBSERVICE_FAULT_JSONREQUEST);
                },
                url: "CheckForMachinePresenceOnBarcode"
            });
            requester.ExecuteRequest();
        }

    //    MachineExistenceRequestComplete : function (data, status, xhr) {

    //    console.log("Request successful");
    //    console.log(data.d);
    //    var checkValidation = data.d.SessionTokenValid;
    //    var machinesPresent = data.d.TrueOrFalse;
    //    if (checkValidation == false) {

    //        console.log("moving to token expired page");
    //        //$.mobile.navigate("#dialog_tokenexpired", { role: "dialog" });

    //        $("#scanwithcamera_generic_popup_header").html(ReturnPhraseOnKey("dialogue_tokenexpired_message1"));
    //        $("#scanwithcamera_generic_popup_text").html(ReturnPhraseOnKey("dialogue_tokenexpired_message1"));

    //        $("#scanwithcamera_generic_popup").off().on("popupafterclose", function (event, ui) {
    //            $(":mobile-pagecontainer").pagecontainer("change", "#page_login", { role: "page", reverse: false, changeHash: false });
    //        });

    //        $("scanwithcamera_generic_popup_button").unbind("click").click(function () {
    //            $("#scanwithcamera_generic_popup").popup("close");
    //        });

    //        $("#scanwithcamera_generic_popup").popup().popup("open");

    //    }
    //    else if (machinesPresent == false) {
    //        console.log("Could not find machines");
    //        $("#scanwithcamera_errormessage").text(ReturnPhraseOnKey("machineselect_message_nomachinesfound"));
    //        $("#scanwithcamera_errormessage").show();
    //    }

    //    else if (machinesPresent == true) {
    //        if ($("#scanwithcamera_errormessage").is(":visible")) {
    //            $("#scanwithcamera_errormessage").hide();
    //        }

    //        $.cookie("machinesearchparam", $("#selectmachine_machineid_input").val());
    //        $.cookie("machinetypeidsearchparam", $("#machinesearch_machinetypes").val());

    //        //Set barcode reading from text fields to nothing - otherwise scanning will continue after each enter button entry
    //        initScanner(undefined);
    //        $.mobile.navigate("#page_machinelist", { role: "page" });
    //    }

    //},

    //MachineExistenceRequestIncomplete : function (data, status, xhr) {
    //    console.log("Unable to reach web service. Can't verify presence of machine search result.");
    //    DbCommunicationErrorHandler(WEBSERVICE_FAULT_JSONREQUEST);
    //}


    };

    MachineBarcodeReader.init();

    Quagga.onProcessed(function (result) {
        var drawingCtx = Quagga.canvas.ctx.overlay,
            drawingCanvas = Quagga.canvas.dom.overlay;

        if (result) {
            //if (result.boxes) {
            //    drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
            //    result.boxes.filter(function (box) {
            //        return box !== result.box;
            //    }).forEach(function (box) {
            //        Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "pink", lineWidth: 2 });
            //    });
            //}

            //if (result.box) {
            //    Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "yellow", lineWidth: 2 });
            //}

            //if (result.codeResult && result.codeResult.code) {
            //    Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: "olivedrab", lineWidth: 3 });
            //}
        }
    });

    Quagga.onDetected(function (result) {


        //If Quagga is triggered, ensure that the scan is handled here ONLY if this page is actually on the screen

        var currentPageId = $.mobile.activePage.attr("id")

        if (currentPageId !== "page_barcode_cam") {
            return;
        }
        else{
            var code = result.codeResult.code;

            if (MachineBarcodeReader.lastResult !== code) {

                if (code != null) {
                    MachineBarcodeReader.lastResult = code;
                    var currentActivePage = $.mobile.activePage.attr("id");
                    if (currentActivePage == "page_barcode_cam") {
                        MachineBarcodeReader.checkForMachineExistenceOnBarcode();
                    }

                }
            }
   
        }
    });

    return MachineBarcodeReader;
}

var machineBarcodeHandler = null;

$(document).on("pagebeforeshow", "#page_barcode_cam", function (e) {
    $("#scanwithcamera_scanagain").hide();
    
    //$("#page_sparepart_barcode_cam .scanner_section").attr("id", "");
    //$("#page_barcode_cam .scanner_section").attr("id", "interactive");

    $("#errormessage_flash").text(ReturnPhraseOnKey("barcodecam_info_text"));
    $("#errormessage_flash").show();
});


$(document).on("pageshow", "#page_barcode_cam", function (e) {
    machineBarcodeHandler = MachineBarcodeHandler();
    machineBarcodeHandler.moveToInfoPageRequested = false;
    machineBarcodeHandler.navigationAlreadyRequested = false;

    CURRENT_MACHINE_SEARCH_MODE = MACHINE_SEARCH_INPUT_BARCODE;

    $("#errormessage_flash").text(ReturnPhraseOnKey("barcodecam_info_text"));

    machineBarcodeHandler.init();

    if($(".video").is(":hidden")){
        $(".video").show();
    }
    if ($(".drawingBuffer").is(":hidden")) {
        $(".drawingBuffer").show();
    }

    if ($(".spac").is(":hidden")) {
        $(".spac").show();
    }

    machineBarcodeHandler.moveToInfoPageRequested = false;
    if ($("#info_camBarcodeScanner").is(":hidden")) {
        $("#info_camBarcodeScanner").show();
    }



    $("#barcode_cam_switch_to_manual").unbind().click(function (event) {
        c8('scanwithcamera ln615: returing with header menu button');

        if (machineBarcodeHandler.navigationAlreadyRequested == false) {
            machineBarcodeHandler.navigationAlreadyRequested = true;
            machineBarcodeHandler.moveToInfoPageRequested = true;
        }
        CURRENT_MACHINE_SEARCH_MODE = MACHINE_SEARCH_INPUT_MANUAL;

        $.mobile.navigate("#page_machineselect", { role: "page" });
    });

    

    $("#scanwithcamera_scanagain").unbind().click(function (event) {
        event.preventDefault();
        machineBarcodeHandler.init();
        alreadyStarted = true;
        machineBarcodeHandler.moveToInfoPageRequested = false;
        if ($("#info_camBarcodeScanner").is(":hidden")) {
            $("#info_camBarcodeScanner").show();
        }
        $("#errormessage_flash").text(ReturnPhraseOnKey("barcodecam_info_text"));
        $("#scanwithcamera_scanagain").hide().fadeOut(1000);
    });
});

$(document).on("pagehide", "#page_barcode_cam", function () {
    machineBarcodeHandler.ShutdownCamera();
    machineBarcodeHandler.lastResult = '';

});
