/**
 * Utils
 * @param prop
 * @param data
 * @returns {*}
 */
ko.observableArray.fn.find = function(prop, data) {
    var valueToMatch = data[prop];
    return ko.utils.arrayFirst(this(), function(item) {
        return item[prop] === valueToMatch;
    });
};
String.format = function() {
    // The string containing the format items (e.g. "{0}")
    // will and always has to be the first argument.
    var theString = arguments[0];

    // start with the second argument (i = 1)
    for (var i = 1; i < arguments.length; i++) {
        // "gm" = RegEx options for Global search (more than one instance)
        // and for Multiline search
        var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
        theString = theString.replace(regEx, arguments[i]);
    }

    return theString;
}

/**
 * Search workorders by supervisors
 */

var worker = function(id, picture, code, name, last_name, phone_p, phone_w, email_p, email_w,
                      addrees_street, addrees_city, addrees_state, addrees_zip, date_hire, date_birth, date_fire,
                      department, pay_standard, pay_schedule, pay_rate, is_pay_by_hour, is_full_time, is_active,
                      is_supervisor, unit){
    var self = this;

    self.id = ko.observable(id);
    self.picture = ko.observable({
        file: ko.observable(), // will be filled with a File object
        // Read the files (all are optional, e.g: if you're certain that it is a text file, use only text:
        binaryString: ko.observable(), // FileReader.readAsBinaryString(Blob|File) - The result property will contain the file/blob's data as a binary string. Every byte is represented by an integer in the range [0..255].
        text: ko.observable(), // FileReader.readAsText(Blob|File, opt_encoding) - The result property will contain the file/blob's data as a text string. By default the string is decoded as 'UTF-8'. Use the optional encoding parameter can specify a different format.
        dataURL: ko.observable(picture), // FileReader.readAsDataURL(Blob|File) - The result property will contain the file/blob's data encoded as a data URL.
        arrayBuffer: ko.observable(), // FileReader.readAsArrayBuffer(Blob|File) - The result property will contain the file/blob's data as an ArrayBuffer object.

        // a special observable (optional)
        base64String: ko.observable() // just the base64 string, without mime type or anything else
    });
    self.picture_has_changed = ko.observable(false);
    self.code = ko.observable(code);
    self.name = ko.observable(name);
    self.last_name = ko.observable(last_name);
    self.phone_p = ko.observable(phone_p);
    self.phone_w = ko.observable(phone_w);
    self.email_p = ko.observable(email_p);
    self.email_w = ko.observable(email_w);
    self.addrees_street = ko.observable(addrees_street);
    self.addrees_city = ko.observable(addrees_city);
    self.addrees_state = ko.observable(addrees_state);
    self.addrees_zip = ko.observable(addrees_zip);
    self.date_hire = ko.observable(date_hire);
    self.date_birth = ko.observable(date_birth);
    self.date_fire = ko.observable(date_fire);
    self.department = ko.observable(department ?
        $.grep(viewModel.departments(),
            function(s){ return s.id == department;})[0] : null);
    self.unit = ko.observable(unit ?
        $.grep(viewModel.units(),
            function(s){ return s.id == unit;})[0] : null);
    self.pay_standard = ko.observable(pay_standard);
    self.pay_schedule = ko.observable(pay_schedule ?
        $.grep(viewModel.pay_schedules(),
            function(s){ return s.id == pay_schedule;})[0] : null);
    self.pay_rate = ko.observable(pay_rate);
    self.is_pay_by_hour = ko.observable(is_pay_by_hour != null ? is_pay_by_hour : true);
    self.is_full_time = ko.observable(is_full_time != null ? is_full_time : true);
    self.is_active = ko.observable(is_active != null ? is_active : true);
    self.is_supervisor = ko.observable(is_supervisor != null ? is_supervisor : false);


    self.delete_picture = ko.observable(false);

    self.full_name = ko.computed(function(){
        return self.name() + (self.last_name() ? (" " + self.last_name()) : "")
    });
    self.phone2show = ko.computed(function(){
        var phone = self.phone_p() != null ? self.phone_p() : "";
        if(self.phone_p() != null && self.phone_w() != null)
            phone = self.phone_p() + " / " + self.phone_w()
        else if(self.phone_w() != null)
            phone = self.phone_w()
        return phone;
    });
    self.email2show = ko.computed(function(){
        var email = self.email_p() != null ? self.email_p() : "";
        if(self.email_p() != null && self.email_w() != null)
            email = self.email_p() + " / " + self.email_w()
        else if(self.email_w() != null)
            email = self.email_w()
        return email;
    });
    self.state_zip2show = ko.computed(function(){
        var state_zip = self.addrees_state() != null ? self.addrees_state() : "";
        if(self.addrees_state() != null && self.addrees_zip() != null)
            state_zip = self.addrees_state() + " / " + self.addrees_zip()
        else if(self.addrees_zip() != null)
            state_zip = self.addrees_zip()
        return state_zip;
    });


    self.picture.subscribe(function(new_value) {
        if(new_value.file()){
            self.picture_has_changed(true);
            self.delete_picture(false);
        }
    });

    self.clear_picture = function(){
        if(confirm('Are you sure?')){
            self.picture().clear && self.picture().clear();
            self.picture_has_changed(false);
            self.delete_picture(true);
        }
    };
    self.show_me = function(){
        if(!viewModel.large_picture())
            generate_worker_url(self.id());
        loadPageFeatures();
    };
    self.validate = function(){
        var errors = [];
        if(self.name() == null || self.name().trim() == "")
            errors.push({"element" : "name", "message": "Invalid/No válido"});
        if(self.last_name() == null || self.last_name().trim() == "")
            errors.push({"element" : "last_name", "message": "Invalid/No válido"});
        if(self.code() == null || self.code().trim() == "")
            errors.push({"element" : "code", "message": "Invalid/No válido"});
        else{
            $.ajax({
                type: 'post',
                async: false,
                dataType: 'json',
                url: getURLTryWorkerCode(),
                data: {id: self.id(), code: self.code()},
                success: function(response) {
                    if(!response.ok)
                        errors.push({"element" : "code", "message": response.message});
                },
                error:function() {
                    alert("Error");
                }
            });
        }
        if(self.department() == null)
            errors.push({"element" : "department", "message": "Invalid/No válido"});
        if(self.unit() == null)
            errors.push({"unit" : "unit", "message": "Invalid/No válido"});
        if(self.pay_schedule() == null)
            errors.push({"element" : "pay_schedule", "message": "Invalid/No válido"});
        if(self.pay_rate() == null)
            errors.push({"element" : "pay_rate", "message": "Invalid/No válido"});
        return errors;
    };
    self.saveme =  function(){
        var errors = self.validate();
        if(errors.length == 0){
            var formData = new FormData();

            formData.append('id', self.id());
            formData.append('code', self.code());
            formData.append('picture_has_changed', self.picture_has_changed());
            if(self.picture_has_changed())
                formData.append('picture', self.picture().file(), self.picture().file().name);
            formData.append('name', self.name());
            formData.append('last_name', self.last_name());
            formData.append('phone_p', self.phone_p());
            formData.append('phone_w', self.phone_w());
            formData.append('email_p', self.email_p());
            formData.append('email_w', self.email_w());
            formData.append('addrees_street', self.addrees_street());
            formData.append('addrees_city', self.addrees_city());
            formData.append('addrees_state', self.addrees_state());
            formData.append('addrees_zip', self.addrees_zip());
            formData.append('date_hire', self.date_hire());
            formData.append('date_birth', self.date_birth());
            formData.append('date_fire', self.date_fire());
            formData.append('department', self.department() ? self.department().id : null);
            formData.append('unit', self.unit() ? self.unit().id : null);
            formData.append('pay_standard', self.pay_standard());
            formData.append('pay_schedule', self.pay_schedule() ? self.pay_schedule().id : null);
            formData.append('pay_rate', self.pay_rate());
            formData.append('is_pay_by_hour', self.is_pay_by_hour());
            formData.append('is_full_time', self.is_full_time());
            formData.append('is_active', self.is_active());
            formData.append('is_supervisor', self.is_supervisor());
            formData.append('delete_picture', self.delete_picture());

            var xhr = new XMLHttpRequest();
            xhr.open('POST', getURLUpdateWorker(), true);
            xhr.onload = function () {
                if (xhr.status === 200) {
                    viewModel.message_caption("Success!!!");
                    viewModel.message_text("Worker information has been saved successfully.");
                    viewModel.message_stext("Los datos del trabajador han sido salvados.");
                    viewModel.message_footer(false);
                    viewModel.show_message();
                    go_workers_list();
                    $.each( $(".error-style"), function( i, val ) {
                        $(val).removeClass("error-style");
                    });
                } else {
                    viewModel.message_caption("Error!!!");
                    viewModel.message_text("This information has erros, please check it.");
                    viewModel.message_stext("Los datos registrados presentan errores, favor de revisarlos.");
                    viewModel.message_footer(true);
                    viewModel.show_message();
                }
            };
            xhr.send(formData);
        }
        else{
            $.each( errors, function( i, val ) {
                set_error_style(val.element + "_input");
                set_error_style(val.element + "_label");
            });
        }
    };
    self.enlarge_picture = function(){
        viewModel.large_picture(self.picture().dataURL());
        ShowPicture();
    };
}

