/**
 * Created by vlade on 2/27/15.
 */

/**
 * 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;
    });
};

/**
 * Search workers 4 time record manager
 */

function area(id, index, code, name, description, level, active, color){
    var self = this;

    self.id = id;
    self.index = index;
    self.code = code;
    self.name = name;
    self.description = description;
    self.level = level;
    self.active = active;
    self.color = color;

    self.parent = ko.observable(null);
    self.children = ko.observableArray(new Array());
    self.selected = ko.observable(false);

    self.level_back = function(){
        if(self.parent() != null)
            self.parent().click_me();
    };

    self.selected_children_count = function(){
        var count = 0
        if(self.children().length == 0)
            count = self.selected() ? 1 : 0;
        else
            $.each( self.children(), function( i, child ) {
                count += child.selected_children_count();
            });
        return count;
    };

    self.generated_works = function(){
        var works = "";
        var children_count = self.children().length;
        if(self.selected() && self.children().length == 0)
            works = self.name;
        else
            $.each( self.children(), function( i, child ) {
                if(child.generated_works() != ""){
                    if(works == "")
                        works += child.generated_works();
                    else
                        works += " - " + child.generated_works();
                }
            });
        return works;
    };

    self.click_me = function(){
        if(self.children().length == 0)
                self.select_me();
        else{
            viewModel.parent_cat_selected(self);
            viewModel.children_cat_2_shown(self.children());
            $('#' + self.code + '-children').modal('show');
        }
    }

    self.select_me = function(){
        self.selected(!self.selected());
    };

    self.deselect_my_children = function(){
        if(self.children().length == 0)
            self.selected(false);
        else
            $.each( self.children(), function( i, child ) {
                child.deselect_my_children();
            });
    };
}
function work(index, name, color){
    var self = this;
    self.index = index;
    self.name = name;
    self.color = color;
    self.selected = ko.observable(false);

    self.select_me = function(){
        self.selected(!self.selected());
        if(self.selected())
            viewModel.add_selected_work(self);
        else
            viewModel.remove_selected_work(self);
    };
}
function loop(id, workorder, as_no, area, work, started){
    var self = this;
    self.id = id;
    self.workorder = ko.observable(workorder);
    self.as_no = ko.observable(as_no);
    self.area = ko.observable(area);
    self.work = ko.observable(work);
    self.started = ko.observable(started);

    self.active = ko.observable(true);

    self.active_me = function(){
        self.active(!self.active());
    };
    self.remove_me = function(){
        viewModel.worker().remove_loop(this);
    };
}
function worker(id, name, department, picture, code, pay_rate){
    var self = this;
    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.department = ko.observable(department);
    self.picture = ko.observable(picture);
    self.code = ko.observable(code);
    self.pay_rate = pay_rate;

    self.loops = ko.observableArray(new Array());
    self.loops2start = ko.observableArray(new Array());

    self.remove_loop = function(loop){
        self.loops.remove(loop);
    };
}
function stock(id, number, code, serial, equipment, description, picture){
    var self = this;
    self.id = id;
    self.number = number;
    self.code = code;
    self.serial = serial;
    self.equipment = equipment;
    self.description = description;
    self.picture = picture;

    self.selected = ko.observable(false);

    self.select_me = function(){
        self.selected(!self.selected());
        if(self.selected())
            viewModel.workorder().add_selected_stock(self);
        else
            viewModel.workorder().remove_selected_stock(self);
    };
    self.my_class = ko.computed(function() {
        var my_class = "action-button btn-info-touch rounded-all";

        my_class += self.selected() ? " selected" : "";

        return my_class;
    });
    /*self.my_height = ko.computed(function() {
     if(viewModel.workorder()){
     return viewModel.workorder().stocks().length > 16 ? "18.5%" :
     viewModel.workorder().stocks().length > 10 ? "23.5%" :
     (100 / viewModel.workorder().stocks().length) + "%";
     }
     return 0;
     });*/
}
function workorder(id, number, supervisor, worktype, picture, client, equipment){
    var self = this;
    self.id = id;
    self.number = number;
    self.supervisor = supervisor;
    self.worktype = worktype;
    self.picture = picture;
    self.client = client;
    self.equipment = equipment;

    self.stocks = ko.observableArray(new Array());
    self.selected_stocks = ko.observableArray(new Array());

    self.add_me = function(){
        viewModel.add_workorder(self);
    };
    self.select_me = function(){
        viewModel.workorder(self);
    };
    self.remove_me = function(){
        viewModel.remove_workorder(self);
    };
    self.add_selected_stock = function(stock){
        self.selected_stocks.push(stock);
        self.selected_stocks().sort(function(a, b){return a.number- b.number;});
        self.selected_stocks.valueHasMutated();

        viewModel.worker().loops2start.push(new loop(null, self.number, stock.number, null, null, null));
    };
    self.remove_selected_stock = function(stock){
        self.selected_stocks.remove(stock);
        self.selected_stocks().sort(function(a, b){return a.number- b.number;});
        self.selected_stocks.valueHasMutated();

        var loop2del = $.grep(viewModel.worker().loops2start(), function(s){
            return s.as_no() == stock.number && s.workorder() == self.number;
        });
        if(loop2del.length == 1){
            loop2del = loop2del[0];
            viewModel.worker().loops2start.remove(loop2del);
        }
    };
}

