var alreadyStarted = false;

function JobIdBarcodeHander() {

    var uo = null;
    var testSwitch = true;
    //var moveToInfoPageRequested = false;
    //var jobIdInfoRequested = 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 JobIdBarcodeReader = {

        //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();
                JobIdBarcodeReader.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) {
            c1(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));

                JobIdBarcodeReader.init();

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

            $("#cam_stop").unbind().click(function () {
                JobIdBarcodeReader.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 () {
            JobIdBarcodeReader.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();

            JobIdBarcodeReader.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));
            JobIdSparepartBarcodeReader.detachListeners();
            Quagga.stop();
            JobIdBarcodeReader.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("jobid_scan"), //$("fdgss")[0],
                constraints: {
                    width: { min: 200 },
                    height: { min: 200 },
                    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,


       


        LookupScannedJobId: function () {
            var current_session_token = $.cookie("session_token");
            var detected_jobid = this.lastResult;
            var requester = new AjaxRequest({
                data: { "jobid": detected_jobid, "userid": $.cookie("user_id"), "session_token": current_session_token }, // This is for the json request
                success: function (data, status, xhr) {
                    if (data.d.TrueOrFalse == false) {

                        c1('scanjobidwithcamera row 562 - job with detected barcode not found in database');

                        $("#scanjobidwithcamera_errormessage_flash").text(ReturnPhraseOnKey("jobid_barcodecam_no_job_with_this_id") + ' ' + detected_jobid);
                        JobIdBarcodeReader.lastResult = '';
                        JobIdBarcodeHander.jobIdInfoRequested = true;
                        $("#info_jobid_camBarcodeScanner").hide();
                        
                        Quagga.stop();
                        if ($("#scanjobidwithcamera_scanagain").is(":hidden")) {
                            $("#scanjobidwithcamera_scanagain").show();
                        }

                        
                    }
                    
                    else {
                        c1('scanjobwithcamera row 576 - job with detected barcode is found in database, moving on to sp consumption page');
                        if (JOB_BARCODE_SCANNED_AND_CONFIRMED == false) {

                            //Block multiple requests for navigation to spare part consumption page
                            JOB_BARCODE_SCANNED_AND_CONFIRMED = true;
                            
                            //Override search mode for spare parts to be consummed. This will always set initial spare part search mode to manual input.
                            //Enforced to stop situation where job id barcode is immediately read on spare part consumption page, resulting in 'no such spare part' message.
                            //Alternative approach could be considered at later date.

                            CONSUMPTION_SP_SEARCH_MODE = SPAREPART_SEARCH_INPUT_MANUAL;


                            $.cookie("currently_selected_jobid", detected_jobid);
                            $.mobile.navigate("#page_consumption_on_job", { role: "page" });

                            e4('scanjobidwithcamera row 592');
                        }
                        else {
                            c1('scanjobidwithcamera row 595 - Superfluos call to navigate to consumption on job page');
                        }
                    }

                },
                error: function (data, status, xhr) {
                    $("#jobselectonid_jobid_input").val("");
                    c1("Unable to reach web service. Can't verify presence of job search result.");
                    DbCommunicationErrorHandler(WEBSERVICE_FAULT_JSONREQUEST);
                },
                url: "CheckForJobExistenceOnJobId"
            });
            requester.ExecuteRequest();
        },

        handleHeaderText: function () {
            //if (currently_selected_application_section == SPAREPARTS_SECTION) {
            //    $("#scansparepartwithcamera_errormessage_flash").text(ReturnPhraseOnKey("sparepartsearchinstore_header") + storeSelect.SelectedStoreName);
            //}
            //else {
            //    $("#scansparepartwithcamera_errormessage_flash").text(ReturnPhraseOnKey("sp_barcodecam_info_text"));
            //};

            $("#scanjobidwithcamera_errormessage_flash").text("Scan job id with camera  - temporary instruction text");
        }

      

    };

    JobIdBarcodeReader.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) {

        var currentPageId = $.mobile.activePage.attr("id")
        var code = result.codeResult.code;

        if (JobIdBarcodeReader.lastResult !== code) {


            if (code != null) {
                JobIdBarcodeReader.lastResult = code;
                var currentActivePage = $.mobile.activePage.attr("id");
                if (currentActivePage == "page_jobid_barcode_cam") {
                    JobIdBarcodeReader.LookupScannedJobId();                    
                }

            }

        }
    });

    return JobIdBarcodeReader;
}

var jobIdBarcodeHander = null;

$(document).on("pagebeforeshow", "#page_jobid_barcode_cam", function (e) {
    $("#scanjobidwithcamera_scanagain").hide();
    //$("#scansparepartwithcamera_errormessage_flash").text(ReturnPhraseOnKey("sp_barcodecam_info_text"));
    $("#scanjobidwithcamera_errormessage_flash").text('');
    $("#scanjobidwithcamera_errormessage_flash").show();
    JOB_BARCODE_SCANNED_AND_CONFIRMED = false;
});


$(document).on("pageshow", "#page_jobid_barcode_cam", function (e) {
    jobIdBarcodeHander = JobIdBarcodeHander();
    jobIdBarcodeHander.jobIdInfoRequested = false;

    e3(jobIdBarcodeHander.jobIdInfoRequested);

    jobIdBarcodeHander.handleHeaderText();

    CURRENT_JOBID_SEARCH_MODE = JOBID_SEARCH_INPUT_BARCODE;


    jobIdBarcodeHander.init();

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

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

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

    
    $("#scanjobidwithcamera_switch_to_manual").unbind().click(function (event) {
        //$(":mobile-pagecontainer").pagecontainer("change", "#page_machineselect", { role: "page", reverse: false, changeHash: false });
        $.mobile.navigate("#page_jobsearch_onid", { role: "page" });
    });



    $("#scanjobidwithcamera_scanagain").unbind().click(function (event) {
        event.preventDefault();
        jobIdBarcodeHander.init();
        alreadyStarted = true;
        jobIdBarcodeHander.jobIdInfoRequested = false;
        jobIdBarcodeHander.handleHeaderText();
        //$("#scansparepartwithcamera_errormessage_flash").text(ReturnPhraseOnKey("sp_barcodecam_info_text"));

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

        $("#scanjobidwithcamera_scanagain").hide().fadeOut(1000);
    });


});

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

});