var wo_unit_data = function(id, name){
    var self = this;

    self.id = id;
    self.name = name;
};
var wo_dep_data = function(id, name){
    var self = this;

    self.id = id;
    self.name = name;
};
var wo_pay_schedule_data = function(id, name){
    var self = this;

    self.id = id;
    self.name = name;
};

var viewModel = {
    departments: ko.observableArray(new Array()),
    units: ko.observableArray(new Array()),
    pay_schedules: ko.observableArray(new Array()),

    active_workers: ko.observableArray(new Array()),
    unactive_workers: ko.observableArray(new Array()),

    worker_id_to_update: ko.observable(null),
    chosen_worker: ko.observable(null),
    new_worker: ko.observable(new worker(null, null, null, null, null, null, null, null, null, null, null, null,
        null, null, null, null, null, null, null, null, true, true, true, false)),

    large_picture: ko.observable(null),

    message_caption: ko.observable(null),
    message_text: ko.observable(null),
    message_stext: ko.observable(null),
    message_footer: ko.observable(false),
    message_shown: ko.observable(false),

    active_workers_oTable: null,
    unactive_workers_oTable: null,

    datatable_maxHeight: function(){
        return ($(window).height() - $("nav.navbar-inverse.menu-bar").height()) -  130;
    },
    init_active_workers_table: function(){
        this.active_workers_oTable = $('table.active_workers').dataTable( {
            "sScrollY": this.datatable_maxHeight(),
            "scrollCollapse": true,
            "paging": false,
            "jQueryUI": true,
            "order": [[ 1, "asc" ]],
            "aoColumnDefs": [
                { "bSortable": false, "aTargets": [ 0, 4, 5, 6 ] }
            ]
        } );
        this.add_title_of_active_workers_table();
    },
    refresh_active_workers_table: function(){
        if(this.active_workers_oTable != null){
            //Delete the datable object first
            this.active_workers_oTable.fnDestroy();
            //Remove all the DOM elements
            $('#feedback-datatable').empty();
            $("#active-workers-table").addClass("table-responsive col-lg-12");
        }
        this.init_active_workers_table();
    },
    init_unactive_workers_table: function(){
        this.unactive_workers_oTable = $('table.unactive_workers').dataTable( {
            "sScrollY": this.datatable_maxHeight(),
            "scrollCollapse": true,
            "paging": false,
            "jQueryUI": true,
            "order": [[ 1, "asc" ]],
            "aoColumnDefs": [
                { "bSortable": false, "aTargets": [ 0, 4, 5, 6 ] }
            ]
        } );
        this.add_title_of_unactive_workers_table();
    },
    refresh_unactive_workers_table: function(){
        if(this.unactive_workers_oTable != null){
            //Delete the datable object first
            this.unactive_workers_oTable.fnDestroy();
            //Remove all the DOM elements
            $('#feedback-datatable').empty();
            $("#unactive-workers-table").addClass("table-responsive col-lg-12");
        }
        this.init_unactive_workers_table()
    },
    add_title_of_active_workers_table: function(){
        var html_title_0 = '<div class="pull-left" style="font-size: 2.5vmin;"><strong>Active employees</strong>'
            + '<a href="' + getURLNewWorker() + '" style="display: inline-block; margin-left: 2vmin;'
            + ' color: #428bca; cursor: pointer;">'
            + '<span class="glyphicon glyphicon-plus"></span></a></div>';
        $($("div.fg-toolbar")[0]).append(html_title_0);
    },
    add_title_of_unactive_workers_table: function(){
        var html_title_1 = '<div class="pull-left" style="font-size: 2.5vmin;"><strong>Unactive employees</strong>'
            + '<a href="' + getURLNewWorker() + '" style="display: inline-block; margin-left: 2vmin;'
            + ' color: #428bca; cursor: pointer;">'
            + '<span class="glyphicon glyphicon-plus"></span></a></div>';
        $($("div.fg-toolbar")[2]).append(html_title_1);
    },
    active_workers_table_title: function(){
        return ($(window).height() - $("nav.navbar-inverse.menu-bar").height()) -  120;
    },
    get_workers_data: function(){
        loadMask("workers_list", "Loading workers")
        $.ajax({
            type: 'post',
            async: false,
            dataType: 'json',
            url: getURLFilterWorkers(),
            data: {},
            success: function(response) {
                $.each( response.workers, function( i, val ) {
                    var _worker = new worker(val.id,
                        val.picture,
                        val.code,
                        val.name,
                        val.last_name,
                        val.phone_p,
                        val.phone_w,
                        val.email_p,
                        val.email_w,
                        val.addrees_street,
                        val.addrees_city,
                        val.addrees_state,
                        val.addrees_zip,
                        val.date_hire,
                        val.date_birth,
                        val.date_fire,
                        val.department_id,
                        val.pay_standard,
                        val.pay_schedule_id,
                        val.pay_rate,
                        val.is_pay_by_hour,
                        val.is_full_time,
                        val.is_active,
                        val.is_supervisor,
                        val.unit_id);

                    if(val.is_active == false)
                        viewModel.unactive_workers.push(_worker);
                    else
                        viewModel.active_workers.push(_worker);
                });
            },
            error:function() {
                alert("Error");
            }
        });
        hideMask("workers_list");
    },
    get_support: function(){
        $.ajax({
            type: 'post',
            async: false,
            dataType: 'json',
            url: getURLSupport(),
            data: {},
            success: function(response) {
                $.each( response.departments, function( i, val ) {
                    viewModel.departments.push(new wo_dep_data(val.id, val.name));
                });
                $.each( response.units, function( i, val ) {
                    viewModel.units.push(new wo_unit_data(val.id, val.name));
                });
                $.each( response.pay_schedules, function( i, val ) {
                    viewModel.pay_schedules.push(new wo_pay_schedule_data(val.id, val.name));
                });
            },
            error:function() {
                alert("Error");
            }
        });
    },
    get_worker_data: function(){
        $.ajax({
            type: 'post',
            async: false,
            dataType: 'json',
            url: getURLWorkerData(),
            data: {id: viewModel.worker_id_to_update()},
            success: function(response) {
                viewModel.chosen_worker(new worker(response.worker.id,
                    response.worker.picture,
                    response.worker.code,
                    response.worker.name,
                    response.worker.last_name,
                    response.worker.phone_p,
                    response.worker.phone_w,
                    response.worker.email_p,
                    response.worker.email_w,
                    response.worker.addrees_street,
                    response.worker.addrees_city,
                    response.worker.addrees_state,
                    response.worker.addrees_zip,
                    response.worker.date_hire,
                    response.worker.date_birth,
                    response.worker.date_fire,
                    response.worker.department_id,
                    response.worker.pay_standard,
                    response.worker.pay_schedule_id,
                    response.worker.pay_rate,
                    response.worker.is_pay_by_hour,
                    response.worker.is_full_time,
                    response.worker.is_active,
                    response.worker.is_supervisor,
                    response.worker.unit_id));
            },
            error:function() {
                alert("Error");
            }
        });
    },
    create_new_wroker: function(){
        viewModel.chosen_worker(new worker(null, null, null, null, null, null, null, null, null, null, null, null,
            null, null, null, null, null, null, null, null, true, true, true, false, null));
        $('.nav-tabs a[href="#chosen_worker"]').tab('show');
        loadPageFeatures();
    },
    show_message: function(){
        this.message_shown(true);
        $("#message").modal('show');
        if(!this.message_footer()){
            setTimeout(function() {
                $("#message").modal('hide');
                viewModel.message_shown(false);
            }, 3000);
        }
    }
};

//Other functions
function loadPageFeatures(){
    if(check_device() == 2){
        $('.datepicker').datetimepicker({
            language:  'en',
            weekStart: 0,
            todayBtn:  1,
            autoclose: 1,
            todayHighlight: 1,
            startView: 2,
            minView: 2,
            forceParse: 0
        });
    }
    else{
        $('.datepicker').each(function(){
            var value = new Date($(this).val());
            this.type="date";
            value = value.getFullYear() + '-'
                + (value.getMonth() < 9 ? '0' + (value.getMonth() + 1) : (value.getMonth() + 1)) + "-"
                + (value.getDate() < 10 ? '0' + value.getDate() : value.getDate());
            $(this).val(value);});
    }
}
function applyFeturesToStockIndex(index){
    //Masks
    $('#stock-number-' + index).inputmask("9[9]",
        {placeholder:"-", greedy: false});
}
function ShowPicture(){
    $('#large-picture').modal('show');
}
function loadMask(area_id, message){
    $('#' + area_id).waitMe({
        effect: 'ios',
        text: message + '...',
        bg: 'rgba(255,255,255,0.7)',
        color:'#014576'
    });
}
function hideMask(area_id){
    $('#' + area_id).waitMe('hide');
}