var viewModel = {
    worker_code: ko.observable(null),
    workorder_number: ko.observable(null),
    stage: ko.observable(0),
    stages: [0, 1, 2, 3, 4],
    area_options_count: stock_areas.length,
    work_options_count: area_works.length,

    can_go_back: ko.observable(false),
    can_go_next: ko.observable(false),

    date: ko.observable(null),
    started: ko.observable(null),
    finished: ko.observable(null),

    hours: function(){
        var result = 0;
        if(this.started() == "")
            this.started(null);
        if(this.finished() == "")
            this.finished(null);
        if(this.started() != null && this.finished() != null){
            var h1 = parseInt(this.started().split(':')[0], 10) * 60 + parseInt(this.started().split(':')[1], 10);
            var h2 = parseInt(this.finished().split(':')[0], 10) * 60 + parseInt(this.finished().split(':')[1], 10);
            /*if(self.lunch())
                h2 = h2 - 30;*/
            result = (h2 - h1) / 60;
        }
        return parseFloat(result.toFixed(2));
    },

    worker: ko.observable(null),
    workorder: ko.observable(null),
    workorders: ko.observableArray(new Array()),
    shown_workorders: ko.observableArray(new Array()),
    areas: ko.observableArray(new Array()),
    works: ko.observableArray(new Array()),
    selected_works: ko.observableArray(new Array()),

    parent_cat_selected: ko.observable(null),
    children_cat_2_shown: ko.observableArray(new Array()),
    selected_categories: ko.observableArray(new Array()),

    selected_areas_count: function(){
        var count = 0;
        $.each( viewModel.areas(), function( i, area ) {
            if(area.selected_children_count() > 0)
                count++;
        });
        return count;
    },
    selected_works_count: function(){
        var count = 0;
        $.each( viewModel.areas(), function( i, area) {
            count += area.selected_children_count();
        });
        return count;
    },

    areas_text: function(){
        var text = "";
        $.each( viewModel.areas(), function( i, area ) {
            if(area.selected_children_count() > 0){
                if(text == "")
                    text += area.name;
                else
                    text += " - " + area.name;
            }
        });
        return text;
    },
    works_text: function(){
        var text = "";
        $.each( viewModel.areas(), function( i, area ) {
            if(area.generated_works() != ""){
                if(text == "")
                    text += area.generated_works();
                else
                    text += " - " + area.generated_works();
            }
        });
        return text;
    },

    fulllabors: function(){
        var list = $.map(this.workorders(), function(workorder) {
            return {
                id: workorder.id,
                stocks: workorder.selected_stocks().length > 0 ?
                    $.map(workorder.selected_stocks(), function(stock){
                        return {
                            id: stock.id ? stock.id : "",
                            as_no: stock.number
                        };
                    }) : new Array() };
        });

        return list;
    },
    labors2finish: function(){
        var list = $.map(this.worker().loops(), function(loop) {
            if(loop.active())
                return {id: loop.id};
        });

        return list;
    },
    labors2start: function(){
        var list = $.map(this.workorders(), function(workorder) {
            return {
                id: workorder.id,
                stocks: workorder.selected_stocks().length > 0 ?
                    $.map(workorder.selected_stocks(), function(stock){
                        return {
                            id: stock.id ? stock.id : "",
                            as_no: stock.number
                        };
                    }) : new Array() };
        });

        return list;
    },
    labors2delete: function(){
        var list = $.map(this.worker().loops(), function(loop) {
            if(!loop.active())
                return {id: loop.id};
        });

        return list;
    },

    next_stage: function(){
        switch (this.stage()){
            case 0:
                if(this.worker() != null){
                    this.stage(this.stage() + 1);
                    this.prepare_workorder_search();
                }
                break;
            case 1:
                if(this.workorder() != null || this.workorders().length > 0){
                    if(this.workorders().length == 0)
                        this.workorders.push(this.workorder());
                    $.each( viewModel.workorders(), function( i, workorder ) {
                        if(workorder.selected_stocks().length == 0){
                            viewModel.worker().loops2start.push(new loop(null, workorder.number, null, null,
                                null, null));
                        }
                    });
                    this.stage(this.stage() + 1);
                }
                break;
            case 2:
                if(this.selected_works_count() > 0){
                    this.stage(this.stage() + 2);
                    load_input_features();
                    this.date(null);
                    this.started(null);
                    this.finished(null);
                }
                break;
            case 3:
                if(this.selected_works().length > 0)
                    this.stage(this.stage() + 1);
                break;
            default:
                if(this.date() != null && this.started() != null && this.finished() != null)
                    this.save_all();
                break;
        }
        this.refresh_keyboard();
    },
    back_stage: function(){
        if(this.stage() > 0)
            this.stage(this.stage() - 1);
    },
    save_all: function(code){
        $.ajax({
            type: 'post',
            async: true,
            dataType: 'json',
            url: saveClockControllerData(),
            data: {worker_id: this.worker().id(),
                fulllabors: JSON.stringify(this.fulllabors()),
                areas_text: this.areas_text(),
                works_text: this.works_text(),
                date: this.date(),
                started: this.started(),
                finished: this.finished()},
            success: function(response) {
                //alert(response.message);
            },
            error:function() {
                alert("Error");
            }
        });
        $("#end-message").modal('show');
        setTimeout(function() {
            $("#end-message").modal('hide');
            viewModel.cancel_all();
        }, 3000);
    },

    next_shown_workorders: function(){
        if(this.workorders().length > 0){
            var ipos = this.workorders.indexOf(this.shown_workorders().last()) + 1;

            if(ipos < this.workorders().length){
                var epos = (ipos + 4) <= this.workorders().length ? (ipos + 4) : this.workorders().length;
                this.shown_workorders.removeAll();
                for(ipos; ipos < epos; ipos ++){
                    this.shown_workorders.push(this.workorders()[ipos]);
                }
            }

            this.can_go_next(this.workorders().length > 4 &&
                this.shown_workorders().length == 4 &&
                (this.workorders.indexOf(this.shown_workorders().last()) + 1) < this.workorders().length);
            this.can_go_back(this.workorders().length > 4 &&
                (this.workorders.indexOf(this.shown_workorders().first()) - 1) >= 0);
        }
    },
    back_shown_workorders: function(){
        if(this.workorders().length > 0){
            var ipos = (this.workorders.indexOf(this.shown_workorders().first()) - 5) < 0 ? 0 :
                this.workorders.indexOf(this.shown_workorders().first()) - 5;
            var epos = (ipos + 4) <= this.workorders().length ? (ipos + 4) : this.workorders().length;
            this.shown_workorders.removeAll();
            for(ipos; ipos < epos; ipos ++){
                this.shown_workorders.push(this.workorders()[ipos]);
            }

            this.can_go_next(this.workorders().length > 4 &&
                this.shown_workorders().length == 4 &&
                (this.workorders.indexOf(this.shown_workorders().last()) + 1) < this.workorders().length);
            this.can_go_back(this.workorders().length > 4 &&
                (this.workorders.indexOf(this.shown_workorders().first()) - 1) >= 0);
        }
    },
    cancel_all: function(){
        this.worker_code(null);
        this.workorder_number(null);
        this.worker(null);
        this.workorder(null);
        this.workorders.removeAll();
        this.clear_selected_areas();
        this.clear_selected_works();
        this.clear_workorders();
        this.prepare_worker_search();
        this.prepare_workorder_search();
        this.stage(0);
        this.refresh_keyboard();
    },
    clear_worker: function(){
        this.worker(null);
        this.prepare_worker_search();
        this.refresh_keyboard();
    },
    clear_selected_areas: function(){
        $.each( viewModel.areas(), function( i, area ) {
            area.deselect_my_children();
        });
    },
    clear_selected_works: function(){
        $.each( viewModel.selected_works(), function( i, val ) {
            val.selected(false);
        });

        viewModel.selected_works.removeAll();
    },
    clear_workorders: function(){
        viewModel.shown_workorders.removeAll();
        viewModel.workorders.removeAll();
    },
    get_worker: function(code){
        $.ajax({
            type: 'post',
            async: true,
            dataType: 'json',
            url: getURLWorkerByCode(),
            data: {code: code},
            success: function(response) {
                if(response.worker){
                    viewModel.worker(new worker(response.worker.id, response.worker.fullname,
                        response.worker.department, response.worker.picture, response.worker.code,
                        response.worker.pay_rate));

                    $.each( response.worker.started_loops, function( i, val ) {
                        viewModel.worker().loops.push(new loop(val.id, val.workorder, val.as_no, val.area, val.work,
                            val.started));
                    });
                }
                else
                    alert("This code is not valid. Please try again!")
            },
            error:function() {
                alert("Error");
            }
        });
    },
    get_workorder: function(number){
        $.ajax({
            type: 'post',
            async: true,
            dataType: 'json',
            url: getURLWorkOrderByNo(),
            data: {number: number},
            success: function(response) {
                if(response.workorder) {
                    viewModel.workorder(new workorder(response.workorder.id, response.workorder.number,
                        response.workorder.supervisor, response.workorder.worktype, response.workorder.picture,
                        response.workorder.client, response.workorder.equipment));
                    $.each( response.workorder.stocks, function( i, val ) {
                        viewModel.workorder().stocks.push(new stock(val.id, val.number, val.code, val.serial, val.equipment,
                            val.description, val.picture));
                    });

                    var i = 1;
                    for (i; i <= 21; i++) {
                        var temp = $.grep(viewModel.workorder().stocks(), function(s){ return s.number == i; });
                        if(temp.length == 0)
                            viewModel.workorder().stocks.push(new stock(null, i, null, null, null, null, null));
                    }
                    viewModel.workorder().stocks().sort(function(a, b){return a.number- b.number;});
                    viewModel.workorder().stocks.valueHasMutated();
                }
                else{
                    $('#no-workorder-message').modal('show');
                }
            },
            error:function() {
                alert("Error");
            }
        });
    },
    new_workorder_search: function(number){
        this.workorder(null);
        this.workorder_number(null);
        this.prepare_workorder_search();
        this.refresh_keyboard();
    },
    new_worker_search: function(number){
        this.worker(null);
        this.worker_code(null);
        this.prepare_worker_search();
        this.refresh_keyboard();
    },
    add_workorder: function(wo){
        this.workorders.push(wo);
        if(this.shown_workorders().length < 4)
            this.shown_workorders.push(wo);
        this.workorder(null);

        this.can_go_next(this.workorders().length > 4 &&
            this.shown_workorders().length == 4 &&
            (this.workorders.indexOf(this.shown_workorders().last()) + 1) < this.workorders().length);
        this.can_go_back(this.workorders().length > 4 &&
            (this.workorders.indexOf(this.shown_workorders().first()) - 1) >= 0);

        this.prepare_workorder_search();
        this.refresh_keyboard();
    },
    create_workorder: function(){
        var wo = new workorder(null, this.workorder_number(), null, null, null, null, null);
        for (var i = 1; i <= 21; i++) {
            wo.stocks.push(new stock(null, i, null, null, null, null, null));
        }
        viewModel.workorder(wo);

    },
    cancel_workorder: function(){
        viewModel.prepare_worker_search();
        viewModel.prepare_workorder_search();
    },
    add_selected_work: function(w){
        this.selected_works.push(w);
    },
    remove_selected_work: function(w){
        this.selected_works.remove(w);
    },
    remove_workorder: function(wo){
        if(wo.number == this.workorder().number)
            this.workorder(null);
        if(this.shown_workorders.indexOf(wo) != -1)
            this.shown_workorders.remove(wo);
        this.workorders.remove(wo);

        var loops2del = $.grep(this.worker().loops2start(), function(s){
            return s.workorder() == wo.number;
        });
        $.each( loops2del, function( i, loop ) {
            viewModel.worker().loops2start.remove(loop);
        });

        if(this.workorders.indexOf(this.shown_workorders().last()) < this.workorders().length - 1)
            this.shown_workorders.push(this.workorders()[this.workorders.indexOf(this.shown_workorders().last()) + 1]);

        this.workorder_number(null);

        this.can_go_next(this.workorders().length > 4 &&
            this.shown_workorders().length == 4 &&
            (this.workorders.indexOf(this.shown_workorders().last()) + 1) < this.workorders().length);
        this.can_go_back(this.workorders().length > 4 &&
            (this.workorders.indexOf(this.shown_workorders().first()) - 1) >= 0);

        this.workorder_number(null);
    },
    fill_data_support: function(){
        $.ajax({
            type: 'post',
            async: true,
            dataType: 'json',
            url: get_areas_by_level_url(),
            data: {level: 0},
            success: function(response) {
                var categories = [];
                var alength = response.areas.length < 63 ? response.areas.length : 62;
                for(var i = 0; i < alength; i++){
                    categories.push(get_full_category(response.areas[i], null));
                }
                viewModel.areas(categories);
            },
            error:function() {
                alert("Error getting level 0 work categories!!!");
            }
        });

        /*var alength = this.area_options_count < 63 ? this.area_options_count : 62;
        viewModel.areas.removeAll();
        for(var i = 0; i < alength; i++){
            this.areas.push(new area(i, stock_areas[i].name, stock_areas[i].color));
        }*/

        var wlength = this.work_options_count < 63 ? this.work_options_count : 62;
        viewModel.works.removeAll();
        for(var i = 0; i < wlength; i++){
            this.works.push(new work(i, area_works[i].name, area_works[i].color));
        }
    },
    next_shown_areas: function(){
        /*if((viewModel.areas().last().index + 1) < viewModel.area_options_count){
            var ipos = viewModel.areas().last().index + 1;
            var epos = (ipos + 62) < viewModel.area_options_count ? ipos + 61 : viewModel.area_options_count;
            viewModel.areas.removeAll();
            for(ipos; ipos < epos; ipos++){
                viewModel.areas.push(new area(ipos, stock_areas[ipos].name, stock_areas[ipos].color));
            }
        }

        $.each( viewModel.selected_areas(), function( i, area ) {
            var result = $.grep(viewModel.areas(), function(s){ return s.index == area.index; });
            if(result.length == 1)
                result[0].selected(true);
        });*/
    },
    back_shown_areas: function(){
        /*if((viewModel.areas().first().index + 1) > 0){
            var ipos = viewModel.areas().first().index <= 62 ? 0 : viewModel.areas().first().index - 61;
            var epos = viewModel.areas().first().index;
            viewModel.areas.removeAll();
            for(ipos; ipos < epos; ipos++){
                viewModel.areas.push(new area(ipos, stock_areas[ipos].name, stock_areas[ipos].color));
            }
        }
        $.each( viewModel.selected_areas(), function( i, area ) {
            var result = $.grep(viewModel.areas(), function(s){ return s.index == area.index; });
            if(result.length == 1)
                result[0].selected(true);
        });*/
    },
    next_shown_works: function(){
        if((viewModel.works().last().index + 1) < viewModel.work_options_count){
            var ipos = viewModel.works().last().index + 1;
            var epos = (ipos + 62) < viewModel.work_options_count ? ipos + 61 : viewModel.work_options_count;
            viewModel.works.removeAll();
            for(ipos; ipos < epos; ipos++){
                viewModel.works.push(new work(ipos, area_works[ipos].name, area_works[ipos].color));
            }
        }
        $.each( viewModel.selected_works(), function( i, work ) {
            var result = $.grep(viewModel.works(), function(s){ return s.index == work.index; });
            if(result.length == 1)
                result[0].selected(true);
        });
    },
    back_shown_works: function(){
        if((viewModel.works().first().index + 1) > 0){
            var ipos = viewModel.works().first().index <= 62 ? 0 : viewModel.works().first().index - 61;
            var epos = viewModel.works().first().index;
            viewModel.works.removeAll();
            for(ipos; ipos < epos; ipos++){
                viewModel.works.push(new work(ipos, area_works[ipos].name, area_works[ipos].color));
            }
        }
        $.each( viewModel.selected_works(), function( i, work ) {
            var result = $.grep(viewModel.works(), function(s){ return s.index == work.index; });
            if(result.length == 1)
                result[0].selected(true);
        });
    },
    prepare_worker_search: function(){
        $('#worker_code_input').val("");
        $('#worker_code_input').focus();
        this.worker_code(null);
    },
    prepare_workorder_search: function(){
        $('#workorder_number_input').val("");
        $('#workorder_number_input').focus();
        this.workorder_number(null);
    },
    refresh_keyboard: function(){
        $('div#workorder-virtual-Keyboard div#mlkeyboard ul li').css('font-size',$('div#workorder-virtual-Keyboard div#mlkeyboard ul li').height() - 10);
        $('div#workorder-virtual-Keyboard div#mlkeyboard ul li').css('line-height',$('div#workorder-virtual-Keyboard div#mlkeyboard ul li').height() + 2 + 'px');

        $('div#worker-virtual-Keyboard div#mlkeyboard ul li').css('font-size',$('div#worker-virtual-Keyboard div#mlkeyboard ul li').height() - 10);
        $('div#worker-virtual-Keyboard div#mlkeyboard ul li').css('line-height',$('div#worker-virtual-Keyboard div#mlkeyboard ul li').height() + 2 + 'px');
    }
};

