//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',
  'modules/base',
  'backgrid',
  'moment',

  

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

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            equipmentTypeId: 0,
            equipmentTypes: [],
            equipmentName: null,

            ihId: app.models.ihDataSources.get('id'),
            includeChildrens: false,
            showAbsolutes: false,

            alarmTypeId : null,
            alarms: [],
            alarmsRows: [],

            date: new moment().format('YYYY-MM-DD'),

            hasData: false,
            isLoading: false,
        },
        computeds: {
            date$: {
                deps: ['date'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    return { date: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                },
            },

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

            qp.Add('@includeInternals', 'BIT', 0);
            qp.Add('@ihId', 'INT', this.get('ihId'));

            Core.Json.CallProcedure(
                app.DatabaseNames.System + ".EQUIP.GetEquipmentTypes",
                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("equipmentTypes", 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('@isCatalog', 'BIT', 1);
            qp.Add('@ihId', 'INT', this.get('ihId'));

            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;
        }, 
        fetchAlarms: function (options) {
            var that = this,
                qp = new Core.Database.QueryParameters();

            qp.Add('@ihId', 'INT', this.get('ihId'));

            Core.Json.CallProcedure(
                app.DatabaseNames.ELT + ".CAT.GetAlarmTypes",
                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("alarms", 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;
        }, 
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'equipment-counters-report',
        id: 'equipment-counters-report',
        title: 'Equipment Counters Report',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,
        items:null,
        subviews: null,
        viewParams: null,
        searchTbx: null,
        searchItems: null,
        grids: 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.fetchEquipmentTypes();
            this.model.fetchAlarms();

            this.items = new Screen.Collections.Items();

            

            this.bindingSources = {};

            this.grids = { items: null };

            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.model, "change:equipmentTypeId", this.model_change_equipmentTypeId);
        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.autoRefresh.toid !== null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }

            this.refreshHistory(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({}, viewParams);
            if (viewParams.date)
                fixedParams.date = new moment(fixedParams.date, 'YYYYMMDD').format('YYYY-MM-DD');
            if (viewParams.equipmentTypeId)
                fixedParams.equipmentTypeId = (viewParams.equipmentTypeId != 0) ? parseInt(viewParams.equipmentTypeId, 10) : 0;
            if (viewParams.equipmentName)
                fixedParams.equipmentName = (viewParams.equipmentName == '-') ? null : viewParams.equipmentName;
            if (viewParams.includeChildrens)
                fixedParams.includeChildrens = (viewParams.includeChildrens == "TRUE") ? true : false;
            if (viewParams.alarmTypeId)
                fixedParams.alarmTypeId = (viewParams.alarmTypeId != 0) ? parseInt(viewParams.alarmTypeId, 10) : 0;

            this.model.set(fixedParams);
            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    fixedParams,
                    {}
                ),
            });
        },
        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/modules/elt/' + 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.searchTbx = that.$el.find("#searchTbx").typeaheadExtended({
                                items: Infinity,
                                minLength: 0,
                                source: _.bind(that.getSearchControlSource, that),
                                updater: function (item) {
                                    var match;
                                    try {
                                        match = that.selectItemFromSearchComboItem(item);
                                    }
                                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    finally {
                                        if (match)
                                            return match.Name;
                                        else
                                            return item;
                                    }
                                }
                            });

                            var grid = that.grids.items = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                collection: that.items,
                                footer: Backgrid.Extension.Infinator.extend({
                                    scrollToTop: false,
                                }),
                                row: Backgrid.Row.extend({
                                    events: function () {
                                        return {
                                            'click': this.click,
                                        };
                                    },
                                    click: function (e) {
                                        try {
                                            this.model.trigger('backgrid:rowclick', this.model);
                                        }
                                        catch (Error) { console.error(Error.stack); }
                                    }
                                })
                            });

                            
                            that.$el.find('.equipment-counters-report-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.date)
                                fixedParams.date = new moment(fixedParams.date, 'YYYYMMDD').format('YYYY-MM-DD');
                            if (fixedParams.equipmentTypeId)
                                fixedParams.equipmentTypeId = (fixedParams.equipmentTypeId != 0) ? parseInt(fixedParams.equipmentTypeId, 10) : 0;
                            if (fixedParams.equipmentName)
                                fixedParams.equipmentName = (fixedParams.equipmentName == '-') ? null : fixedParams.equipmentName;
                            if (fixedParams.includeChildrens)
                                fixedParams.includeChildrens = (fixedParams.includeChildrens == "TRUE") ? true : false;
                            if (fixedParams.alarmTypeId)
                                fixedParams.alarmTypeId = (fixedParams.alarmTypeId != 0) ? parseInt(fixedParams.alarmTypeId, 10) : 0;

                            that.model.set(fixedParams, {from: 'render'}); 


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

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

                            //that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        selectItemFromSearchComboItem: function (value) {
            var item = this.searchItems[value];

            if (item) {
                this.model.set('equipmentName', value);
            } else {
                this.model.set('equipmentName', value);
            }
            return item;
        },
        getSearchControlSource: function (query, process) {
            var that = this,
                opt = { params: {}, };


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



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

                            if (records) {
                                var items = [];


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

                                    if (!find) {
                                        if (obj.TypeId == that.model.get('equipmentTypeId') || that.model.get('equipmentTypeId') == 0) {
                                            var legend = obj.Name;
                                            that.searchItems[legend] = obj;
                                            items.push(legend);
                                        }
                                    }
                                    
                                });
                            }

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

        },
        model_change_equipmentTypeId: function (model, value, opt) {
            try {
                if (!opt)
                    opt = {};

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

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

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

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

                        if (!item) {
                            item = _.findWhere(this.searchItems, { 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); }
        },
        showSearchItemsBtn_click: function (e) {
            try {
                if ((this.searchItems) && (this.searchItems.length > 0))
                    this.searchTbx.typeaheadExtended('show');
                else
                    this.searchTbx.typeaheadExtended('lookup');
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        itemsChanged: function (a, b, c) {
            var fromFetch = (
                (c && c.from && c.from == "fetch") ||
                (!c && b && b.from == "fetch")
            ) ? true : false;

            if (fromFetch) {
                this._refresh({reset: true});
            }
        },
        refreshHistory: function (options) {
            var that = this;
            var attrs = this.model.toJSON();
            opt = _.extend({ params: {}, }, options );
            
            if ((opt.refresh == true) || (opt.reset == true))
                this.model.set('isLoading', true);

            this.items.fetch(_.extend(opt, 
                {   
                    params: {
                        ihId: attrs.ihId,
                    },
                    success: function (collection, records) {
                        try {

                            var showAbsolutes = that.model.get('showAbsolutes');

                            var array = [];
                            var actualRecord = null;

                            //Parse of records columns
                            rows = _.map(records.Table, function (obj) {
                                return {
                                    equipmentModelId: obj.EquipmentModelId,
                                    equipmentName: obj.EquipmentName,
                                    equipmentCurrentStatus: obj.EquipmentCurrentStatusName ,
                                    equipmentTypeName: obj.EquipmentTypeName,
                                };
                            });

                            counters = _.map(records.Table3, function (obj) {
                                return {
                                    equipmentCounterId: obj.EquipmentCounterId,
                                    equipmentCounterName: obj.EquipmentCounterName,
                                    equipmentCounterUnit: obj.EquipmentCounterUnit,
                                    equipmentCounterTypeCode: obj.EquipmentCounterTypeCode
                                }
                            });

                            alarms = _.map(records.Table4, function (obj) {
                                return {
                                    equipmentId: obj.EquipmentId,
                                    equipmentCounterId: obj.EquipmentCounterId,
                                    alarmLimit: obj.AlarmLimit,
                                    alarmLimitFormatted: obj.AlarmLimitFormatted,
                                    alarmName: obj.Name,
                                    alarmColor: obj.AlarmColor,
                                    alarmIcon: obj.AlarmIcon
                                }
                            });

                            that.model.set('alarmsRows', alarms);

                            var columns = [];
                            var columns2 = [];
                            
                            _.map(counters, function (obj) {
                                var find =  _.findWhere(columns, { name: 'counter_' + obj.equipmentCounterName });
                                if (!find  ) {
                                    columns.push({ name: 'counter_' + obj.equipmentCounterName });
                                    columns2.push({ name: 'counterAbsolute_' + obj.equipmentCounterName});
                                }
                            });

                            if (rows.length > 0) {
                                columns.push({ name: 'totalTime' });
                                columns2.push({ name: 'absolute_totalTime' });
                            }

                            that.grids.items.listenTo(that.grids.items.columns, "reset", function () {
                                if (that.grids.items.header) {
                                    that.grids.items.header = new (Backgrid.Extension.GroupedHeader.extend({
                                        columnLayout: (showAbsolutes)
                                            ? [
                                                {
                                                    name: 'equipmentName'
                                                },
                                                {
                                                    name: 'equipmentCurrentStatusName'
                                                },
                                                {
                                                    name: 'equipmentTypeName'
                                                },
                                                {
                                                    name: app.translate(that, 'campaign_col_label'),
                                                    children: columns,
                                                },
                                                {
                                                    name: app.translate(that, 'absolute_col_label'),
                                                    children: columns2,
                                                },
                                            ]
                                            : [
                                                {
                                                    name: 'equipmentName'
                                                },
                                                {
                                                    name: 'equipmentCurrentStatusName'
                                                },
                                                {
                                                    name: 'equipmentTypeName'
                                                },
                                                {
                                                    name: app.translate(that, 'campaign_col_label'),
                                                    children: columns,
                                                }
                                            ]
                                    }))(that.grids.items.header.options)
                                }

                                that.grids.items.render();
                            });

                            that.grids.items.columns.reset();

                            var column = {
                                name: 'equipmentName',
                                label: app.translate(that, 'equipment_name_column_label'),
                                cell: Backgrid.StringCell.extend({
                                    orderSeparator: '',
                                    className: 'string-cell align-center-cell equipment-name',
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'equipment-name'
                                }),
                            };

                            array.push(column);
                            that.grids.items.columns.set(column);

                            var column = {
                                name: 'equipmentTypeName',
                                label: app.translate(that, 'equipment_type_column_label'),
                                cell: Backgrid.StringCell.extend({
                                    orderSeparator: '',
                                    className: 'string-cell align-center-cell equipmentType',
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'equipment-type'
                                }),
                            };

                            array.push(column);
                            that.grids.items.columns.add(column);

                            var column = {
                                name: 'equipmentCurrentStatus',
                                label: app.translate(that, 'equipment_status_column_label'),
                                cell: Backgrid.StringCell.extend({
                                    orderSeparator: '',
                                    className: 'string-cell align-center-cell equipmentCurrentStatus',
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'equipment-status'
                                }),
                            };

                            array.push(column);
                            that.grids.items.columns.add(column);

                            _.map(counters, function (obj) {

                                var equipmentCounterTypeCode;
                                var equipmentCounterTypeCodeAbsolute;

                                switch (obj.equipmentCounterTypeCode) {
                                    case 'INTEGER': equipmentCounterTypeCode = Backgrid.IntegerCell.extend({
                                        className: 'integer-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                        render: function () {

                                            Backgrid.IntegerCell.prototype.render.apply(this, arguments);

                                            var grid = this;

                                            var alarmsFiltered = _.filter(alarms, function (alarm) { return alarm.equipmentId == grid.model.get('equipmentId') && alarm.equipmentCounterId == obj.equipmentCounterId });

                                            if (alarmsFiltered.length > 0) {
                                                alarmsFiltered = _.sortBy(alarmsFiltered, 'alarmLimit');

                                                _.map(alarmsFiltered, function (alarm) {
                                                    if (alarm.alarmLimit < grid.model.get('counter_' + obj.equipmentCounterName)) {
                                                        grid.$el.css({ background: alarm.alarmColor });

                                                        var c = alarm.alarmColor.substring(1);      // strip #
                                                        var rgb = parseInt(c, 16);   // convert rrggbb to decimal
                                                        var r = (rgb >> 16) & 0xff;  // extract red
                                                        var g = (rgb >> 8) & 0xff;  // extract green
                                                        var b = (rgb >> 0) & 0xff;  // extract blue

                                                        var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709

                                                        if (luma < 35) {
                                                            grid.$el.css({ color: '#FFFFFF' });
                                                        } else {
                                                            grid.$el.css({ color: '#000000' });
                                                        }

                                                        grid.el.setAttribute('title', app.translate([that], 'alarm_limit_reached').replace("$1", alarm.alarmName, "gi").replace("$2", alarm.alarmLimitFormatted, "gi"));

                                                    }
                                                });
                                            }

                                            return this;
                                        }
                                    });
                                    equipmentCounterTypeCodeAbsolute = Backgrid.IntegerCell.extend({
                                        className: 'integer-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                    });
                                        break;
                                    case 'REAL': equipmentCounterTypeCode = Backgrid.NumberCell.extend({
                                        className: 'number-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                        decimals: 4,
                                        render: function () {

                                            Backgrid.IntegerCell.prototype.render.apply(this, arguments);

                                            var grid = this;

                                            var alarmsFiltered = _.filter(alarms, function (alarm) { return alarm.equipmentId == grid.model.get('equipmentId') && alarm.equipmentCounterId == obj.equipmentCounterId });

                                            if (alarmsFiltered.length > 0) {
                                                alarmsFiltered = _.sortBy(alarmsFiltered, 'alarmLimit');

                                                _.map(alarmsFiltered, function (alarm) {
                                                    if (alarm.alarmLimit < grid.model.get('counter_' + obj.equipmentCounterName)) {
                                                        grid.$el.css({ background: alarm.alarmColor });

                                                        var c = alarm.alarmColor.substring(1);      // strip #
                                                        var rgb = parseInt(c, 16);   // convert rrggbb to decimal
                                                        var r = (rgb >> 16) & 0xff;  // extract red
                                                        var g = (rgb >> 8) & 0xff;  // extract green
                                                        var b = (rgb >> 0) & 0xff;  // extract blue

                                                        var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709

                                                        if (luma < 40) {
                                                            grid.$el.css({ color: '#FFFFFF' });
                                                        } else {
                                                            grid.$el.css({ color: '#000000' });
                                                        }

                                                        grid.el.setAttribute('title', app.translate([that], 'alarm_limit_reached').replace("$1", alarm.alarmName, "gi").replace("$2", alarm.alarmLimitFormatted, "gi"));

                                                    }
                                                });
                                            }

                                            return this;
                                        }
                                    });
                                    equipmentCounterTypeCodeAbsolute = Backgrid.NumberCell.extend({
                                        className: 'number-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                        decimals: 2,
                                    });
                                        break;
                                    case 'DURATION':
                                        var formatter = Backgrid.Extension.DurationFormatter.extend({
                                            displayFormat: obj.equipmentCounterUnit,
                                            modelFormat: 'm',
                                        });

                                        equipmentCounterTypeCode = Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                            formatter: formatter,
                                            render: function () {

                                                Backgrid.IntegerCell.prototype.render.apply(this, arguments);

                                                var grid = this;

                                                var alarmsFiltered = _.filter(alarms, function (alarm) { return alarm.equipmentId == grid.model.get('equipmentId') && alarm.equipmentCounterId == obj.equipmentCounterId });

                                                if (alarmsFiltered.length > 0) {
                                                    alarmsFiltered = _.sortBy(alarmsFiltered, 'alarmLimit');

                                                    _.map(alarmsFiltered, function (alarm) {
                                                        if (alarm.alarmLimit < grid.model.get('counter_' + obj.equipmentCounterName)) {
                                                            grid.$el.css({ background: alarm.alarmColor });

                                                            var c = alarm.alarmColor.substring(1);      // strip #
                                                            var rgb = parseInt(c, 16);   // convert rrggbb to decimal
                                                            var r = (rgb >> 16) & 0xff;  // extract red
                                                            var g = (rgb >> 8) & 0xff;  // extract green
                                                            var b = (rgb >> 0) & 0xff;  // extract blue

                                                            var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709

                                                            if (luma < 40) {
                                                                grid.$el.css({ color: '#FFFFFF' });
                                                            } else {
                                                                grid.$el.css({ color: '#000000' });
                                                            }

                                                            var limit = that.getSecondsToHours(alarm.alarmLimit);

                                                            grid.el.setAttribute('title', app.translate([that], 'alarm_limit_reached').replace("$1", limit, "gi"));
                                                        }
                                                    });
                                                }

                                                return this;
                                            }
                                        });
                                    equipmentCounterTypeCodeAbsolute = Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell equipment-counter-name ' + 'counter_' + obj.equipmentCounterName,
                                        formatter: formatter,
                                    });
                                        break;
                                    default: Backgrid.StringCell.extend({
                                        orderSeparator: '',
                                        className: 'string-cell align-center-cell equipment-counter-name ' + obj.equipmentCounterName,
                                    });
                                }

                                var find = _.findWhere(array, { label: obj.equipmentCounterName });
                                if (!find) {
                                    var column = {
                                        name: 'counter_' + obj.equipmentCounterName,
                                        label: obj.equipmentCounterName,
                                        cell: equipmentCounterTypeCode,
                                        cell2: equipmentCounterTypeCodeAbsolute,
                                        sortable: false,
                                        editable: false,
                                        headerCell: Backgrid.HeaderCell.extend({
                                            className: 'equipment-counter-name'
                                        }),
                                    };

                                    array.push(column);
                                    that.grids.items.columns.add(column);

                                }
                            });

                            that.grids.items.columns.add({
                                name: 'totalTime',
                                label: app.translate(that, 'total_time_column_label'),
                                cell: Backgrid.StringCell.extend({
                                    className: 'string-cell align-center-cell total-time ',
                                    formatter: Backgrid.Extension.DurationFormatter.extend({
                                        displayFormat: 'd h:m:s',
                                        modelFormat: 's',
                                    }),
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'total-time'
                                }),
                            });

                            if (showAbsolutes) {
                                _.map(array, function (obj) {
                                    if (obj.name != "equipmentName") {
                                        if (obj.name != "equipmentTypeName") {
                                            if (obj.name != "equipmentCurrentStatus") {
                                                name = obj.name.replace(/counter_/, "counterAbsolute_");
                                                var column = {
                                                    name: name,
                                                    label: obj.label,
                                                    cell: obj.cell2,
                                                    sortable: false,
                                                    editable: false,
                                                    headerCell: obj.headerCell,
                                                };

                                                array.push(column);
                                                that.grids.items.columns.add(column);
                                            }
                                        }
                                    
                                    }
                                });

                                that.grids.items.columns.add({
                                    name: 'absolute_totalTime',
                                    label: app.translate(that, 'total_time_column_label'),
                                    cell: Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell total-time ',
                                        formatter: Backgrid.Extension.DurationFormatter.extend({
                                            displayFormat: 'd h:m:s',
                                            modelFormat: 's',
                                        }),
                                    }),
                                    sortable: false,
                                    editable: false,
                                    headerCell: Backgrid.HeaderCell.extend({
                                        className: 'total-time'
                                    }),
                                });
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    params: {
                        alarmTypeId: (attrs.alarmTypeId != 0) ? attrs.alarmTypeId : null,
                        equipmentTypeId: (attrs.equipmentTypeId != 0) ? attrs.equipmentTypeId : null,
                        equipmentName: (attrs.equipmentName == null || attrs.equipmentName == '') ? null : attrs.equipmentName,
                        date: new moment(attrs.date, 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD'),
                        includeChildrens: (attrs.includeChildrens == true) ? 1 : 0,
                    },

            }));
        },
        getSecondsToHours: function (value) {

            var dur = new moment.duration(value, 'm')
            var hours = parseInt(dur.asHours(), 10);
            var minutes = dur.minutes();
            var seconds = dur.seconds();

            

            if (hours < 10)
                hours = '0' + hours;
            if (minutes < 10)
                minutes = '0' + minutes;
            if (seconds < 10)
                seconds = '0' + seconds;


             return hours + ':' + minutes + ':' + seconds;
        },
        refreshBtn_click: function (e) {
            try {
                var params = this.model.toJSON();

                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                alarmTypeId: (params.alarmTypeId != 0) ? params.alarmTypeId : 0,
                                equipmentTypeId: (params.equipmentTypeId != 0) ? params.equipmentTypeId : 0,
                                includeChildrens: (params.includeChildrens == true) ? "TRUE" : "FALSE",
                                equipmentName: (params.equipmentName == null || params.equipmentName == '') ? '-' : params.equipmentName,
                                date: new moment(params.date, 'YYYY-MM-DD').format('YYYYMMDD'),
                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );

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

                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) { }
        },
        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;
        },
    });

    (function () {
        var superRef, superProto, classRef;

        superRef = Base.Models.Base;
        superProto = superRef.prototype;

        Screen.Models.Item = classRef = superRef.extend({
            defaults: _.extend(
                {},
                superProto.defaults,
                {   
                    equipmentId: null,
                    equipmentName: null,
                    equipmentCounterName: null,
                    equipmentCounterTypeCode: null,
                    equipmentTypeName: null,

                }
            ),
            procedures: {
                get: app.DatabaseNames.ELT + '.SYSTEM.GetCountersConfiguration',
            },
            parse: function (obj) {
                return {
                    equipmentId: obj.EquipmentId,
                    equipmentName: obj.EquipmentName,
                    equipmentCounterName: 'counter_' + obj.EquipmentCounterName,
                    equipmentCounterTypeCode: obj.EquipmentCounterTypeCode,
                    equipmentTypeName: obj.EquipmentTypeName,
                };
            }
        });
    })();

    (function () {
        var superRef, superProto, classRef;

        superRef = Base.Collections.Base;
        superProto = superRef.prototype;

        Screen.Collections.Items = classRef = superRef.extend({
            model: Screen.Models.Item,
            pageSize: 50, 
            idAttribute: 'equipmentId',
            parseResponse: function (resp, opt) {
                if ((resp) && (resp.Table) && (resp.Table1) && (resp.Table2) && (resp.Table3)) {
                    var that = this;
                    var records = resp.Table,
                        newColl;

                    var config = resp.Table1,
                        times = resp.Table2,
                        counters = resp.Table3;

                    var data = {
                        equipmentModelId: null,
                        equipmentId: null,
                        equipmentName: null,
                        equipmentTypeName: null,
                        equipmentCurrentStatus: null,
                        totalTime: null,
                        absolute_totalTime: null,
                    };

                    var columns = [];
                    var newData = [];
                    _.map(counters, function (obj) {
                        var table = _.findWhere(counters, { EquipmentCounterName: obj.EquipmentCounterName });
                        if (table) {
                            var find = _.findWhere(columns, { column: 'counter_' + table.EquipmentCounterName });
                            if (!find) {
                                columns.push({ column: 'counter_' + table.EquipmentCounterName }, { column: 'counterAbsolute_' + table.EquipmentCounterName });
                                data['counter_' + table.EquipmentCounterName] = null;
                                data['counterAbsolute_' + table.EquipmentCounterName] = null;
                            }
                        }
                    });
                    
                    _.map(records, function (obj) {
                        var values = [];
                        values = _.where(config, { EquipmentId: obj.EquipmentId, EquipmentCounterId: obj.EquipmentCounterId });

                        var timingValues = [];
                        timingValues = _.where(times, { EquipmentId: obj.EquipmentId });

                        var absolute = [];
                        absolute = _.where(config, { EquipmentId: obj.EquipmentId, EquipmentCounterId: obj.EquipmentCounterId });

                        var keys = Object.keys(data);

                        var object = {
                            equipmentModelId: null,
                            equipmentId: null,
                            equipmentName: null,
                            equipmentTypeName: null,
                            equipmentCurrentStatus: null,
                            totalTime: null,
                            absolute_totalTime: null,
                        };
                        var find = _.findWhere(newData, { equipmentId: obj.EquipmentId });
                        if (!find) {
                            _.each(keys, function (key) {
                                switch (key) {
                                    case 'counter_' + obj.EquipmentCounterName:
                                        value = _.last(values);
                                        (value) ? object[key] = value.TotalValue : object[key] = null;
                                        //object[key] = null;
                                        break;
                                    case 'counterAbsolute_' + obj.EquipmentCounterName :
                                        value = _.last(absolute);
                                        (value) ? object[key] = value.AbsoluteTotalValue : object[key] = null;
                                        break;
                                    case 'equipmentModelId': object[key] = obj.EquipmentModelId;
                                        break;
                                    case 'equipmentId': object[key] = obj.EquipmentId;
                                        break;
                                    case 'equipmentName': object[key] = obj.EquipmentName;
                                        break;
                                    case 'equipmentTypeName': object[key] = obj.EquipmentTypeName;
                                        break;
                                    case 'equipmentCurrentStatus': object[key] = (obj.EquipmentCurrentStatusName) ? app.translate([app, this], obj.EquipmentCurrentStatusName + '_label') : null;
                                        break;
                                    case 'totalTime':
                                        value = _.last(timingValues);
                                        (value) ? object[key] = value.PartialTime : object[key] = null;
                                        
                                        break;
                                    case 'absolute_totalTime':
                                        value = _.last(timingValues);
                                        (value) ? object[key] = value.TotalTime : object[key] = null;
                                        break;
                                    default:
                                        if (key.indexOf('counter_') != -1) {
                                            if (_.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                singleConfig = _.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() });

                                                value = _.last(_.where(config, { EquipmentId: obj.EquipmentId, EquipmentCounterId: singleConfig.EquipmentCounterId }));
                                                (value) ? object[key] = value.TotalValue : object[key] = null;
                                                //object[key] = null;
                                            }
                                        } else if (key.indexOf('counterType_') != -1) {
                                            if (objAux = _.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                (value) ? object[key] = objAux.EquipmentCounterType : object[key] = null;
                                            }
                                        } else if (key.indexOf('counterAbsolute_') != -1) {
                                            if (_.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                singleConfig = _.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() });

                                                value = _.last(_.where(config, { EquipmentId: obj.EquipmentId, EquipmentCounterId: singleConfig.EquipmentCounterId }));
                                                (value) ? object[key] = value.AbsoluteTotalValue : object[key] = null;
                                            }
                                        }
                                }
                            });
                            newData.push(object);
                        }
                        //else {
                        //    for (i in newData) {
                        //        if (newData[i].equipmentId == find.equipmentId){
                        //            _.each(keys, function (key) {
                        //                switch (key) {
                        //                    case 'counter_' + obj.EquipmentCounterName:
                        //                        value = _.last(values);
                        //                        if (value) {
                        //                            if (newData[i][key] == null)
                        //                                newData[i][key] = value.TotalValue;
                        //                                //newData[i][key] = null;
                        //                        } else {
                        //                            newData[i][key] = null;
                        //                        }
                                                

                        //                        break;
                        //                    case 'counterAbsolute_' + obj.EquipmentCounterName:
                        //                        value = _.last(absolute);
                        //                        (value) ? newData[i][key] = value.AbsoluteTotalValue : newData[i][key] = null;
                        //                        break;
                        //                    case 'equipmentModelId': object[key] = obj.EquipmentModelId;
                        //                        break;
                        //                    case 'equipmentId': newData[i][key] = obj.EquipmentId;
                        //                        break;
                        //                    case 'equipmentName': newData[i][key] = obj.EquipmentName;
                        //                        break;
                        //                    case 'equipmentTypeName': newData[i][key] = obj.EquipmentTypeName;
                        //                        break;
                        //                    case 'equipmentCurrentStatus': newData[i][key] = (obj.EquipmentCurrentStatusName) ? app.translate([app, this], obj.EquipmentCurrentStatusName + '_label') : null;
                        //                        break;

                        //                    default: if (find[key] == null)
                        //                                newData[i][key] = null;
                        //                }
                        //            });
                        //        }
                        //     }
                        // }
                         
                    }); 


                    
                    var method = ((opt.refresh) || ((opt.reset))) ? 'set' : 'add';
                    //var method = 'set';
                    this[method](newData, { from: 'fetch' });

                    return true;
                }

                return false;
            },
        });
    })();

       

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