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

    "js/jstree/jstree",
  "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, Modal, Base, Backgrid, moment) {

    var TREE_NODE_ROOT_ID = -1;

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

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

            ihId: app.models.ihDataSources.get('id'),
            locations: [],

            alarms: [],
            alarmsRows: [],

            includeChildrens: false,
            showAbsolutes: false,
            //date: new moment().format('YYYY-MM-DD'),

            hasData: false,
            isLoading: false,
        },
        computeds: {
        },
        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;
        },
        fetchEquipmentStatus: function () {
            var that = this,
                qp = new Core.Database.QueryParameters();

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

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

                                var newItems = _.map(records, function (obj) {
                                    return { value: obj.Code, label: app.translate([app, this], obj.Code + '_label'), };
                                });

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

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

            Core.Json.CallProcedure(
                app.DatabaseNames.System + ".EQUIP.GetEquipmentLocations",
                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("locations", 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;
        },
        changeEquipment: function (ihId, props, success, error) {
            var that = this;
            var QP = new QueryParameters();
            //QP.Add("Id", "INT", id);

            //QP.Add("ihId", "INT", ihId);

            for (var q in props) {
                QP.Add(props[q].name, props[q].type, props[q].value);
            }

            Core.Json.CallProcedure(app.DatabaseNames.System + ".EQUIP.ChangeEquipmentByName", QP, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var data = data.Table;
                        //var ids = [];

                        if (data && data.length > 0 && data[0].Status && data[0].Status == "FAILURE") {
                            var failureCode = "UNKNOWN";
                            failureCode = (data[0].Code) ? data[0].Code : failureCode;

                            if (error != null && _.isFunction(error))
                                error.call(this, that, failureCode);
                        } else {
                            ////ids = _.pluck(data, 'Id');

                            ////if (success != null && _.isFunction(success))
                            ////    success.call(this, that, ids);

                            //var itemData = data[0];

                            //var item = {
                            //    id: itemData.Id,
                            //    parent: ((itemData.ParentId != null) && (itemData.ParentId != -1))
                            //        ? itemData.ParentId
                            //        : TREE_NODE_ROOT_ID,
                            //    type: itemData.TypeName,//.toLowerCase(),
                            //    text: itemData.Name,
                            //    order: itemData.Order - 1,
                            //    deleted: itemData.Deleted,
                            //    enabled: !itemData.Deleted,
                            //    data: {
                            //        enabled: !itemData.Deleted,
                            //    }
                            //};

                            if (success != null && _.isFunction(success))
                                success.call(this, that, data[0]);
                        }
                    } else {
                        var message;
                        if (data.Message)
                            message = data.Message;
                        else
                            message = 'CAN_NOT_MOVE_EQUIPMENT';


                        error.call(this, that, message);
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'equipment-campaigns',
        id: 'equipment-campaigns',
        title: 'Equipment Campaigns',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,
        currentModal: null,
        grids: null,
        items:null,
        subviews: null,
        viewParams: null,
        searchTbx: null,
        searchItems: null,
        templates: null,

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

            var that = this;

            this.templates = {
                newCampaignModal: null,
                changeEquipmentModal: null,
            };

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

            this.model.fetchEquipmentTypes();
            this.model.fetchEquipmentStatus();
            this.model.fetchLocations();

            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.refreshItems(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.equipmentTypeId)
                fixedParams.equipmentTypeId = (viewParams.equipmentTypeId != 0) ? parseInt(viewParams.equipmentTypeId, 10) : 0;
            if (viewParams.equipmentStatusCode)
                fixedParams.equipmentStatusCode = (viewParams.equipmentStatusCode.toLowerCase() == '-') ? null : viewParams.equipmentStatusCode;
            if (viewParams.equipmentName) {
                fixedParams.equipmentName = (viewParams.equipmentName == '-') ? null : viewParams.equipmentName;
            }
            if (viewParams.includeChildrens)
                fixedParams.includeChildrens = (viewParams.includeChildrens == "TRUE") ? true : false;
        
            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.templates.newCampaignModal = Handlebars.compile(that.$el.find('#new_campaign_modal_template').html());

                            that.templates.changeEquipmentModal = Handlebars.compile(that.$el.find('#change_equipment_modal_template').html());

                            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',
                                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-campaigns-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.equipmentStatusCode)
                                fixedParams.equipmentStatusCode = (fixedParams.equipmentStatusCode.toLowerCase() == '-') ? null : fixedParams.equipmentStatusCode;
                            if (fixedParams.equipmentName)
                                fixedParams.equipmentName = (fixedParams.equipmentName == '-') ? null : fixedParams.equipmentName;
                            if (fixedParams.includeChildrens)
                                fixedParams.includeChildrens = (fixedParams.includeChildrens == "TRUE") ? true : false;

                            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;
                                        	if (items.indexOf(legend) == -1) {
                                            	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});
            }
        },
        refreshItems: 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,
                        equipmentTypeId: (attrs.equipmentTypeId != 0) ? attrs.equipmentTypeId : null,
                        equipmentStatusCode: (attrs.equipmentStatusCode != '') ? attrs.equipmentStatusCode : null,
                        equipmentName: (attrs.equipmentName != '') ? attrs.equipmentName : null,
                        includeChildrens: (attrs.includeChildrens == true) ? 1 : 0,
                        //date: new moment(attrs.date, 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD'),
                    },
                    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 {
                                    equipmentName: obj.EquipmentName,
                                    equipmentCurrentStatus: obj.EquipmentCurrentStatus,
                                    equipmentTypeName: obj.EquipmentTypeName,
                                };
                            });

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

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

                            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 equipmentName',
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'equipmentName'
                                }),
                            };

                            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: 'equipmentCurrentStatusName',
                                label: app.translate(that, 'equipment_status_column_label'),
                                cell: Backgrid.StringCell.extend({
                                    orderSeparator: '',
                                    className: 'string-cell align-center-cell equipmentCurrentStatusName',
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'equipmentStatus'
                                }),
                            };

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

                            _.map(counters, function (obj) {

                                var equipmentCounterType;
                                var equipmentCounterTypeCodeAbsolute;

                                switch (obj.equipmentCounterType) {
                                    case 'INTEGER': equipmentCounterType = Backgrid.IntegerCell.extend({
                                        className: 'integer-cell align-center-cell equipmentCounterName ' + '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': equipmentCounterType = Backgrid.NumberCell.extend({
                                        className: 'number-cell align-center-cell equipmentCounterName ' + '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"));

                                                    }
                                                });
                                            }
                                        }
                                    });

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

                                        equipmentCounterType = Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell equipment-counter-name ' + 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) / 60)) {
                                                            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", alarm.alarmName, "gi").replace("$2", 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 equipmentCounterName ' + obj.equipmentCounterName,
                                    });
                                }

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

                                    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 totalTime ',
                                    formatter: Backgrid.Extension.DurationFormatter.extend({
                                        displayFormat: 'd h:m:s',
                                        modelFormat: 's',
                                    }),
                                }),
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: 'totalTime'
                                }),
                            });

                            if (showAbsolutes) {
                                _.map(array, function (obj) {
                                    if (obj.name != "equipmentName") {
                                        if (obj.name != "equipmentTypeName") { 
                                            if (obj.name != "equipmentCurrentStatusName") {
                                                name = obj.name.replace(/counter_/, "counterAbsolute_");
                                                var column = {
                                                    name: name, 
                                                    label: obj.label,
                                                    cell: obj.cell2.extend({
                                                        className: obj.cell2.prototype.className + ' absoluteCell',
                                                    }),
                                                    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 absoluteTotalTime absoluteCell',
                                        formatter: Backgrid.Extension.DurationFormatter.extend({
                                            displayFormat: 'd h:m:s',
                                            modelFormat: 's',
                                        }),
                                    }),
                                    sortable: false,
                                    editable: false,
                                    headerCell: Backgrid.HeaderCell.extend({
                                        className: 'absoluteTotalTime'
                                    }),
                                });
                            }

                            that.grids.items.columns.add({
                                name: "actions",
                                label: "",
                                sortable: false,
                                editable: false,
                                headerCell: Backgrid.HeaderCell.extend({
                                    className: "configuretd",
                                }),
                                cell: Backgrid.Cell.extend({
                                    template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                    className: 'actions-cell',
                                    events: {
                                        'click .btn-cell-action': 'cellActionClick',

                                        "click .btn-dropdown-config-option": "configure_dropdown_config_opt_click",
                                        "click .btn-dropdown-action-option": "configure_dropdown_action_opt_click",
                                    },

                                    initialize: function () {
                                        Backgrid.Cell.prototype.initialize.apply(this, arguments);
                                        
                                        this.bindEvents();
                                    },
                                    render: function () {
                                        Backgrid.Cell.prototype.render.apply(this, arguments);
                                        this.$el.html(this.template(this.model.toJSON()));

                                        this.render_actions();

                                        this.delegateEvents();
                                        return this;
                                    },
                                    render_newRow: function () {
                                        this.$el.find('[data-toggle="tooltip"]').tooltip();

                                        return this;
                                    },
                                    render_actions: function () {
                                        this.$el.find("[data-toggle=popover]").popover();
                                        
                                        this.checkAnyOptions();
                                        return this;
                                    },
                                    bindEvents: function () {
                                    },
                                    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); }
                                    },
                                    checkAnyOptions: function () {
                                        var actionSourceBtn = this.$el.find(".action-source-btn");
                                        if (this.$el.find(".action-source-dropdown").find("li").length > 0) {
                                            actionSourceBtn.attr("disabled", false);
                                        } else {
                                            actionSourceBtn.attr("disabled", true);
                                        }
                                    },
                                    configure_dropdown_config_opt_click: function (e) {
                                        try {
                                            e.preventDefault();
                                            if (!$(e.target).hasClass("disabled-link")) {
                                                that.configureSource(this.model, { option: $(e.target).data("option") });
                                            }
                                        } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    },
                                }),
                            }); 
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
            }));
        },
        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;
        },
        configureSource: function (model, data) {
            try {
                var that = this,
                    menu_option = (data && data.option) ? data.option : null;

                switch (menu_option.toUpperCase()) {
                    case "NEW-CAMPAIGN":
                        this.newCampaignBtn_click(model);
                        break;
                    case "CHANGE-EQUIPMENT":
                        this.changeEquipment_click(model);
                        break;
                    case "ASSIGN-EQUIPMENT":
                        this.assignEquipment_click(model);
                        break;
                    case "READY":
                        var that = this;
                        this.currentModal = new Modal.Views.Main({
                            focusOk: false,
                            focusSelector: '#btn-cancel',
                            title: app.translate([this, app], "change_equipment_status_title"),
                            message: app.translate([this, app], "set_ready_status_message"),
                            buttons_type: "CONTINUE-CANCEL",
                        });

                        this.listenToOnce(this.currentModal, "continue", function (modal) {
                            try {
                                that.setEquipmentStatus({
                                    ihId: that.model.get('ihId'),
                                    params: [
                                        { Name: 'equipmentId', Type: 'INT', Value: model.get('equipmentId'), },
                                        { Name: 'statusCode', Type: 'VARCHAR', Value: 'READY', },
                                        { Name: 'returnData', Type: 'BIT', Value: 1, },
                                    ],
                                    success: function (ctx, records) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'));

                                            that.currentModal = null;

                                            that._refresh({ reset: true });
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                    error: function (ctx, errorMsg) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], errorMsg));
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        this.currentModal.show();
                        break;
                    case "ONLINE":
                        var that = this;
                        this.currentModal = new Modal.Views.Main({
                            focusOk: false,
                            focusSelector: '#btn-cancel',
                            title: app.translate([this, app], "change_equipment_status_title"),
                            message: app.translate([this, app], "set_online_status_message"),
                            buttons_type: "CONTINUE-CANCEL",
                        });

                        this.listenToOnce(this.currentModal, "continue", function (modal) {
                            try {
                                that.setEquipmentStatus({
                                    ihId: that.model.get('ihId'),
                                    params: [
                                        { Name: 'equipmentId', Type: 'INT', Value: model.get('equipmentId'), },
                                        { Name: 'statusCode', Type: 'VARCHAR', Value: 'ONLINE', },
                                        { Name: 'returnData', Type: 'BIT', Value: 1, },
                                    ],
                                    success: function (ctx, records) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'));

                                            that.currentModal = null;

                                            that._refresh({ reset: true });
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                    error: function (ctx, errorMsg) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], errorMsg));
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        this.currentModal.show();
                        break;
                    case "OFFLINE":
                        var that = this;
                        this.currentModal = new Modal.Views.Main({
                            focusOk: false,
                            focusSelector: '#btn-cancel',
                            title: app.translate([this, app], "change_equipment_status_title"),
                            message: app.translate([this, app], "set_offline_status_message"),
                            buttons_type: "CONTINUE-CANCEL",
                        });

                        this.listenToOnce(this.currentModal, "continue", function (modal) {
                            try {
                                that.setEquipmentStatus({
                                    ihId: that.model.get('ihId'),
                                    params: [
                                        { Name: 'equipmentId', Type: 'INT', Value: model.get('equipmentId'), },
                                        { Name: 'statusCode', Type: 'VARCHAR', Value: 'OFFLINE', },
                                        { Name: 'returnData', Type: 'BIT', Value: 1, },
                                    ],
                                    success: function (ctx, records) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'));

                                            that.currentModal = null;

                                            that._refresh({ reset: true });
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                    error: function (ctx, errorMsg) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], errorMsg));
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        this.currentModal.show();
                        break;
                    case "INSHOP":
                        var that = this;
                        this.currentModal = new Modal.Views.Main({
                            focusOk: false,
                            focusSelector: '#btn-cancel',
                            title: app.translate([this, app], "change_equipment_status_title"),
                            message: app.translate([this, app], "set_in_shop_status_message"),
                            buttons_type: "CONTINUE-CANCEL",
                        });

                        this.listenToOnce(this.currentModal, "continue", function (modal) {
                            try {
                                that.setEquipmentStatus({
                                    ihId: that.model.get('ihId'),
                                    params: [
                                        { Name: 'equipmentId', Type: 'INT', Value: model.get('equipmentId'), },
                                        { Name: 'statusCode', Type: 'VARCHAR', Value: 'INSHOP', },
                                        { Name: 'returnData', Type: 'BIT', Value: 1, },
                                    ],
                                    success: function (ctx, records) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'));

                                            that.currentModal = null;

                                            that._refresh({ reset: true });
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                    error: function (ctx, errorMsg) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], errorMsg));
                                        } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    },
                                });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        this.currentModal.show();
                        break;
                }

            } catch (Error) { }
        },

        refreshBtn_click: function (e) {
            try {
                var params = this.model.toJSON();

                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                equipmentTypeId: (params.equipmentTypeId != 0) ? params.equipmentTypeId : 0,
                                includeChildrens: (params.includeChildrens == true) ? "TRUE" : "FALSE",
                                equipmentStatusCode: (params.equipmentStatusCode == '') ? '-' : params.equipmentStatusCode,
                                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); }
        },
        newCampaignBtn_click: function (model) {
            try {
                var that = this
                    , attrs = model.toJSON()
                    , filteredAttrs
                    , items = this.items;
                    //, clickedBtn = $(e.target)
                    //, auxSource = this.source;

                //Disable clicked button to prevent issues with multiple clicks.
                //clickedBtn.attr("disabled", true);

                //set the current code for the auxiliar source to clone
                //auxSource.set('code', this.editor.getValue());

                filteredAttrs = _.omit(attrs, [
                    'equipmentCounterName',
                    'equipmentCurrentStatus',
                    'equipmentCurrentStatusName',
                    'equipmentId',
                    'equipmentName'
                ]);
                
                this.currentModal = new Screen.Views.NewCampaignModal({
                    model: new Screen.Models.NewCampaignModal(attrs, { ihId: that.model.get('ihId') } ),
                    i18n: this.options.i18n[this.template],
                    template: this.templates.newCampaignModal,
                    collectionData: filteredAttrs,
                });

                var fn_modal_shown_hidden = function () {
                    try {
                        //Enable button in both events, shown and hidden, just to prevent issues if one of them fails
                        //or it is not executed for some reason.
                        //clickedBtn.attr("disabled", false);
                    }
                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                };

                this.listenToOnce(this.currentModal, 'shown', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'hidden', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'finish', function (modal, output) {
                        try {
                            if (output.result == 'SUCCESS') {

                                that.currentModal = null;

                                var params = this.model.toJSON();

                                app.views.topMessages.showMessage(app.translate([that, app], 'new_campaign_started'), { stay: 5 * 1000, });


                                that._refresh({
                                    reset: true,
                                    params: _.extend(
                                        {},
                                        params,
                                        {
                                            ihId: params.ihId,
                                            includeChildrens: (params.includeChildrens == true) ? 1 : 0,
                                            equipmentTypeId: (params.equipmentTypeId != 0) ? params.equipmentTypeId : 0,
                                            equipmentStatusCode: (params.equipmentStatusCode == '') ? '-' : params.equipmentStatusCode,
                                            equipmentName: (params.equipmentName == null || params.equipmentName == '') ? '-' : params.equipmentName,
                                        }
                                    ),
                                });
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    });;

                this.currentModal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        changeEquipment_click: function (model) {
            try {
                var that = this,
                    attrs = model.toJSON(),
                    locations = that.model.get('locations');

                this.currentModal = new Screen.Views.ChangeEquipmentModal({
                    model: new Screen.Models.ChangeEquipmentModal({
                        ihId: that.model.get('ihId'),
                        modelId: attrs.equipmentModelId,
                        typeName: attrs.equipmentTypeName,
                        equipmentName: attrs.equipmentName.split('> ').pop(),
                        locations: locations,
                        codesText: app.translate([that, this], "root_tree_text"),
                    }),
                    parent: that,
                    i18n: this.options.i18n[this.template],
                    template: this.templates.changeEquipmentModal,
                });


                this.listenTo(this.currentModal, 'saving', function (modal, data, callbacks) {
                    try {
                        that.model.changeEquipment(
                            data.ihId,
                            [
                                { name: "equipmentName", type: "VARCHAR", value: data.equipmentName },
                                { name: "locationName", type: "VARCHAR", value: data.name },
                                //{ name: "Name", type: "VARCHAR", value: data.name }
                            ],
                            function (coll, item) {
                                try {
                                    callbacks.success(item.Name);
                                }
                                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                            },
                            function (coll, msg) {
                                try {
                                    callbacks.error(msg);
                                }
                                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                            }
                        );
                    }
                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                })
                    .listenToOnce(this.currentModal, 'finish', function (modal, output) {
                        try {
                            if (output.result == 'SUCCESS') {
                                var params = that.model.toJSON();

                                that.currentModal = null;

                                //that.model.set('selected', output.id);

                                that._refresh({
                                    reset: true,
                                    params: _.extend(
                                        {},
                                        params,
                                        {
                                            ihId: params.ihId,
                                            includeChildrens: (params.includeChildrens == true) ? 1 : 0,
                                            equipmentTypeId: (params.equipmentTypeId != 0) ? params.equipmentTypeId : 0,
                                            equipmentStatusCode: (params.equipmentStatusCode == '') ? '-' : params.equipmentStatusCode,
                                            equipmentName: (params.equipmentName == null || params.equipmentName == '') ? '-' : params.equipmentName,
                                        }
                                    ),
                                });

                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    });;

                this.currentModal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        //changeEquipment_click: function (model) {
        //    try {
        //        var that = this,
        //            attrs = model.toJSON();
        //            //locations = that.model.get('locations');

        //        this.currentModal = new Screen.Views.ChangeEquipmentModal({
        //            model: new Screen.Models.ChangeEquipmentModal({
        //                modelId: attrs.equipmentModelId,
        //                ihId: that.model.get('ihId'),
        //                //locations: locations,
        //                codesText: app.translate([that, this], "root_tree_text"),
        //            }),
        //            parent: that,
        //            i18n: this.options.i18n[this.template],
        //            template: this.templates.changeEquipmentModal,
        //        });


        //        this.listenTo(this.currentModal, 'saving', function (modal, data, callbacks) {
        //            try {
        //                that.model.changeEquipment(
        //                    data.ihId,
        //                    [
        //                        { name: "ModelId", type: "INT", value: data.modelId },
        //                        { name: "EquipmentModelId", type: "INT", value: data.equipmentModelId },
        //                        { name: "LocationModelId", type: "INT", value: data.locationModelId },
        //                        //{ name: "Name", type: "VARCHAR", value: data.name }
        //                    ],
        //                    function (coll, item) {
        //                        try {
        //                            callbacks.success(item.id);
        //                        }
        //                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        //                    },
        //                    function (coll, msg) {
        //                        try {
        //                            callbacks.error(msg);
        //                        }
        //                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        //                    }
        //                );
        //            }
        //            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        //        })
        //            .listenToOnce(this.currentModal, 'finish', function (modal, output) {
        //                try {
        //                    if (output.result == 'SUCCESS') {
        //                        var params = that.model.toJSON();

        //                        that.currentModal = null;

        //                        //that.model.set('selected', output.id);

        //                        that._refresh({
        //                            reset: true,
        //                            params: _.extend(
        //                                {},
        //                                params,
        //                                {
        //                                    ihId: params.ihId,
        //                                    includeChildrens: (params.includeChildrens == true) ? 1 : 0,
        //                                    equipmentTypeId: (params.equipmentTypeId != 0) ? params.equipmentTypeId : 0,
        //                                    equipmentStatusCode: (params.equipmentStatusCode == '') ? '-' : params.equipmentStatusCode,
        //                                    equipmentName: (params.equipmentName == null || params.equipmentName == '') ? '-' : params.equipmentName,
        //                                }
        //                            ),
        //                        });

        //                    }
        //                }
        //                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        //            });;

        //        this.currentModal.show();
        //    }
        //    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        //},
        setEquipmentStatus: function (options) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                opt = _.extend({
                    async: true,
                }, options);

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

            Core.Json.CallProcedure(
                app.DatabaseNames.ELT + '.WebApp.ChangeEquipmentStatus',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table) && (resp.Table.length > 0)) {
                                if (opt.success)
                                    opt.success(that, resp.Table[0]);
                            }
                            else {
                                var errorMsg = ((resp) && (resp.Message))
                                                            ? resp.Message
                                                            : 'SERVER_RESPONSE_NOT_VALID';
                                console.error(errorMsg);

                                if (opt.error)
                                    opt.error(that, errorMsg);
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onError: function (errorMsg) {
                        try {
                            if (opt.error)
                                opt.error(that, errorMsg);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: opt.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );
        },

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


    Screen.Models.CounterConfiguration = Backbone.Epoxy.Model.extend({
        defaults: {
            id: null,
            counterId: null,
            active: null,
        },
        parse: function (obj) {
            return {
                id: obj.Id,
                counterId: obj.EquipmentCounterId,
                active: obj.Active,
            }
        }
    });

    Screen.Collections.CounterConfigurations = Backbone.Collection.extend({
        model: Screen.Models.CounterConfiguration,

        fixedParameters: [],
        isFetching: false,
        currentPage: 1,
        pageSize: 50,
        transaction_timestamp: null,

        comparator: function (a, b) {
            var attrsA = a.toJSON(),
                attrsB = b.toJSON();

            if (attrsA.isNew) return -1;
            else if (attrsB.isNew) return 1;
            else if (attrsA.name < attrsB.name) return -1;
            else if (attrsA.name > attrsB.name) return 1;
            else return 0;
        },

        fetch: function (opt) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                ttimestamp = this.transaction_timestamp = new Date().getTime(),
                options = opt ? _.clone(opt) : {};

            this.isFetching = true;

            //if (options.reset) {
            //this.resetPagination(true);

            this.fixedParameters = [
                { Name: '@id', Type: 'INT', Value: options.params.id, },
                { Name: '@ihId', Type: 'INT', Value: options.params.ihId, },
            ];
            //}

            _.each(this.fixedParameters, function (qpParams) {
                qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });

            if (options.refresh) {
                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', this.currentPage * this.pageSize);
            }
            else if (options.reset) {
                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', this.pageSize);
            }
            else {
                qp.Add('@fromRow', 'INT', (this.currentPage - 1) * this.pageSize);
                qp.Add('@rowsToFetch', 'INT', this.pageSize);
            }


            Core.Json.CallProcedure(
                app.DatabaseNames.ELT + ".SYSTEM.GetEquipmentConfiguration",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            //checking transaction timestamp
                            if (ttimestamp != that.transaction_timestamp)
                                return;

                            if ((resp) && (resp.Table)) {
                                var records = resp.Table,
                                    newColl;

                                newColl = _.map(records, that.model.prototype.parse);

                                var method = ((options.refresh) || ((options.reset))) ? 'set' : 'add';

                                //checking transaction timestamp
                                if (ttimestamp != that.transaction_timestamp)
                                    return;

                                if (!options.reset) {
                                    var editingItems = _.where(that.toJSON(), { isNew: true });
                                    [].push.apply(newColl, editingItems);
                                }

                                that[method](newColl, { from: 'fetch' })
                                    .trigger('fetch', that, records);

                                //decreasing page since we couldn't get any data on this page.
                                if (newColl.length == 0 && method == 'add')
                                    that.currentPage--;

                                that.isFetching = false;
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    },
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
    });

    Screen.Models.NewCampaignModal = Backbone.Epoxy.Model.extend({
        defaults: {
            message: null,
            ihId: null,
            //equipmentId: null,
            //equipmentName: null,
            comments: '',
            
            errorMsg: "",
            processing: false,
        },
    });

    Screen.Views.NewCampaignModal = Modal.Views.SimpleModal.extend({
        className: Modal.Views.SimpleModal.prototype.className + ' new-campaign-modal',

        i18n: null,
        equipmentCounters: null,
        countersGrid: null,
        innerModal: null,
        templates: null,
        propertiesColl: null,
        collectionData: null,

        initialize: function (options) {
            _.extend(this, options);

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

            if (!this.equipmentCounters) {
                this.equipmentCounters = new Screen.Collections.CounterConfigurations();
                this.equipmentCounters.fetch(
                    {
                        params: {
                            id: this.model.get('equipmentId'),
                            ihId: this.model.get('ihId'),
                        },
                    }
                );
            }

            this.initializePropertiesColl();

            this.bindingSources = {
                properties: this.propertiesColl,
            };

            this.bindEvents();

            return this;
        },
        bindEvents: function () {
            Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
        },
        formatToType: function (val, type) {
            var formattedValue = null;

            if (val && type) {
                switch (type.toUpperCase()) {
                    case 'DURATION':
                        if (val) {
                            var dur = new moment.duration(val, 'm')
                            var hours = parseInt(dur.asHours(), 10);
                            var minutes = dur.minutes();
                            var seconds = dur.seconds();

                            hours.toFixed(0);
                            minutes.toFixed(0);
                            seconds.toFixed(0);

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

                        formattedValue = (val) ? hours + ':' + minutes + ':' + seconds : null;
                        break;
                    case 'INTEGER':
                        formattedValue = (val) ? val.toFixed(0).toString() : null;
                        break;
                    case 'REAL':
                        formattedValue = (val) ? val.toFixed(4).toString() : null;
                        break;
                }
            } else {
                formattedValue = '-';
            }

            return formattedValue;
        },
        initializePropertiesColl: function () {
            var that = this,
                counterIndexes = [],
                counterItems = [];

            this.propertiesColl = new Backbone.Collection();

            counterIndexes = _.map(this.collectionData, function (val, key) {
                if ((key.indexOf("counter_") != -1))
                    return key.split("_").pop();
            });

            counterItems = _.map(counterIndexes, function (val, key) {
                if (val) {
                    var counterType = that.collectionData['counterType_' + val];
                    return { name: val, campaignValue: that.formatToType(that.collectionData['counter_' + val], counterType), absoluteValue: that.formatToType(that.collectionData['counterAbsolute_' + val], counterType) };
                }
            });

            this.propertiesColl.add(_.filter(counterItems, function (val) { return val; }));

            //_.map(this.collectionData, function (val, key) {
            //    that.propertiesColl.add({ label: key, value: val });
            //});
        },
        startCampaign: function (options) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                opt = _.extend({
                    async: true,
                }, options);

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

            qp.Add('@uniqueEquipment', 'BIT', 0);

            Core.Json.CallProcedure(
                app.DatabaseNames.ELT + '.WebApp.StartCampaign',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table) && (resp.Table.length > 0)) {
                                if (opt.success)
                                    opt.success(that, resp.Table[0]);
                            }
                            else {
                                var errorMsg = ((resp) && (resp.Message))
                                                            ? resp.Message
                                                            : 'SERVER_RESPONSE_NOT_VALID';
                                console.error(errorMsg);

                                if (opt.error)
                                    opt.error(that, errorMsg);
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onError: function (errorMsg) {
                        try {
                            if (opt.error)
                                opt.error(that, errorMsg);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: opt.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );
        },

        render: function () {
            Modal.Views.SimpleModal.prototype.render.apply(this, arguments);

            var countersGrid = this.countersGrid = new Backgrid.Grid({
                className: 'backgrid table table-hover',
                columns: [
                    {
                        name: 'name',
                        label: app.translate([this, app], 'name_col_label'),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: 'string-cell align-center-cell',
                        }),
                    },
                    {
                        name: 'campaignValue',
                        label: app.translate([this, app], 'campaign_col_label'),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: 'string-cell align-center-cell',
                        }),
                    },
                    {
                        name: 'absoluteValue',
                        label: app.translate([this, app], 'absolute_col_label'),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: 'string-cell align-center-cell',
                        }),
                    },
                ],
                collection: this.propertiesColl,
            });

            this.$el.find('.counters-grid-container').append(countersGrid.render().el);
        },
        
        save: function () {
            var that = this,
                attrs = this.model.toJSON();

            if (attrs.processing == false) {
                this.model.set('processing', true);

                try {
                    this.startCampaign({
                        params: [
                                { Name: '@ihId', Type: 'INT', Value: attrs.ihId },
                                { Name: '@equipmentId', Type: 'INT', Value: attrs.equipmentId, },
                                { Name: '@comments', Type: 'VARCHAR', Value: attrs.comments, },
                        ],
                        success: function (model, resp) {
                            try {
                                that.model.set('processing', false);
                                
                                that.finish({ result: 'SUCCESS', data: resp });

                                that.hide();
                                //setTimeout(_.bind(that.hide, that), 1500);
                            }
                            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                        },
                        error: function (model, errorMsg) {
                            try {
                                app.views.topMessages.showMessage(app.translate([{ options: { i18n: { 1: that.i18n, }, }, template: 1, }, app], errorMsg), { stay: 5 * 1000, });
                            }
                            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                            finally {
                                that.model.set('processing', false);
                            }
                        },
                    });
                }
                catch (e) {
                    this.model.set('processing', false);
                    throw e;
                }
            }
        },
        show: function () {
            if (!this.isRendered) {
                this.render();
            }
            else {
                this.$el.modal({
                    keyboard: false,
                    backdrop: 'static',
                });
            }

            return this;
        },
        hide: function () {
            if (this.innerModal)
                this.innerModal.hide();

            var result = Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
            return result;
        },
        
        acceptBtn_click: function (e) {
            try {
                this.save();
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
    });

        Screen.Models.EquipmentTree = Backbone.Model.extend({
            initialize: function () {
            }
            , defaults: {
                id: null,
                ihId: null,
                parent: null,
                type: null,
                typeId: null,
                text: null,
                order: null,
                iconId: null,
                iconData: null,
                deleted: false,
                enabled: true,
            }
        });

        Screen.Models.EquipmentsTree = Backbone.Collection.extend({
            model: Screen.Models.EquipmentTree,
            getAssignableEquipments: function (options) {
                var that = this;

                var QP = new QueryParameters();
                if (options && options.params) {
                    if (options.params.id) QP.Add("Id", "INT", options.params.id);
                    if (options.params.ihId) QP.Add("ihId", "INT", options.params.ihId);
                }

                //QP.Add("includeIcons", "BIT", 1);

                var items = [];
                items.push({
                    id: TREE_NODE_ROOT_ID,
                    parent: '#',
                    type: "root",
                    text: options.codesText,
                    state: {
                        opened: true,
                    },
                    icon: 'fa fa-cogs icon-style',
                    a_attr: { style: "background : #c1c1c1; border: 2px solid #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
                });

                Core.Json.CallProcedure(app.DatabaseNames.System + ".EQUIP.GetAvailableTemplates", QP, {
                    onSuccess: function (data) {
                        if (Core.Object.Eval(data, "Table")) {
                            var models = data.Table;
                            var type = data.Table1[0];
                            //var templates = data.Table1
                            //var icons = data.Table1;

                            for (var i = 0; i < models.length; i++) {
                                var itemData = models[i];
                                var equipmentModel = {
                                    id: itemData.Id,
                                    parent: ((itemData.ParentId != null) && (itemData.ParentId != -1))
                                        ? itemData.ParentId
                                        : TREE_NODE_ROOT_ID,
                                    typeId: itemData.TypeId,
                                    text: (itemData.Name) ? itemData.Name : itemData.TypeName,
                                    equipmentId: itemData.EquipmentId,
                                    internal: itemData.Internal,
                                    //enabled: itemData.Enabled,
                                    state: {
                                        opened: true,
                                    },
                                    order: itemData.Order - 1,
                                    //order: 0,
                                    data: {
                                        enabled: itemData.Enabled,
                                    },
                                    icon: (itemData.IconData) ? itemData.IconData : 'fa fa-minus',
                                    a_attr: (itemData.Name && itemData.Internal)
                                        ? { style: "background: #f1f1f1; border: 2px dotted #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
                                        : ((itemData.Name && !itemData.Internal))
                                            ? { style: "background : #c1c1c1; border: 2px solid #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
                                            : ((itemData.TypeName != type.TypeId)) 
                                                ? { style: "background : #c1c1c1; border: 2px solid #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
                                                : { style: "background: #f1f1f1;color: #999999; border: 2px dotted #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
                                };

                                items.push(equipmentModel);
                            }

                        }

                        that['set'](items, { from: "fetch" });

                        if (options.callback != null && _.isFunction(options.callback))
                            options.callback.call(this, that, items);
                    },
                    Secured: true
                }, app.ConnectionStrings.app);

                return this;
            },
            //GetAvailableEquipmentTemplates: function (options) {
            //    var that = this;

            //    var QP = new QueryParameters();
            //    if (options && options.params) {
            //        if (options.params.id) QP.Add("Id", "INT", options.params.id);
            //        if (options.params.ihId) QP.Add("ihId", "INT", options.params.iHId);
            //    }

            //    //QP.Add("includeIcons", "BIT", 1);

            //    var items = [];
            //    items.push({
            //        id: TREE_NODE_ROOT_ID,
            //        parent: '#',
            //        type: "root",
            //        text: options.codesText,
            //        state: {
            //            opened: true,
            //        },
            //        icon: 'fa fa-cogs icon-style',
            //        a_attr: { style: "background : #c1c1c1; border: 2px solid #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;" }
            //    });

            //    Core.Json.CallProcedure(app.DatabaseNames.System + ".EQUIP.GetAvailableEquipmentTemplates", QP, {
            //        onSuccess: function (data) {
            //            if (Core.Object.Eval(data, "Table")) {
            //                var models = data.Table;
            //                //var templates = data.Table1
            //                //var icons = data.Table1;

            //                for (var i = 0; i < models.length; i++) {
            //                    var itemData = models[i];
            //                    var equipmentModel = {
            //                        id: itemData.Id,
            //                        parent: ((itemData.ParentId != null) && (itemData.ParentId != -1))
            //                            ? itemData.ParentId
            //                            : TREE_NODE_ROOT_ID,
            //                        equipmentId : itemData.EquipmentId,
            //                        typeId: itemData.TypeId,
            //                        text: itemData.Name,
            //                        //enabled: itemData.Enabled,
            //                        state: {
            //                            opened: true,
            //                        },
            //                        order: itemData.Order - 1,
            //                        //order: 0,
            //                        data: {
            //                            enabled: itemData.Enabled,
            //                        },
            //                        icon: (itemData.IconData) ? itemData.IconData : 'fa fa-minus',
            //                        a_attr: {
            //                            style: (itemData.EquipmentId && itemData.Internal)
            //                                ? "background: #f1f1f1; border: 2px dotted #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;"
            //                                : "background : #c1c1c1; border: 2px solid #c1c1c1; border-radius:5px; margin-bottom:3px; line-height: 28px;height: 28px;padding-right: 10px; text-decoration:none;"
            //                        }
            //                    };

            //                    items.push(equipmentModel);
            //                }

            //            }

            //            that['set'](items, { from: "fetch" });

            //            if (options.callback != null && _.isFunction(options.callback))
            //                options.callback.call(this, that, items);
            //        },
            //        Secured: true
            //    }, app.ConnectionStrings.app);

            //    return this;
            //},
            
        });


        Screen.Models.ChangeEquipmentModal = Backbone.Epoxy.Model.extend({
            defaults: {
                message: null,


                modelId: null,
                typeName: null,
                ihId: null,
                equipmentModelId: null,
                locationModelId: null,
                locations:[],
                equipments: [],
                equipmentName: '',
                name: '',
                type: null,
                hierarchyList: null,
                equipmentId: null,
                available: true,

                codesText: null,


                processing: false,
                errorMsg: "",
            },
        });

        Screen.Views.ChangeEquipmentModal = Modal.Views.SimpleModal.extend({
            className: Modal.Views.SimpleModal.prototype.className + ' change-equipment-modal',

            i18n: null,
            innerModal: null,
            templates: null,
            modelsGrid: null,
            initialize: function (options) {
                _.extend(this, options);

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

                this.items = new Screen.Models.EquipmentsTree();

                this.bindEvents();

                return this;
            },
            bindEvents: function () {
                Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
                //this.listenTo(this.items, 'fetch', this.collection_fetch);
                //this.listenTo(this.model, "change:equipmentModelId", this.idChanged);
            },

            render: function () {

                Modal.Views.SimpleModal.prototype.render.apply(this, arguments);
                var that = this;

                that.applyBindings();
                //loading the view and appeding it to the views's $el.
                //that.$el.html(tmp(that.model.toJSON()));
                this.tree = null;

                this.items.getAssignableEquipments(_.extend(
                    {},
                    {
                        params: {
                            id: this.model.get('modelId'),
                            ihId: this.model.get('ihId'),
                        },
                        codesText: this.model.get('codesText'),
                        callback: function (model, item) {
                            if (item.length > 1) {
                                that.model.set('available', true);

                                $.jstree.defaults.core.themes.variant = "large";
                                var times = 0;
                                that.$el.find(".jstreePreview").jstree({
                                    core: {
                                        check_callback: true,
                                        data: function (obj, cb) {
                                            var data = that.items.toJSON();

                                            //setting disabled nodes
                                            _.each(data, function (t) { t.li_attr = { "class": (t.enabled) ? "" : "node-disabled" } });

                                            data[1].parent = TREE_NODE_ROOT_ID;

                                            cb.call(this, data);
                                        },
                                    },
                                    sort: function (a, b) {
                                        var nodea = this.get_node(a);
                                        var nodeb = this.get_node(b);

                                        var collection = that.items;
                                        var model_a = collection.get(nodea.id);
                                        var model_b = collection.get(nodeb.id);

                                        if (model_a && model_b)
                                            return model_a.get("order") > model_b.get("order") ? 1 : -1;
                                        else if (model_a) return -1;
                                        else if (model_b) return 1;
                                        else return -1;
                                    },
                                    plugins: [
                                        "wholerow",
                                        "types",
                                        "sort",
                                    ],
                                });

                                that.tree = that.$el.find(".jstreePreview").jstree(true);



                                that.$el.find(".jstreePreview").jstree('open_all');

                                that.setTreeLoadingState(false);

                                that.$el.find(".jstreePreview").bind({
                                    "select_node.jstree": _.bind(that.onSelectNode, that),
                                });
                            } else {
                                that.model.set('available', null);
                            }
                        }
                    }));

            },
            modelSelectChanged: function (e) {
                try {
                    if (!this.ignoreDropdownEvent) {
                        var modelId = this.modelsSelect.GetValue();

                        this.model.set({
                            equipmentModelId: (parseInt(modelId, 10) == 0) ? null : modelId
                        });
                    }
                } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            },
            onSelectNode: function (e, obj) {
                //Select node event is fired event for right click. We don't want that because
                //we don't want to refresh item selected data on right click. So return if it is
                //right click.

                //Right click = 2. Also check if 'obj.event.button' because select node also is fired by
                //keyboard. In that case 'obj.event.button' is undefined. Also 'obj.event' can be undefined (but don't know why!).
                if ((obj.event) && (obj.event.button) && (obj.event.button == 2))
                    return;

                var that = this;
                var node = obj.node;
                var instance = obj.instance;
                var collection = this.items;
                var parent;

                if (obj.selected.length < 2) {

                    that.model.set('name', null);
                    that.model.set('equipmentModelId', null);
                    that.model.set('equipmentId', null);

                    if (node.original.equipmentId && node.original.internal) {
                        that.model.set('name', node.text);
                        that.model.set('equipmentModelId', node.id);
                        that.model.set('equipmentId', null);
                    }

                    if (!node.original.equipmentId && (that.model.get('typeName') == node.text)) {

                        
                        parent = that.tree.get_node(node.parent);

                        while (!parent.original.equipmentId) {
                            parent = that.tree.get_node(parent.parent);
                        }

                        that.model.set('name', parent.text);
                        that.model.set('equipmentModelId', node.id);
                        that.model.set('equipmentId', null);

                    }
                        
                }
            },
            setTreeLoadingState: function (isLoading) {
                var tree = this.tree;

                var rootNode = tree.get_node(TREE_NODE_ROOT_ID);

                if (isLoading == true) {
                    tree.set_type(rootNode, 'loading');

                    $('.tree li').each(function () {
                        tree.disable_node(this.id);
                    });
                }
                else {
                    tree.set_type(rootNode, 'root');

                    $('.tree li').each(function () {
                        tree.enable_node(this.id);
                    });
                }
            },
            save: function () {
                var that = this,
                    attrs = this.model.toJSON();

                if (attrs.processing == false) {
                    this.model.set('processing', true);

                    try {
                        this.trigger(
                            'saving',
                            this,
                            attrs,
                            {
                                success: function (name) {
                                    try {
                                        that.model.set('processing', false);

                                        that.finish({ result: 'SUCCESS', name: name});

                                        that.hide();
                                        //setTimeout(_.bind(that.hide, that), 1500);
                                    }
                                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                },
                                error: function (errorMsg) {
                                    try {
                                        app.views.topMessages.showMessage(app.translate([{ options: { i18n: { 1: that.i18n, }, }, template: 1, }, app], errorMsg), { stay: 5 * 1000, });
                                    }
                                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                    finally {
                                        that.model.set('processing', false);
                                    }
                                },
                            }
                        );
                    }
                    catch (e) {
                        this.model.set('processing', false);
                        throw e;
                    }
                }
            },
            show: function () {
                if (!this.isRendered) {
                    this.render();
                }
                else {
                    this.$el.modal({
                        keyboard: false,
                        backdrop: 'static',
                    });
                }

                return this;
            },
            hide: function () {
                if (this.innerModal)
                    this.innerModal.hide();

                var result = Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
                return result;
            },
            removeRow: function (model) {
                var that = this;
                model.collection.removeItem(
                    model.get('id')
                    , function (coll, data) {
                        app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'), { stay: 5 * 1000, });

                        that.items.remove(model);

                        that.collection_fetch();
                    }
                    , function (coll, msg) {
                        app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 10 * 1000, });
                    }
                );
            },
            downloadScript: function (m) {
                try {
                    var that = this;

                    Script.download(
                        {
                            params: {
                                id: m.get('id')
                            },
                            success: function (model, data) {
                                try {
                                    // Blob for saving.
                                    var blob = new Blob([new Uint8Array(data.Content)], { type: 'application/octet-stream' });

                                    // Tell the browser to download the file.
                                    saveAs(blob, data.FileName);
                                }
                                catch (error) {
                                    console.error((error.stack) ? error.stack : new Error(error).stack);
                                }
                            },
                            error: function (model, msg) {
                                try {
                                    app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 5 * 1000, });
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            },
                        }
                    );
                }
                catch (error) {
                    console.error((error.stack) ? error.stack : new Error(error).stack);
                }
            },


            acceptBtn_click: function (e) {
                try {
                    this.save();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            collection_fetch: function (col, resp) {
                var that = this;
                var s = [];
                var e = [];

                this.items.each(
                    function (m) {
                        if (m.get('statusCode') == 'EXAMPLE') {
                            e.push(m);
                        }
                        else {
                            s.push(m);
                        }
                    }
                );

                s.forEach(function (model, index) {
                    model.set('curSourceId', that.model.get('curSourceId'));
                });

                this.sources.set(s);

                this.examples.set(e);

                if (this.toCloneSource && !this.sources.findWhere({ id: -1 })) {
                    this.addNewClone(this.toCloneSource);
                }
            },
        });

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

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

        Screen.Models.Item = classRef = superRef.extend({
            defaults: _.extend(
                {},
                superProto.defaults,
                {
                    equipmentName: null,
                    equipmentCounterName: null,
                    equipmentCounterType: null,
                    equipmentTypeName: null,
                }
            ),
            procedures: {
                get: app.DatabaseNames.ELT + '.WebApp.GetEquipmentsCurrentCampaign',
            },
            parse: function (obj) {
                return  {
                    equipmentName: obj.EquipmentName,
                    equipmentCounterName: 'counter_' + obj.EquipmentCounterName,
                    equipmentCounterType: obj.EquipmentCounterType,
                    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)) {
                    var that = this,
                        newColl;

                    //First table contains info of both equipments & counters configuration
                    var records = resp.Table;
                    var config = resp.Table;
                    //Second table contains the counters data
                    var dataValues = resp.Table1;
                    //Third table contains total time and absolute total time values for the equipments
                    var times = resp.Table2;

                    //Fourth table contains counter codes and types, but it's not used here

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

                    var columns = [];
                    var newData = [];

                    //Creates the attributes of the equipment counter 'EquipmentCounterNam  e' if 'EquipmentCounterName' exists
                    _.map(config, function (obj) {
                        var table = _.findWhere(records, { EquipmentId: obj.EquipmentId, EquipmentCounterId: obj.EquipmentCounterId });
                        if (table) {
                            if (table.EquipmentCounterName) {
                                var find = _.findWhere(columns, { column: table.EquipmentCounterName });
                                if (!find) {
                                    columns.push({ column: 'counter_' + table.EquipmentCounterName }, { column: 'counterType_' + table.EquipmentCounterName }, { column: 'counterAbsolute_' + table.EquipmentCounterName });
                                    data['counter_' + table.EquipmentCounterName] = null;
                                    data['counterType_' + table.EquipmentCounterName] = null;
                                    data['counterAbsolute_' + table.EquipmentCounterName] = null;
                                }
                            }
                        }
                    });
                    
                    _.map(records, function (obj) {
                        //Get all counter in variable for values
                        var values = [];
                        values = _.where(dataValues, { EquipmentId: obj.EquipmentId, EquipmentCounterId: obj.EquipmentCounterId });

                        //Get all timing values
                        var timingValues = [];
                        timingValues = _.where(times, { EquipmentId: obj.EquipmentId });

                        //Get all counter in variable for absolute values
                        var absolute = [];
                        absolute = _.where(dataValues, { EquipmentId: obj.EquipmentId, EquipmentCounterId: obj.EquipmentCounterId });

                        var keys = Object.keys(data);

                        var objAux;

                        var object = {
                            equipmentId: null,
                            equipmentModelId: null,
                            equipmentName: null,
                            equipmentTypeName:null,
                            equipmentCurrentStatus: null,
                            equipmentCurrentStatusName: null,
                            totalTime: null,
                            absolute_totalTime: null,
                            //absolute:null,
                        };

                        var find = _.findWhere(newData, { equipmentId: obj.EquipmentId });
                        if (!find) {
                            //Loop and gets each key on keys.
                            //Add attribute keys to the equipment object, and includes
                            //counter attributes if matches EquipmentCounterName when the current
                            //equipment has that counter.
                            //Details on case default.
                            _.map(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 'counterType_' + obj.EquipmentCounterName:
                                        (value) ? object[key] = obj.EquipmentCounterType : object[key] = null;
                                        break;
                                    case 'counterAbsolute_' + obj.EquipmentCounterName:
	                                    value = _.last(absolute);
	                                    (value) ? object[key] = value.AbsoluteTotalValue : object[key] = null;
	                                    break;
                                    case 'equipmentId': object[key] = obj.EquipmentId;
                                        break;
                                    case 'equipmentModelId': object[key] = obj.EquipmentModelId;
                                        break;
                                    case 'equipmentName': object[key] = obj.EquipmentName;
                                        break;
                                    case 'equipmentTypeName': object[key] = obj.EquipmentTypeName;
                                        break;
                                    case 'equipmentCurrentStatus': object[key] = obj.EquipmentCurrentStatus;
                                        break;
                                    case 'equipmentCurrentStatusName': object[key] = (obj.EquipmentCurrentStatus ) ? app.translate([app, that], obj.EquipmentCurrentStatus + '_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(config, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                singleConfig = _.findWhere(config, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() });

                                                value = _.last(_.where(dataValues, {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(config, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                (value) ? object[key] = objAux.EquipmentCounterType : object[key] = null;
                                            }
                                        } else if (key.indexOf('counterAbsolute_') != -1) {
                                            if (_.findWhere(config, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() })) {
                                                singleConfig = _.findWhere(config, { EquipmentId: obj.EquipmentId, EquipmentCounterName: key.split("_").pop() });

                                                value = _.last(_.where(dataValues, { EquipmentId: obj.EquipmentId, EquipmentCounterId: singleConfig.EquipmentCounterId }));
                                                (value) ? object[key] = value.AbsoluteTotalValue : object[key] = null;
                                            }
                                        }
                                }
                            });
                            newData.push(object);
                        }
                    }); 

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