function get_full_category(pcategory, parent){
    var children = [];
    var category = new area(pcategory.id,
                            0,
                            pcategory.code,
                            pcategory.name,
                            pcategory.description,
                            pcategory.level,
                            pcategory.active, "#5bc0de");
    category.parent(parent);
    if(pcategory.children.length > 0){
        $.each( pcategory.children, function( i, child ) {
            children.push(get_full_category(child,category));
        });
    }
    category.children(children);
    return category;
}
function load_input_features(){
    if(check_device() == 2){
        $('#input-date').datetimepicker({
            language:  'en',
            weekStart: 0,
            todayBtn:  1,
            autoclose: 1,
            todayHighlight: 1,
            startView: 2,
            minView: 2,
            forceParse: 0
        });

        $('#input-stime').datetimepicker({
            language:  'en',
            weekStart: 0,
            todayBtn:  0,
            autoclose: 1,
            todayHighlight: 1,
            startView: 1,
            minView: 0,
            forceParse: 0
        });

        $('#input-etime').datetimepicker({
            language:  'en',
            weekStart: 0,
            todayBtn:  0,
            autoclose: 1,
            todayHighlight: 1,
            startView: 1,
            minView: 0,
            forceParse: 0
        });
    }
    else{
        $('#input-date').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);});
        $('#input-stime').each(function(){var value = $(this).val();this.type="time";$(this).val(value);});
        $('#input-etime').each(function(){var value = $(this).val();this.type="time";$(this).val(value);});
    }
}