//SCREEN-BOILERPLATE

//this boilerplate builds screens that are gonna be shown in the <div class='content'> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

define([
  // Application variable, always include it to have access to app methods.
  'app',

  //templates-loader: this loads templates async.
  'js/templates-loader',
  'backgrid',
  'moment',

  'modules/equipment-log',

  'backgrid/computed-cell',
  'backgrid/duration-cell',
  'backgrid/infinator',
  'backgrid/moment-cell',
  'js/backgrid-0.3.5/extensions/valid-limit-cell/backgrid-valid-limit-cell',
  'js/typeahead.extended/typeahead.extended'
],
function (app, T, Backgrid, moment, EquipmentLog) {

    var Screen = { Models: {}, Views: {}, Collections: {} }

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            start: new moment().format('YYYY-MM-DD'),
            end: new moment().add(1, 'days').format('YYYY-MM-DD'),

            shifts: [],
            shiftId: null,

            crews: [],
            crewId: null,

            status: [],
            statusCode: null,

            equipmentName: null,
            userName: null,

            commentSearch: null,

            hasData: false,
            isLoading: false,
        },
        computeds: {
            start$: {
                deps: ['start'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    return { start: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                },
            },
            end$: {
                deps: ['end'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    return { end: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                },
            },
        },
        fetchShifts: function () {
            var that = this,
                qp = new Core.Database.QueryParameters();

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + ".Delays.GetShifts",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;

                                var newItems = _.map(records, function (obj) {
                                    return { value: obj.Id, label: obj.Name, };
                                });

                                that.set("shifts", newItems);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        fetchCrews: function () {
            var that = this,
                qp = new Core.Database.QueryParameters();

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + ".SYSTEM.GetCrews",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;

                                var newItems = _.map(records, function (obj) {
                                    return { value: obj.Id, label: obj.Id, };
                                });

                                that.set("crews", newItems);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        fetchEquipmentLogsStatus: function () {
            var that = this,
                qp = new Core.Database.QueryParameters();

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + ".CAT.GetEquipmentLogsStatus",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;

                                var newItems = _.map(records, function (obj) {
                                    return { value: obj.Code, label: obj.Name, };
                                });

                                that.set("status", newItems);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        fetchEquipments: function (options) {
            var that = this,
                qp = null;

            var opt = _.extend(
                { error: function () { }, success: function () { }, },
                options
            );

            if (opt.params) {
                //Check if params is a query parameters instance or not.
                if (opt.params.GetQueryParameter) {
                    qp = opt.params;
                }
                else {
                    qp = new QueryParameters();

                    for (var pname in opt.params)
                        qp.Add(pname, 'VARCHAR', opt.params[pname]);
                }
            }

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.System + ".EQUIP.GetEquipments",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;
                                opt.success(records);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },

                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        fetchUsers: function (options) {
            var that = this,
                qp = null;

            var opt = _.extend(
                { error: function () { }, success: function () { }, },
                options
            );

            if (opt.params) {
                //Check if params is a query parameters instance or not.
                if (opt.params.GetQueryParameter) {
                    qp = opt.params;
                }
                else {
                    qp = new QueryParameters();

                    for (var pname in opt.params)
                        qp.Add(pname, 'VARCHAR', opt.params[pname]);
                }
            }

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + ".CAT.GetUsers",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;
                                opt.success(records);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },

                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'equipment-logs-report',
        id: 'equipment-logs-report',
        title: 'Equipment Logs Report',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                "click .btn-export-to-excel": this.exportToExcel,
                'keypress #searchEquipmentsTbx': this.searchEquipmentsTbx_keypress,
                'keypress #searchUsersTbx': this.searchUsersTbx_keypress,
                'click #showSearchEquipmentsBtn': this.showSearchEquipmentsBtn_click,
                'click #showSearchUsersBtn': this.showSearchUsersBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,

        searchEquipmentsTbx: null,
        searchUsersTbx: null,

        searchEquipmentsItems: null,
        searchUsersItems: null,

        viewParams: null,

        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            var that = this;

            if (!this.model)
                this.model = new Screen.Models.Main();

            this.model.fetchCrews();
            this.model.fetchShifts();
            this.model.fetchEquipmentLogsStatus();

            this.equipmentLogs = new (EquipmentLog.Collections.EquipmentLogs.extend({ pageSize: 30, }))();

            this.bindingSources = {};

            this.subviews = {};
            this.autoRefresh = {
                enabled: null
                , toid: null
                , every: 5 * 1000
            };

            this.bindEvents();
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            //this.listenTo(this.processes, 'backgrid:rowclick', this.processes_backgrid_rowclick);
            //this.listenTo(this.model, 'change:start change:end', this.model_change_pickers);
            this.listenTo(this.model, "change:crewId change:shiftId change:crewId change:statusCode", this.model_change_combo_filters);
        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }

            this.refreshLogs(opt);

            if (this.autoRefresh.enabled == true) {
                var that = this;

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (viewParams) {
            var fixedParams = _.extend({}, Screen.Models.Main.prototype.defaults, viewParams);

            if (viewParams.start)
                fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
            if (viewParams.end)
                fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');
            if (viewParams.shiftId)
                fixedParams.shiftId = (viewParams.shiftId != 0) ? parseInt(viewParams.shiftId, 10) : null;
            if (viewParams.crewId)
                fixedParams.crewId = (viewParams.crewId != '-') ? viewParams.crewId : null;
            if (viewParams.equipmentName)
                fixedParams.equipmentName = (viewParams.equipmentName != '-') ? viewParams.equipmentName : null;
            if (viewParams.userName)
                fixedParams.userName = (viewParams.userName != '-') ? viewParams.userName : null;
            if (viewParams.commentSearch)
                fixedParams.commentSearch = (viewParams.commentSearch != '-') ? viewParams.commentSearch : null;
            if (viewParams.statusCode)
                fixedParams.statusCode = (viewParams.statusCode != '-') ? viewParams.statusCode : null;

            this.model.set(fixedParams);

            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    fixedParams,
                    {}
                ),
                showLoading: true,
            });
        },
        render: function (container, viewParams) {
            var that = this;

            this.viewParams = viewParams;

            var thatContainer = (this.options.container) ? this.options.container : container;
            this.options.container = thatContainer;

            //the screens have a custompath, so it has to be specified in the customPath variable that is
            //then sent to the template loader.
            var customPath = '/app/custom-screens/' + this.template + '/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    if (!that.options.i18n) that.options.i18n = {};

                    app.getI18NJed(
                        that,
                        that.template,
                        function (i18nJED) {
                            //storing internationalization data
                            that.options.i18n[that.template] = i18nJED;

                            //loading the view and appeding it to the views's $el.
                            that.$el.html(tmp());

                            that.applyBindings();

                            //start: the view was already loaded an is on a div element, but not appended to the main container
                            //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                            //or this.$('#id')

                            that.$el.find('.input-date').datepicker();

                            that.searchEquipmentsTbx = that.$el.find("#searchEquipmentsTbx").typeaheadExtended({
                                items: Infinity,
                                minLength: 3,
                                source: _.bind(that.getSearchEquipments, that),
                                updater: function (item) {
                                    var match;
                                    try {
                                        match = that.selectItemFromSearchComboEquipments(item);
                                    }
                                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    finally {
                                        if (match)
                                            return match.Name;
                                        else
                                            return item;
                                    }
                                }
                            });

                            that.searchUsersTbx = that.$el.find("#searchUsersTbx").typeaheadExtended({
                                items: Infinity,
                                minLength: 3,
                                source: _.bind(that.getSearchUsers, that),
                                updater: function (item) {
                                    var match;
                                    try {
                                        match = that.selectItemFromSearchComboUsers(item);
                                    }
                                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    finally {
                                        if (match)
                                            return match.Name;
                                        else
                                            return item;
                                    }
                                }
                            });
                            
                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [
                                    {
                                        name: 'timestamp',
                                        label: app.translate([that, app], 'timestamp_col'),
                                        sortable: false, 
                                        cell: Backgrid.Extension.MomentCell.extend({
                                            className: 'momment-cell align-center-cell timestamp',
                                            modelFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
                                            displayFormat: app.translate([that, app], 'MM/DD/YYYY') + ' HH:mm',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'shift',
                                        sortable: false, 
                                        label: app.translate([that, app], 'shift_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell shift',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'crew',
                                        label: app.translate([that, app], 'crew_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell crew',
                                        }),
                                        editable: false,
                                        sortable: false, 
                                    },
                                    {
                                        name: 'user',
                                        label: app.translate([that, app], 'user_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell user',
                                        }),
                                        editable: false,
                                        sortable: false, 
                                    },
                                    {
                                        name: 'equipment',
                                        label: app.translate([that, app], 'equipment_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell equipment',
                                        }),
                                        editable: false,
                                        sortable: false, 
                                    },
                                    {
                                        name: 'comment',
                                        label: app.translate([that, app], 'comments_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell comment',
                                        }),
                                        editable: false,
                                        sortable: false, 
                                    },
                                    {
                                        name: 'status',
                                        label: app.translate([that, app], 'status_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell status',
                                        }),
                                        editable: false,
                                        sortable: false, 
                                    },
                                    {
                                        name: 'actions',
                                        label: app.translate([that, app], 'actions_col'),
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.Cell.extend({
                                            template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                            className: 'actions-cell actions',
                                            events: {
                                                'click .btn-cell-action': 'cellActionClick'
                                            },

                                            initialize: function () {
                                                Backgrid.Cell.prototype.initialize.apply(this, arguments);

                                                this.bindEvents();
                                            },
                                            render: function () {
                                                this.$el.html(this.template());

                                                this.$el.find('[data-toggle="tooltip"]').tooltip();

                                                this.delegateEvents();
                                                return this;
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change:isNew', this.checkMode);
                                            },

                                            cellActionClick: function (e) {
                                                try {
                                                    var target = $(e.target);
                                                    var actionData = target.closest('[data-cell-action]').data('cell-action');
                                                    if (actionData) {
                                                        that.actionOnRow(this.model, actionData);
                                                    }
                                                }
                                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                            },
                                        }),
                                    },
                                ],
                                collection: that.equipmentLogs,
                                footer: Backgrid.Extension.Infinator.extend({
                                    scrollToTop: false,
                                }),
                            });
                            that.$el.find('.equipment-logs-grid-container').append(grid.render().el);


                            //appending view to the main container
                            that.append(thatContainer, that.$el);


                            //Set model with view params here to prevent changes on the model when the view bindings are applied.
                            var fixedParams = _.extend({}, viewParams);

                            if (fixedParams.start)
                                fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');

                            if (fixedParams.end)
                                fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');

                            if (fixedParams.shiftId)
                                fixedParams.shiftId = (fixedParams.shiftId != 0) ? parseInt(fixedParams.shiftId, 10) : null;

                            if (fixedParams.crewId)
                                fixedParams.crewId = (fixedParams.crewId != '-') ? fixedParams.crewId : null;

                            if (fixedParams.equipmentName)
                                fixedParams.equipmentName = (fixedParams.equipmentName != '-') ? fixedParams.equipmentName : null;

                            if (fixedParams.userName)
                                fixedParams.userName = (fixedParams.userName != '-') ? fixedParams.userName : null;

                            if (fixedParams.commentSearch)
                                fixedParams.commentSearch = (fixedParams.commentSearch != '-') ? fixedParams.commentSearch : null;

                            if (fixedParams.statusCode)
                                fixedParams.statusCode = (fixedParams.statusCode != '-') ? fixedParams.statusCode : null;


                            that.model.set(fixedParams);

                            //Call first refresh.
                            var params = that.model.toJSON();

                            that._refresh({
                                reset: true,
                                params: _.extend(
                                    {},
                                    params,
                                    {
                                    }
                                ),
                                showLoading:true,
                            });

                            //that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        getSearchEquipments: function (query, process) {
            var that = this,
                opt = { params: {}, };


            if (query)
                opt.params.search = query;


            that.model.fetchEquipments(_.extend(
                opt,
                {
                    success: function (records) {
                        try {
                            that.searchEquipmentsItems = {};

                            if (records) {
                                var items = [];


                                _.each(records, function (obj) {
                                    var find = _.findWhere(items, obj.Name);

                                    if (!find) {
                                            var legend = obj.Name;
                                        that.searchEquipmentsItems[legend] = obj;
                                            items.push(legend);
                                    }
                                });
                            }

                            process(items);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                }
            ));

        },

        getSearchUsers: function (query, process) {
            var that = this,
                opt = { params: {}, };


            if (query)
                opt.params.search = query;


            that.model.fetchUsers(_.extend(
                opt,
                {
                    success: function (records) {
                        try {
                            that.searchUsersItems = {};

                            if (records) {
                                var items = [];


                                _.each(records, function (obj) {
                                    var find = _.findWhere(items, obj.FullName);

                                    if (!find) {
                                        var legend = obj.FullName;
                                        that.searchUsersItems[legend] = obj;
                                        items.push(legend);
                                    }
                                });
                            }

                            process(items);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                }
            ));

        },
        selectItemFromSearchComboEquipments: function (value) {
            var item = this.searchEquipmentsItems[value];

            if (item) {
                this.model.set('equipmentName', value);
            } else {
                this.model.set('equipmentName', value);
            }
            return item;
        },
        selectItemFromSearchComboUsers: function (value) {
            var item = this.searchUsersItems[value];

            if (item) {
                this.model.set('userName', value);
            } else {
                this.model.set('userName', value);
            }
            return item;
        },
        model_change_combo_filters: function (model, value, opt) {
            try {
                if (!opt)
                    opt = {};

                if (opt.from != 'render') {
                    this.model.set({ equipmentName: null });
                    this.model.set({ userName: null });
                }

            } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        searchEquipmentsTbx_keypress: function (e) {
            try {
                var keyCode = e.which || e.keyCode;

                if (keyCode == 13) {
                    var search = this.model.get('equipmentName');

                    if (search) {
                        var item = this.selectItemFromSearchComboEquipments(search);

                        if (!item) {
                            item = _.findWhere(this.searchEquipmentsItems, { Name: search, });

                            if (item) {

                                this.model.set('equipmentName', search);
                            }
                            else {
                                this.model.set('equipmentName', search);
                            }
                        }
                    }
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        searchUsersTbx_keypress: function (e) {
            try {
                var keyCode = e.which || e.keyCode;

                if (keyCode == 13) {
                    var search = this.model.get('userName');

                    if (search) {
                        var item = this.selectItemFromSearchComboUsers(search);

                        if (!item) {
                            item = _.findWhere(this.searchUsersItems, { Name: search, });

                            if (item) {

                                this.model.set('userName', search);
                            }
                            else {
                                this.model.set('userName', search);
                            }
                        }
                    }
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },

        showSearchEquipmentsBtn_click: function (e) {
            try {
                if ((this.searchEquipmentsItems) && (this.searchEquipmentsItems.length > 0))
                    this.searchEquipmentsTbx.typeaheadExtended('show');
                else
                    this.searchEquipmentsTbx.typeaheadExtended('lookup');
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        showSearchUsersBtn_click: function (e) {
            try {
                if ((this.searchUsersItems) && (this.searchUsersItems.length > 0))
                    this.searchUsersTbx.typeaheadExtended('show');
                else
                    this.searchUsersTbx.typeaheadExtended('lookup');
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        refreshLogs: function (options) {
            var that = this;

            var attrs = this.model.toJSON(),
                opt = _.extend({}, options, { params: {}, });

            var fetched = false;

            if (opt && opt.showLoading) {
                setTimeout(function () {
                    if (!fetched) that.showLoading(true);
                }, 500);
            }

            this.equipmentLogs.fetch(_.extend(opt, {
                params: {
                    
                    start: attrs.start,
                    end: new moment(attrs.end, 'YYYY-MM-DD').add('days', 1).format('YYYY-MM-DD'),
                    shift: (attrs.shiftId != 0) ? attrs.shiftId : null,
                    crew: (attrs.crewId != '-' && attrs.crewId != '') ? attrs.crewId : null,
                    equipment: (attrs.equipmentName != '' && attrs.equipmentName != '-') ? attrs.equipmentName : null,
                    user: (attrs.userName != '' && attrs.userName != '-') ? attrs.userName : null,
                    comment: (attrs.commentSearch != '' && attrs.commentSearch != '-') ? attrs.commentSearch : null,
                    status: (attrs.statusCode != '' && attrs.statusCode != '-') ? attrs.statusCode : null,

                },
                success: function () {
                    fetched = true;
                    that.showLoading(false);
                },
            }));
        },
        exportToExcel: function () {
            var that = this,
                start = that.model.get('start'),
                end = that.model.get('end');
            this.setExportButtonExporting(true);


            var params = [
                { Name: '@fromRow', Type: 'INT', Value: -1 },
                { Name: '@toRow', Type: 'INT', Value: -1 },
                { Name: '@start', Type: 'DATETIME', Value: start, },
                { Name: '@end', Type: 'DATETIME', Value: end, },
                { Name: '@shift', Type: 'INT', Value: (that.model.get('shiftId') == 0 ) ? null : that.model.get('shiftId') },
                { Name: '@crew', Type: 'VARCHAR', Value: (that.model.get('crewId') == '' || that.model.get('crewId') == '-') ? null : that.model.get('crewId') },
                { Name: '@equipment', Type: 'VARCHAR', Value: that.model.get('equipmentName') },
                { Name: '@user', Type: 'VARCHAR', Value: that.model.get('userName') },
                { Name: '@comment', Type: 'VARCHAR', Value: that.model.get('commentSearch') },
                { Name: '@status', Type: 'VARCHAR', Value: (that.model.get('statusCode') == '' || that.model.get('statusCode') == '-') ? null : that.model.get('statusCode') },
                { Name: '@timezoneCode', Type: 'VARCHAR', Value: app.models.user.get("timezoneCode"), },
            ];

            var QP = new QueryParameters();

            _.each(params, function (qpParams) {
                QP.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });


            var data = {
                Data: [],
                ConnectionStringName: 'APP',
                FileName: 'Equipment-Logs',
                TemplateFileFullPath: 'generic.xls',
                SQLDataSources: [
                    {
                        Name: 'data',
                        DatabaseParameters: {
                            DBEngine: 'SQLSERVER',
                            Procedure: app.DatabaseNames.MES + '.EQUIP.GetEquipmentLogs',
                            QueryParameters: QP,
                        },
                    },
                ]
            },
                chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                chari = 0;

            data.Data.push({
                SheetName: 'Data',
                RowsData: [{
                    CellsData: 
                        [
                            { Column: chars[chari++], Value: 'Timestamp' },
                            { Column: chars[chari++], Value: 'Shift' },
                            { Column: chars[chari++], Value: 'Crew' },
                            { Column: chars[chari++], Value: 'User' },
                            { Column: chars[chari++], Value: 'Equipment' },
                            { Column: chars[chari++], Value: 'Comments' },
                            { Column: chars[chari++], Value: 'Status' },
                        ],
                }],
                StartRowIndex: 1,
            });

            chari = 0;

            data.Data.push({
                SheetName: 'Data',
                RowsData: [],
                StartRowIndex: 2,
                DataSourceName: 'data',
                DataSourceTableIndex: 0,
                SQLCellsData: 
                    [
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Timestamp', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Shift', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Crew', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'User', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Equipment', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Comment', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Status', DataType: 'String' },
                    ],
            });

            Core.Export.Excel(
                data,
                function (resp) {
                    try {
                        if ((resp) && (resp.Success == true) && (resp.Data)) {
                            location.href = app.foldersRoot + '/excel/' + resp.Data;
                        }
                        else {
                            if ((resp) && (resp.Message))
                                console.error(resp.Message);
                            else
                                console.error('Server response not valid.');
                        }
                    }
                    catch (Error) { console.error(Error); }
                    that.setExportButtonExporting(false);
                },
                function (resp) {
                    that.setExportButtonExporting(false);
                    console.error(resp);
                }
            );
        },
        setExportButtonExporting: function (val) {
            var btn_export = this.$el.find('.btn-export-to-excel');
            var export_state = btn_export.find('.excel-export-state');
            var loading_state = btn_export.find('.loading-state');

            if (val) {
                export_state.css('display', 'none', 'important');
                loading_state.removeClass('hide');

                btn_export.attr('disabled', true);
            } else {
                loading_state.addClass('hide');
                export_state.css('display', 'inline-block', 'important');

                btn_export.attr('disabled', false);
            }
        },
        showLoading: function (val) {
            var loadingPoster = this.$el.find(".loading-poster");
            var gridContainer = this.$el.find(".equipment-logs-grid-container");

            if (val) {
                gridContainer.addClass("hide");
                loadingPoster.removeClass("hide");
            } else {
                loadingPoster.addClass("hide");
                gridContainer.removeClass("hide");
            }
        },
        refreshBtn_click: function (e) {
            try {
                var params = this.model.toJSON();

                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                                shiftId: (params.shiftId != null) ? params.shiftId : 0,
                                crewId: (params.crewId == null || params.crewId == '') ? '-' : params.crewId ,
                                equipmentName: (params.equipmentName == null || params.equipmentName == '') ? '-' : params.equipmentName ,
                                userName: (params.userName == null || params.userName == '') ? '-' : params.userName,
                                commentSearch: (params.commentSearch == null || params.commentSearch == '') ? '-' : params.commentSearch,
                                statusCode: (params.statusCode == null || params.statusCode == '') ? '-' : params.statusCode,
                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );

                this._refresh({
                    reset: true,
                    params: _.extend(
                        {},
                        params,
                        {}
                    ),
                    showLoading:true,
                });

                window.scrollTo(0, 0);
            }
            catch (Error) { console.error(Error.stack); }
        },

        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            if (this.options.state == app.view_states.loading
                || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                this.options.state = app.view_states.shown;
                container.append(el);

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindViewScopedEvents: function () {
            var that = this;
        },
        unbindViewScopedEvents: function () {

        },
        close: function () {
            this.options.state = app.view_states.closed;

            this.stopAutoRefresh();

            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        },
        closeSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.close();
            });
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.showSubviews();
            this.bindEvents();
            this.$el.show();
        },
        showSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.show();
            });
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.hideSubviews();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        hideSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.hide();
            });
        },
        preRender: function () {
            app.models.subnavbar.set("subnavbar", false);
        },
        reRender: function (viewParams) {
            try {
                this.refresh(viewParams);
            } catch (Error) { }
        },
        actionOnRow: function (model, action) {
            try {
                switch (action.toUpperCase()) {
                    case 'EDIT_DETAILS':
                        try {
                            app.router.navigate(
                                app.router.resolveURL(
                                    'equipment-logs',
                                    {   
                                        mode: 'edit',
                                        id: model.get('id'),
                                    },
                                    false
                                ),
                                { trigger: true, }
                            );
                        }
                        catch (Error) { console.error(Error.stack); }
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        startAutoRefresh: function () {
            try {
                if (this.autoRefresh.enabled !== true) {
                    var that = this;

                    if (this.autoRefresh.toid != null) {
                        clearTimeout(this.autoRefresh.toid);
                        this.autoRefresh.toid = null;
                    }

                    this.autoRefresh.enabled = true;

                    //use a timeout to execute the first refresh to return the handle to the start function caller.
                    //So when the caller finish it will do the first refresh.
                    this.autoRefresh.toid = setTimeout(
                        function () { that._refresh(); },
                        1
                    );
                }
            } catch (Error) { console.error(Error.stack); }
        },
        stopAutoRefresh: function () {
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }
            this.autoRefresh.enabled = false;
        },
    });

    // Required, return the module for AMD compliance.
    return Screen;
});