//SCREEN-BOILERPLATE

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

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

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

    'backgrid/infinator',
    'js/backgrid-0.3.5/extensions/select-integer-cell/backgrid-select-integer-cell',
    //'js/backgrid-0.3.5/extensions/image-cell/image-cell',
],

    function (app, T, Backgrid, Modal ) {

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


    EventTypes.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            hasData: false,
            isLoading: true,
            typeCode: [],
            tags: [],
        },
        //computeds: {
        //},

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

            qp.Add('@OnlyEnabledTags', 'BIT', 1);
            qp.Add('@RowsToFetch', 'INT', 999999999);

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

                                var newItems = _.map(records, function (obj) { return { value: obj.TagID, label: (obj.Alias) ? obj.Alias : obj.Name, dataType: obj.DataType }; });

                                that.set("tags", 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;
        },
    });

    //the generate id method is called everytime a view is going to be shown by the router and returns and id that
    //is used by the router to store in cache (if it is cacheable) and to know the current shown view.
    //this is useful in case your view is reusable, and displays different data depending on url parameters 
    //(such as a catalog view, or a report that doesnt change in terms of UI but it does change in terms of data)
    //so you can always use the same view on the router but the cache can tell which view is which by using differents ids.
        EventTypes.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return 'events';
        } catch (Error) { }
    }

        EventTypes.Views.Main = Backbone.Epoxy.View.extend({
            template: 'events',
            id: 'events',
        title: 'Events',
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        isCacheable: false,
        events: function () {
            return {
                'click .add-item-edge-events': this.addNewEdgeEvent,
                'click .add-item-digital-change-events': this.addNewDigitalChangeEvent,
                'click .add-item-analog-change-events': this.addNewAnalogChangeEvent,
                'click .add-item-analog-edge-events': this.addNewAnalogEdgeEvent,
            };
        },
        autoRefresh: null,
        subviews: null,
        viewParams: null,
        edgeEvents: null,
        digitalChangeEvents: null,
            analogChangeEvents: null,
        analogEdgeEvents: null,
        grids: null,
        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            var that = this;

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

            this.grids = {};

            this.model = new EventTypes.Models.Main();

            this.edgeEvents = new EventTypes.Collections.EdgeEvents();
            this.digitalChangeEvents = new EventTypes.Collections.DigitalChangeEvents();
            this.analogChangeEvents = new EventTypes.Collections.AnalogChangeEvents();
            this.analogEdgeEvents = new EventTypes.Collections.AnalogEdgeEvents();

            this.model.fetchTags();

            this.bindEvents();
        },
        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/events/configuration/' + 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.subviews.subnavbarControls.render();

                            
                            

                            var grid = that.grids.edgeEvents = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'name',
                                        label: app.translate(that, 'name_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            orderSeparator: '',
                                            className: 'string-cell align-center-cell name',
                                        }),
                                    },
                                    {
                                        name: 'tagId',
                                        label: app.translate(that, 'tag_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots tagId',
                                            optionValues:
                                                that.filterTags('Digital')
                                            ,
                                        }),
                                    },
                                    {
                                        name: 'tagAscendingFlank',
                                        label: app.translate(that, 'tag_asc_flank_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.BooleanCell.extend({
                                            className: 'boolean-cell align-center-cell tag1AscendingFlank',
                                            
                                        }),
                                    },
                                    //{
                                    //    name: 'tag2Id',
                                    //    label: app.translate(that, 'tag2_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    cell: Backgrid.Extension.SelectIntegerCell.extend({
                                    //        className: 'select-cell align-center-cell text-3dots tagId',
                                    //        optionValues:
                                    //            _.map(that.model.get('tags'), function (obj) { return [obj.label, obj.value,]; })
                                    //        ,
                                    //    }),
                                    //},
                                    //{
                                    //    name: 'tag2AscendingFlank',
                                    //    label: app.translate(that, 'tag2_asc_flank_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    cell: Backgrid.BooleanCell.extend({
                                    //        className: 'boolean-cell align-center-cell tag2AscendingFlank',
                                    //    }),
                                    //},
                                    //{
                                    //    name: 'tagResetValue',
                                    //    label: app.translate(that, 'tag_reset_value_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    cell: Backgrid.NumberCell.extend({
                                    //        className: 'number-cell align-center-cell text-3dots tagResetValue',
                                    //        decimals: 2,
                                    //    }),
                                    //},
                                    //{
                                    //    name: 'tagRealAsDigital',
                                    //    label: app.translate(that, 'tag_real_as_digital_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    //cell: 'boolean',
                                    //    cell: Backgrid.BooleanCell.extend({
                                    //        className: 'boolean-cell align-center-cell tagRealAsDigital',
                                    //    }),
                                    //},
                                    {
                                        name: 'active',
                                        label: app.translate(that, 'active_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: 'boolean',
                                    },
                                    {
                                        name: 'actions',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.Cell.extend({
                                            template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                            className: 'actions-cell',
                                            events: {
                                                'click .btn-cell-action': 'cellActionClick'
                                            },

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

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

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

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

                                            checkMode: function () {
                                                var newRow = this.model.get('isNew');
                                                if (newRow) this.setNewRowMode(true);
                                                else this.setNewRowMode(false);
                                            },
                                            setNewRowMode: function (val) {
                                                var btnRemove = this.$el.find('.btn-remove');
                                                var btnSave = this.$el.find('.btn-save');
                                                var btnDiscard = this.$el.find('.btn-discard');

                                                if (val) {
                                                    btnRemove.addClass('hide');
                                                    btnSave.removeClass('hide');
                                                    btnDiscard.removeClass('hide');
                                                    this.model.set('active', true);

                                                } else {
                                                    btnRemove.removeClass('hide');
                                                    btnSave.addClass('hide');
                                                    btnDiscard.addClass('hide');

                                                }

                                            },

                                            cellActionClick: function (e) {
                                                try {
                                                    var target = $(e.target);
                                                    var actionData = target.closest('[data-cell-action]').data('cell-action');
                                                    if (actionData) {
                                                        
                                                        that.actionOnRowEdgeEvent(this.model, actionData);
                                                    }
                                                }
                                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                            },
                                        }),
                                    },
                                ],
                                collection: that.edgeEvents,
                            });

                            that.$el.find('.edge-events-grid-container').append(grid.render().el);

                            var grid = that.grids.digitalChangeEvents = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'name',
                                        label: app.translate(that, 'name_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            orderSeparator: '',
                                            className: 'string-cell align-center-cell name',
                                        }),
                                    },
                                    {
                                        name: 'tagId',
                                        label: app.translate(that, 'tag_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots tagId',
                                            optionValues:
                                                that.filterTags('Digital')
                                            ,
                                        }),
                                    },
                                    {
                                        name: 'tagAscendingFlank',
                                        label: app.translate(that, 'tag_asc_flank_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.BooleanCell.extend({
                                            className: 'boolean-cell align-center-cell tag1AscendingFlank',

                                        }),
                                    },
                                    {
                                        name: 'tag2Id',
                                        label: app.translate(that, 'tag2_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots tagId',
                                            optionValues:
                                                _.map(that.model.get('tags'), function (obj) { return [obj.label, obj.value,]; })
                                            ,
                                        }),
                                    },
                                    {
                                        name: 'tag2AscendingFlank',
                                        label: app.translate(that, 'tag2_asc_flank_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.BooleanCell.extend({
                                            className: 'boolean-cell align-center-cell tag2AscendingFlank',
                                        }),
                                    },
                                    //{
                                    //    name: 'tagResetValue',
                                    //    label: app.translate(that, 'tag_reset_value_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    cell: Backgrid.NumberCell.extend({
                                    //        className: 'number-cell align-center-cell text-3dots tagResetValue',
                                    //        decimals: 2,
                                    //    }),
                                    //},
                                    //{
                                    //    name: 'tagRealAsDigital',
                                    //    label: app.translate(that, 'tag_real_as_digital_col'),
                                    //    editable: true,
                                    //    sortable: false,
                                    //    //cell: 'boolean',
                                    //    cell: Backgrid.BooleanCell.extend({
                                    //        className: 'boolean-cell align-center-cell tagRealAsDigital',
                                    //    }),
                                    //},
                                    {
                                        name: 'active',
                                        label: app.translate(that, 'active_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: 'boolean',
                                    },
                                    {
                                        name: 'actions',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.Cell.extend({
                                            template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                            className: 'actions-cell',
                                            events: {
                                                'click .btn-cell-action': 'cellActionClick'
                                            },

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

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

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

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

                                            checkMode: function () {
                                                var newRow = this.model.get('isNew');
                                                if (newRow) this.setNewRowMode(true);
                                                else this.setNewRowMode(false);
                                            },
                                            setNewRowMode: function (val) {
                                                var btnRemove = this.$el.find('.btn-remove');
                                                var btnSave = this.$el.find('.btn-save');
                                                var btnDiscard = this.$el.find('.btn-discard');

                                                if (val) {
                                                    btnRemove.addClass('hide');
                                                    btnSave.removeClass('hide');
                                                    btnDiscard.removeClass('hide');
                                                    this.model.set('active', true);
                                                } else {
                                                    btnRemove.removeClass('hide');
                                                    btnSave.addClass('hide');
                                                    btnDiscard.addClass('hide');

                                                }

                                            },

                                            cellActionClick: function (e) {
                                                try {
                                                    var target = $(e.target);
                                                    var actionData = target.closest('[data-cell-action]').data('cell-action');
                                                    if (actionData) {

                                                        that.actionOnRowDigitalChangeEvent(this.model, actionData);
                                                    }
                                                }
                                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                            },
                                        }),
                                    },
                                ],
                                collection: that.digitalChangeEvents,
                            });

                            that.$el.find('.digital-change-events-grid-container').append(grid.render().el);
                            //end

                            var grid = that.grids.analogChangeEvents = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'name',
                                        label: app.translate(that, 'name_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            orderSeparator: '',
                                            className: 'string-cell align-center-cell name',
                                        }),
                                    },
                                    {
                                        name: 'tagId',
                                        label: app.translate(that, 'tag_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots tagId',
                                            optionValues:
                                                that.filterTags('Real')
                                            ,
                                        }),
                                    },
                                    {
                                        name: 'lowerThreshold',
                                        label: app.translate(that, 'lower_threshold_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots lowerThreshold',
                                            decimals: 2,
                                        }),
                                    },
                                    {
                                        name: 'upperThreshold',
                                        label: app.translate(that, 'upper_threshold_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots upperThreshold',
                                            decimals: 2,
                                            initialize: function () {
                                                Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change:lowerThreshold', this.checkValue);
                                                this.listenTo(this.model, 'change:upperThreshold', this.checkUpperThresholdValue);
                                            },
                                            checkValue: function () {
                                                if (this.model.get('lowerThreshold')) {
                                                    this.model.set('upperThreshold', (this.model.get('lowerThreshold') + 1));
                                                }
                                            },
                                            checkUpperThresholdValue: function () {
                                                if (this.model.get('upperThreshold') && this.model.get('lowerThreshold')) {
                                                    if (this.model.get('upperThreshold') < this.model.get('lowerThreshold')) {
                                                        this.model.set('upperThreshold', (this.model.get('lowerThreshold') + 1));
                                                    }
                                                }
                                            }
                                        }),
                                    },
                                    {
                                        name: 'delta',
                                        label: app.translate(that, 'delta_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots delta',
                                            decimals: 2,
                                        }),
                                    },
                                    {
                                        name: 'active',
                                        label: app.translate(that, 'active_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: 'boolean',
                                    },
                                    {
                                        name: 'actions',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.Cell.extend({
                                            template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                            className: 'actions-cell',
                                            events: {
                                                'click .btn-cell-action': 'cellActionClick'
                                            },

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

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

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

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

                                            checkMode: function () {
                                                var newRow = this.model.get('isNew');
                                                if (newRow) this.setNewRowMode(true);
                                                else this.setNewRowMode(false);
                                            },
                                            setNewRowMode: function (val) {
                                                var btnRemove = this.$el.find('.btn-remove');
                                                var btnSave = this.$el.find('.btn-save');
                                                var btnDiscard = this.$el.find('.btn-discard');

                                                if (val) {
                                                    btnRemove.addClass('hide');
                                                    btnSave.removeClass('hide');
                                                    btnDiscard.removeClass('hide');
                                                    this.model.set('active', true);
                                                } else {
                                                    btnRemove.removeClass('hide');
                                                    btnSave.addClass('hide');
                                                    btnDiscard.addClass('hide');
                                                    
                                                }

                                                
                                            },

                                            cellActionClick: function (e) {
                                                try {
                                                    var target = $(e.target);
                                                    var actionData = target.closest('[data-cell-action]').data('cell-action');
                                                    if (actionData) {

                                                        that.actionOnRowAnalogChangeEvent(this.model, actionData);
                                                    }
                                                }
                                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                            },
                                        }),
                                    },
                                ],
                                collection: that.analogChangeEvents,
                            });

                            that.$el.find('.analog-change-events-grid-container').append(grid.render().el);


                            var grid = that.grids.analogEdgeEvents = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'name',
                                        label: app.translate(that, 'name_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            orderSeparator: '',
                                            className: 'string-cell align-center-cell name',
                                        }),
                                    },
                                    {
                                        name: 'tagId',
                                        label: app.translate(that, 'tag_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots tagId',
                                            optionValues:
                                                that.filterTags('Real')
                                            ,
                                        }),
                                    },
                                    {
                                        name: 'edge',
                                        label: app.translate(that, 'edge_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.Extension.SelectIntegerCell.extend({
                                            className: 'select-cell align-center-cell text-3dots edge',
                                            optionValues: [
                                                ['Any Edge', 0],
                                                ['Falling Edge', -1],
                                                ['Rise Edge', 1]
                                            ]
                                            ,
                                            initialize: function () {
                                                Backgrid.Extension.SelectIntegerCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change', this.checkValue);
                                            },
                                            checkValue: function () {
                                                if (!this.model.get('edge')) {
                                                    this.model.set('edge', 0);
                                                }
                                            },
                                            
                                        }),
                                    },
                                    {
                                        name: 'lowerThreshold',
                                        label: app.translate(that, 'lower_threshold_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots lowerThreshold',
                                            decimals: 2,
                                            initialize: function () {
                                                Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change', this.checkValue);
                                            },
                                            checkValue: function () {
                                                if (!this.model.get('lowerThreshold')) {
                                                    this.model.set('lowerThreshold', 0);
                                                }
                                            },
                                        }),
                                    },
                                    {
                                        name: 'delta',
                                        label: app.translate(that, 'delta_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots delta',
                                            decimals: 2,
                                            initialize: function () {
                                                Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change', this.checkValue);
                                            },
                                            checkValue: function () {
                                                if (!this.model.get('delta')) {
                                                    this.model.set('delta', 0);
                                                }
                                            },
                                        }),
                                    },
                                    {
                                        name: 'stabilizationTime',
                                        label: app.translate(that, 'stabilization_time_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'integer-cell align-center-cell text-3dots stabilizationTime',
                                            initialize: function () {
                                                Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change', this.checkValue);
                                            },
                                            checkValue: function () {
                                                if (!this.model.get('stabilizationTime')) {
                                                    this.model.set('stabilizationTime', 0);
                                                }
                                            },
                                        }),
                                    },
                                    {
                                        name: 'tolerance',
                                        label: app.translate(that, 'tolerance_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell text-3dots tolerance',
                                            decimals: 2,
                                            initialize: function () {
                                                Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
                                                this.bindEvents();
                                            },
                                            bindEvents: function () {
                                                this.listenTo(this.model, 'change', this.checkValue);
                                            },
                                            checkValue: function () {
                                                if (!this.model.get('tolerance')) {
                                                    this.model.set('tolerance', 0);
                                                }
                                            },
                                        }),
                                    },
                                    {
                                        name: 'active',
                                        label: app.translate(that, 'active_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: 'boolean',
                                    },
                                    {
                                        name: 'actions',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.Cell.extend({
                                            template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                            className: 'actions-cell',
                                            events: {
                                                'click .btn-cell-action': 'cellActionClick'
                                            },

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

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

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

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

                                            checkMode: function () {
                                                var newRow = this.model.get('isNew');
                                                if (newRow) this.setNewRowMode(true);
                                                else this.setNewRowMode(false);
                                            },
                                            setNewRowMode: function (val) {
                                                var btnRemove = this.$el.find('.btn-remove');
                                                var btnSave = this.$el.find('.btn-save');
                                                var btnDiscard = this.$el.find('.btn-discard');

                                                if (val) {
                                                    btnRemove.addClass('hide');
                                                    btnSave.removeClass('hide');
                                                    btnDiscard.removeClass('hide');
                                                    this.model.set('active', true);
                                                } else {
                                                    btnRemove.removeClass('hide');
                                                    btnSave.addClass('hide');
                                                    btnDiscard.addClass('hide');

                                                }


                                            },

                                            cellActionClick: function (e) {
                                                try {
                                                    var target = $(e.target);
                                                    var actionData = target.closest('[data-cell-action]').data('cell-action');
                                                    if (actionData) {

                                                        that.actionOnRowAnalogEdgeEvent(this.model, actionData);
                                                    }
                                                }
                                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                            },
                                        }),
                                    },
                                ],
                                collection: that.analogEdgeEvents,
                            });

                            that.$el.find('.analog-edge-events-grid-container').append(grid.render().el);
                            //appending view to the main container
                            that.append(thatContainer, that.$el);

                            //Call first refresh.
                            that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        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.edgeEvents, 'change', this.edgeEvents_changed)
                .listenTo(this.edgeEvents, 'add remove', this.edgeEvents_addRemove)
                .listenTo(this.edgeEvents, 'fetch', this.edgeEvents_fetch)
                .listenTo(this.digitalChangeEvents, 'change', this.digitalChangeEvents_changed)
                .listenTo(this.digitalChangeEvents, 'add remove', this.digitalChangeEvents_AddRemove)
                .listenTo(this.digitalChangeEvents, 'fetch', this.digitalChangeEvents_fetch)
                .listenTo(this.analogChangeEvents, 'change', this.analogChangeEvents_changed)
                .listenTo(this.analogChangeEvents, 'add remove', this.analogChangeEvents_AddRemove)
                .listenTo(this.analogChangeEvents, 'fetch', this.analogChangeEvents_fetch)
                .listenTo(this.analogEdgeEvents, 'change', this.analogEdgeEvents_changed)
                .listenTo(this.analogEdgeEvents, 'add remove', this.analogEdgeEvents_AddRemove)
                .listenTo(this.analogEdgeEvents, 'fetch', this.analogEdgeEvents_fetch);
        },
        filterTags: function(dataType) {

            var tagsFiltered = _.where(this.model.get('tags'), { dataType: dataType });

            

            return _.map(tagsFiltered, function (obj) { return [obj.label, obj.value,]; });
        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }

            this.refreshItemsColl(opt);

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

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (viewParams) {
            //if (viewParams.sectionParam1)
            //    viewParams.sectionParam1 = parseInt(viewParams.sectionParam1, 10);
            //else
            //    viewParams.sectionParam1 = EquipmentCounters.Models.Main.prototype.defaults.recipeId;

            //this.model.set({
            //    recipeId: viewParams.sectionParam1,
            //});
        },
        refreshItemsColl: function (options) {
            var that = this,
                itemsColl = this.model.get('items'),
                opt = _.extend({}, options, { params: {}, refresh: true, });
            if (opt.reset == true)
                this.model.set('isLoading', true);

            var that = this,
                modelAttrs = this.model.toJSON();

            if ((options) && (options.collection)) {
                that[options.collection].fetch(_.extend(
                    opt,
                    {
                        params: _.extend(
                            modelAttrs,
                            opt.params,
                            {
                                refresh: opt.refresh,
                                reset: opt.reset,
                            }
                        ),
                    }
                ));
            } else {
                that.edgeEvents.fetch(_.extend(
                    opt,
                    {
                        params: _.extend(
                            modelAttrs,
                            opt.params,
                            {
                                refresh: opt.refresh,
                                reset: opt.reset,
                            }
                        ),
                    }
                ));

                that.digitalChangeEvents.fetch(_.extend(
                    opt,
                    {
                        params: _.extend(
                            modelAttrs,
                            opt.params,
                            {
                                refresh: opt.refresh,
                                reset: opt.reset,
                            }
                        ),
                    }
                ));

                that.analogChangeEvents.fetch(_.extend(
                    opt,
                    {
                        params: _.extend(
                            modelAttrs,
                            opt.params,
                            {
                                refresh: opt.refresh,
                                reset: opt.reset,
                            }
                        ),
                    }
                ));

                that.analogEdgeEvents.fetch(_.extend(
                    opt,
                    {
                        params: _.extend(
                            modelAttrs,
                            opt.params,
                            {
                                refresh: opt.refresh,
                                reset: opt.reset,
                            }
                        ),
                    }
                ));
            }
        },

        addNewEdgeEvent: function () {
            this.edgeEvents.unshift({
                id: -1,
                isNew: true,
            });
        },
        addNewDigitalChangeEvent: function () {
            this.digitalChangeEvents.unshift({
                id: -1,
                isNew: true,
            });
        },
        addNewAnalogChangeEvent: function () {
            this.analogChangeEvents.unshift({
                id: -1,
                isNew: true,
            });
        },addNewAnalogEdgeEvent: function () {
            this.analogEdgeEvents.unshift({
                id: -1,
                isNew: true,
            });
        },

        discardRowEdgeEvent: function (m) {
            //to discard just remove the model from the collection.
            m.collection.remove(m);
        },
        discardRowDigitalChangeEvent: function (m) {
            //to discard just remove the model from the collection.
            m.collection.remove(m);
        },
        discardRow: function (m) {
            //to discard just remove the model from the collection.
            m.collection.remove(m);
        },

        removeRowEdgeEvent: function (model) {
            var that = this;
            that.edgeEvents.removeItem(
                model.get('id')
                , function (coll, data) {
                    app.views.topMessages.showMessage(app.translate([app, that], 'ITEM_DELETED'), { stay: 10000, });
                    that._refresh({collection: 'edgeEvents'});
                }
                , function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({ collection: 'edgeEvents' });
                }
            );
        },
        removeRowDigitalChangeEvent: function (model) {
            var that = this;
            that.digitalChangeEvents.removeItem(
                model.get('id')
                , function (coll, data) {
                    app.views.topMessages.showMessage(app.translate([app, that], 'ITEM_DELETED'), { stay: 10000, });
                    that._refresh({collection: 'digitalChangeEvents'});
                }
                , function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({ collection: 'digitalChangeEvents' });
                }
            );
        },
        removeRowAnalogChangeEvent: function (model) {
            var that = this;
            that.analogChangeEvents.removeItem(
                model.get('id')
                , function (coll, data) {
                    app.views.topMessages.showMessage(app.translate([app, that], 'ITEM_DELETED'), { stay: 10000, });
                    that._refresh({collection: 'analogChangeEvents'});
                }
                , function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({collection: 'AnalogChangeEvents'});
                }
            );
        },
        removeRowAnalogEdgeEvent: function (model) {
            var that = this;
            that.analogEdgeEvents.removeItem(
                model.get('id')
                , function (coll, data) {
                    app.views.topMessages.showMessage(app.translate([app, that], 'ITEM_DELETED'), { stay: 10000, });
                    that._refresh({ collection: 'analogEdgeEvents' });
                }
                , function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({ collection: 'analogEdgeEvents' });
                }
            );
        },

        saveRowEdgeEvent: function (m) {
            var that = this;
            that.edgeEvents.upsertItem(null, [
                { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                { name: 'tagAscendingFlank', type: 'BIT', value: (m.get('tagAscendingFlank')) ? m.get('tagAscendingFlank') : 0 },
                { name: 'tagId', type: 'INT', value: m.get('tagId') },
                { name: 'name', type: 'VARCHAR', value: m.get('name') },
                { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },

            ], function (ref, ids) {
                m.set({ id: ids[0], isNew: false }, { avoidSync: true });
                that._refresh({collection: 'edgeEvents'});
            }, function (coll, msg) {
                app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                that._refresh({collection: 'edgeEvents'});
            });
        },
        saveRowDigitalChangeEvent: function (m) {
            var that = this;
            that.digitalChangeEvents.upsertItem(null, [
                { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                { name: 'tag2AscendingFlank', type: 'BIT', value: (m.get('tag2AscendingFlank')) ? m.get('tag2AscendingFlank') : 0 },
                { name: 'tag2Id', type: 'INT', value: m.get('tag2Id') },
                { name: 'tagAscendingFlank', type: 'BIT', value: (m.get('tagAscendingFlank')) ? m.get('tagAscendingFlank') : 0 },
                { name: 'tagId', type: 'INT', value: m.get('tagId') },
                { name: 'name', type: 'VARCHAR', value: m.get('name') },
                { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
            ], function (ref, ids) {
                m.set({ id: ids[0], isNew: false }, { avoidSync: true });
                that._refresh({collection: 'digitalChangeEvents'});
            }, function (coll, msg) {
                app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                that._refresh({collection: 'digitalChangeEvents'});
            });
        },
        saveRowAnalogChangeEvent: function (m) {
            var that = this;
            that.analogChangeEvents.upsertItem(null, [
                { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                { name: 'delta', type: 'FLOAT', value: m.get('delta') },
                { name: 'upperThreshold', type: 'FLOAT', value: m.get('upperThreshold') },
                { name: 'lowerThreshold', type: 'FLOAT', value: m.get('lowerThreshold') },
                { name: 'tagId', type: 'INT', value: m.get('tagId') },
                { name: 'name', type: 'VARCHAR', value: m.get('name') },
                { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
            ], function (ref, ids) {
                m.set({ id: ids[0], isNew: false }, { avoidSync: true });
                that._refresh({collection: 'analogChangeEvents'});
            }, function (coll, msg) {
                app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                that._refresh({ collection: 'analogChangeEvents'});
            });
        },
        saveRowAnalogEdgeEvent: function (m) {
            var that = this;
            that.analogEdgeEvents.upsertItem(null, [
                { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                { name: 'delta', type: 'FLOAT', value: m.get('delta') },
                { name: 'lowerThreshold', type: 'FLOAT', value: m.get('lowerThreshold') },
                { name: 'tolerance', type: 'FLOAT', value: m.get('tolerance') },
                { name: 'stabilizationTime', type: 'INT', value: m.get('stabilizationTime') },
                { name: 'edge', type: 'INT', value: m.get('edge') },
                { name: 'tagId', type: 'INT', value: m.get('tagId') },
                { name: 'name', type: 'VARCHAR', value: m.get('name') },
                { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
            ], function (ref, ids) {
                m.set({ id: ids[0], isNew: false }, { avoidSync: true });
                that._refresh({ collection: 'analogEdgeEvents' });
            }, function (coll, msg) {
                app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                that._refresh({ collection: 'analogEdgeEvents' });
            });
        },


        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;
            }
        },
        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) ? error.stack : new Error(error).stack); }
        },
        stopAutoRefresh: function () {
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }
            this.autoRefresh.enabled = false;
        },
        bindViewScopedEvents: function () {
        },
        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.stopAutoRefresh();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        hideSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.hide();
            });
        },
        preRender: function () {
            //app.models.subnavbar.setAll(false);
            //app.models.subnavbar.set('sections', '12');
            //app.models.subnavbar.set('subnavbar', true);
        },
        reRender: function () {
            this.startAutoRefresh();
        },

        actionOnRowEdgeEvent: function (model, action) {
            try {
                
                switch (action.toUpperCase()) {
                    case 'DELETE':
                        var that = this,
                            modal = new Modal.Views.Main({
                                focusOk: false,
                                focusSelector: '#btn-cancel',
                                title: app.translate([this, app], "delete_item_modal_confirm_title"),
                                message: app.translate([this, app], "delete_item_modal_confirm_message"),
                                buttons_type: "CONTINUE-CANCEL",
                            });

                        this.listenToOnce(modal, "continue", function (modal) {
                            try {
                                that.removeRowEdgeEvent(model);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        modal.show();
                        break;
                    case 'SAVE':
                        this.saveRowEdgeEvent(model);
                        break;
                    case 'DISCARD':
                        this.discardRow(model);
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        actionOnRowDigitalChangeEvent: function (model, action) {
            try {
                
                switch (action.toUpperCase()) {
                    case 'DELETE':
                        var that = this,
                            modal = new Modal.Views.Main({
                                focusOk: false,
                                focusSelector: '#btn-cancel',
                                title: app.translate([this, app], "delete_item_modal_confirm_title"),
                                message: app.translate([this, app], "delete_item_modal_confirm_message"),
                                buttons_type: "CONTINUE-CANCEL",
                            });

                        this.listenToOnce(modal, "continue", function (modal) {
                            try {
                                that.removeRowDigitalChangeEvent(model);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        modal.show();
                        break;
                    case 'SAVE':
                        this.saveRowDigitalChangeEvent(model);
                        break;
                    case 'DISCARD':
                        this.discardRow(model);
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        actionOnRowAnalogChangeEvent: function (model, action) {
            
            try {
                
                switch (action.toUpperCase()) {
                    case 'DELETE':
                        var that = this,
                            modal = new Modal.Views.Main({
                                focusOk: false,
                                focusSelector: '#btn-cancel',
                                title: app.translate([this, app], "delete_item_modal_confirm_title"),
                                message: app.translate([this, app], "delete_item_modal_confirm_message"),
                                buttons_type: "CONTINUE-CANCEL",
                            });

                        this.listenToOnce(modal, "continue", function (modal) {
                            try {
                                that.removeRowAnalogChangeEvent(model);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        modal.show();
                        break;
                    case 'SAVE':
                        this.saveRowAnalogChangeEvent(model);
                        break;
                    case 'DISCARD':
                        this.discardRow(model);
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
            actionOnRowAnalogEdgeEvent: function (model, action) {

                try {

                    switch (action.toUpperCase()) {
                        case 'DELETE':
                            var that = this,
                                modal = new Modal.Views.Main({
                                    focusOk: false,
                                    focusSelector: '#btn-cancel',
                                    title: app.translate([this, app], "delete_item_modal_confirm_title"),
                                    message: app.translate([this, app], "delete_item_modal_confirm_message"),
                                    buttons_type: "CONTINUE-CANCEL",
                                });

                            this.listenToOnce(modal, "continue", function (modal) {
                                try {
                                    that.removeRowAnalogEdgeEvent(model);
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            });

                            modal.show();
                            break;
                        case 'SAVE':
                            this.saveRowAnalogEdgeEvent(model);
                            break;
                        case 'DISCARD':
                            this.discardRow(model);
                            break;
                    }
                }
                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            },

        addNewEdgeEvent_click: function (e) {
            try {
                this.addNewEdgeEvent();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        addNewDigitalChangeEvent_click: function (e) {
            try {
                this.addNewDigitalChangeEvent();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        addNewAnalogChangeEvent_click: function (e) {
            try {
                this.addNewAnalogChangeEvent();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        addNewAnalogEdgeEvent_click: function (e) {
            try {
                this.addNewAnalogEdgeEvent();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        edgeEvents_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            var isNewRow = m.get('isNew');


           
            if (!fromFetch && !isNewRow && !avoidSync) {
                that.edgeEvents.upsertItem(m.get('id'), [
                    { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                    { name: 'tagAscendingFlank', type: 'BIT', value: (m.get('tagAscendingFlank')) ? m.get('tagAscendingFlank') : 0 },
                    { name: 'tagId', type: 'INT', value: m.get('tagId') },
                    { name: 'name', type: 'VARCHAR', value: m.get('name') },
                    { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
                ], function (ref, ids) {
                }, function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({ collection: 'edgeEvents'});
                });
            }
        },
        digitalChangeEvents_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            var isNewRow = m.get('isNew');

            if (!fromFetch && !isNewRow && !avoidSync) {
                that.digitalChangeEvents.upsertItem(m.get('id'), [
                    { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                    { name: 'tag2AscendingFlank', type: 'BIT', value: (m.get('tag2AscendingFlank')) ? m.get('tag2AscendingFlank') : 0 },
                    { name: 'tag2Id', type: 'INT', value: m.get('tag2Id') },
                    { name: 'tagAscendingFlank', type: 'BIT', value: (m.get('tagAscendingFlank')) ? m.get('tagAscendingFlank') : 0 },
                    { name: 'tagId', type: 'INT', value: m.get('tagId') },
                    { name: 'name', type: 'VARCHAR', value: m.get('name') },
                    { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
                ], function (ref, ids) {
                }, function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({collection: 'digitalChangeEvents'});
                });
            }
        },
        analogChangeEvents_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            var isNewRow = m.get('isNew');


           
            if (!fromFetch && !isNewRow && !avoidSync) {
                that.analogChangeEvents.upsertItem(m.get('id'), [
                    { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                    { name: 'delta', type: 'FLOAT', value: m.get('delta') },
                    { name: 'upperThreshold', type: 'FLOAT', value: m.get('upperThreshold') },
                    { name: 'lowerThreshold', type: 'FLOAT', value: m.get('lowerThreshold') },
                    { name: 'tagId', type: 'INT', value: m.get('tagId') },
                    { name: 'name', type: 'VARCHAR', value: m.get('name') },
                    { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
                ], function (ref, ids) {
                }, function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({collection: 'analogChangeEvents'});
                });
            }
        },
        analogEdgeEvents_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            var isNewRow = m.get('isNew');



            if (!fromFetch && !isNewRow && !avoidSync) {
                that.analogEdgeEvents.upsertItem(m.get('id'), [
                    { name: 'active', type: 'BIT', value: (m.get('active')) ? m.get('active') : 0 },
                    { name: 'tolerance', type: 'FLOAT', value: m.get('stabilizationTime') },
                    { name: 'stabilizationTime', type: 'INT', value: m.get('stabilizationTime') },
                    { name: 'delta', type: 'FLOAT', value: m.get('delta') },
                    { name: 'lowerThreshold', type: 'FLOAT', value: m.get('lowerThreshold') },
                    { name: 'edge', type: 'INT', value: m.get('edge') },
                    { name: 'tagId', type: 'INT', value: m.get('tagId') },
                    { name: 'name', type: 'VARCHAR', value: m.get('name') },
                    { name: 'ihId', type: 'INT', value: app.models.ihDataSources.get("id") },
                ], function (ref, ids) {
                }, function (coll, msg) {
                    app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                    that._refresh({ collection: 'analogChangeEvents' });
                });
            }
        },

        edgeEvents_fetch: function (coll, resp) {
            try {
                this.model.set({
                    hasData: (this.edgeEvents.length > 0),
                    isLoading: false,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        digitalChangeEvents_fetch: function (coll, resp) {
            try {
                this.model.set({
                    hasData: (this.digitalChangeEvents.length > 0),
                    isLoading: false,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        analogChangeEvents_fetch: function (coll, resp) {
            try {
                this.model.set({
                    hasData: (this.analogChangeEvents.length > 0),
                    isLoading: false,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        analogEdgeEvents_fetch: function (coll, resp) {
            try {
                this.model.set({
                    hasData: (this.analogEdgeEvents.length > 0),
                    isLoading: false,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },

        //collectionAddRemove: function (m, b, c) {
        //    if (m.get('isNew'))
        //        this.model.set('hasData', (this.model.get('items').length > 0));
        //},
        model_change_pickers: function (model, value, opt) {
            try {
                var params = this.model.toJSON();

                this.refreshItemsColl({
                    reset: true,
                    params: _.extend(
                        {},
                        params,
                        {}
                    ),
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
    });

    //EDGE EVENTS
    EventTypes.Models.EdgeEvent = Backbone.Epoxy.Model.extend({
        defaults: {
            id: null,
            name: null,
            tagId: null,
            tagAscendingFlank: null,
            active: null
        },

        parse: function (obj) {
            return {
                id: obj.Id,
                name: obj.Name,
                tagId: obj.TagId,
                tagAscendingFlank: obj.TagAscendingFlank,
                active: obj.Active,
            };
        },
    });

    EventTypes.Collections.EdgeEvents = Backbone.Collection.extend({
        model: EventTypes.Models.EdgeEvent,
        fetch: function (opt) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                options = opt ? _.clone(opt) : {};


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

            qp.Add('@fromRow', 'INT', 0);
            qp.Add('@rowsToFetch', 'INT', 999999);


            Core.Json.CallProcedure(
                app.DatabaseNames.System + '.EVENT.GetDigitalEdgeEvents',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

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

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

                                var method = 'set';


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

                                that[method](newColl, { from: 'fetch' })
                                    .trigger('fetch', that, 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); }
                    },
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        upsertItem: function (id, props, success, erro) {
            var that = this;
            var QP = new QueryParameters();
            QP.Add("Id", "INT", id);

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

            Core.Json.CallProcedure(app.DatabaseNames.System + ".EVENT.UpsertDigitalEdgeEvent", 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 {
                            var ids = _.pluck(data, 'Id');

                            if (success != null && _.isFunction(success))
                                success.call(this,that, ids);
                        }
                    } else {
                        if (!data.Message)
                            data.Message = 'UNKNOWN';

                        error.call(this, that, data.Message);
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        removeItem: function (id, success, error) {
            var model = this.get(id);
            if (model) {
                var that = this;
                var QP = new QueryParameters();

                QP.Add('@id', 'INT', id);

                Core.Json.CallProcedure(app.DatabaseNames.System + '.EVENT.RemoveDigitalEdgeEvent', QP, {
                    onSuccess: function (data) {
                        if (data && data.Table && data.Table.length > 0) {
                            var data = data.Table[0];

                            if (data.Id) {
                                if (success != null && _.isFunction(success))
                                    success.call(this, that, data.Id);
                            }
                            else {
                                if (data.Message)
                                    error.call(this, that, data.Message);
                                else
                                    error.call(this, that);
                            }
                        } else {
                            error.call(this, that);
                        }
                    },
                    onError: function (data) {
                        if (error != null && _.isFunction(error))
                            error.call(this, that);
                    },
                    Async: true,
                    Secured: true,
                }, app.ConnectionStrings.app);
            }
        },
    });

    //DIGITAL CHANGE EVENTS
        EventTypes.Models.DigitalChangeEvent = Backbone.Epoxy.Model.extend({
            defaults: {
                id: null,
                name: null,
                tagId: null,
                tagAscendingFlank: null,
                tag2Id: null,
                tag2AscendingFlank: null,
                active: null
            },
            parse: function (obj) {
                return {
                    id: obj.Id,
                    name: obj.Name,
                    tagId: obj.TagId,
                    tagAscendingFlank: obj.TagAscendingFlank,
                    tag2Id: obj.Tag2Id,
                    tag2AscendingFlank: obj.Tag2AscendingFlank,
                    active: obj.Active,
                };
            },
            
    });

    EventTypes.Collections.DigitalChangeEvents = Backbone.Collection.extend({
        model: EventTypes.Models.DigitalChangeEvent,
        fetch: function (opt) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                options = opt ? _.clone(opt) : {};


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

            qp.Add('@fromRow', 'INT', 0);
            qp.Add('@rowsToFetch', 'INT', 999999);


            Core.Json.CallProcedure(
                app.DatabaseNames.System + '.EVENT.GetDigitalStateEvents',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

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

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

                                var method = 'set';


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

                                that[method](newColl, { from: 'fetch' })
                                    .trigger('fetch', that, 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); }
                    },
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        upsertItem: function (id, props, success, erro) {
            var that = this;
            var QP = new QueryParameters();
            QP.Add("Id", "INT", id);

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

            Core.Json.CallProcedure(app.DatabaseNames.System + ".EVENT.UpsertDigitalStateEvent", 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 {
                            var ids = _.pluck(data, 'Id');

                            if (success != null && _.isFunction(success))
                                success.call(this, that, ids);
                        }
                    } else {
                        if (!data.Message)
                            data.Message = 'UNKNOWN';

                        error.call(this, that, data.Message);
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        removeItem: function (id, success, error) {
            var model = this.get(id);
            if (model) {
                var that = this;
                var QP = new QueryParameters();

                QP.Add('@id', 'INT', id);

                Core.Json.CallProcedure(app.DatabaseNames.System + '.EVENT.RemoveDigitalStateEvent', QP, {
                    onSuccess: function (data) {
                        if (data && data.Table && data.Table.length > 0) {
                            var data = data.Table[0];

                            if (data.Id) {
                                if (success != null && _.isFunction(success))
                                    success.call(this, that, data.Id);
                            }
                            else {
                                if (data.Message)
                                    error.call(this, that, data.Message);
                                else
                                    error.call(this, that);
                            }
                        } else {
                            error.call(this, that);
                        }
                    },
                    onError: function (data) {
                        if (error != null && _.isFunction(error))
                            error.call(this, that);
                    },
                    Async: true,
                    Secured: true,
                }, app.ConnectionStrings.app);
            }
        },
    });


    //ANALOG CHANGE EVENTS
    EventTypes.Models.AnalogChangeEvent = Backbone.Epoxy.Model.extend({
        defaults: {
            id: null,
            name: null,
            tagId: null,
            lowerThreshold: null,
            upperThreshold: null,
            delta: null,
            active: null
        },

        parse: function (obj) {
            return {
                id: obj.Id,
                name: obj.Name,
                tagId: obj.TagId,
                lowerThreshold: obj.LowerThreshold,
                upperThreshold: obj.UpperThreshold,
                delta: obj.Delta,
                active: obj.Active,
            };
        },
    });

    EventTypes.Collections.AnalogChangeEvents = Backbone.Collection.extend({
        model: EventTypes.Models.AnalogChangeEvent,
        fetch: function (opt) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                options = opt ? _.clone(opt) : {};


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

            qp.Add('@fromRow', 'INT', 0);
            qp.Add('@rowsToFetch', 'INT', 999999);


            Core.Json.CallProcedure(
                app.DatabaseNames.System + '.EVENT.GetAnalogChangeEvents',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

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

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

                                var method = 'set';


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

                                that[method](newColl, { from: 'fetch' })
                                    .trigger('fetch', that, 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); }
                    },
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        upsertItem: function (id, props, success, erro) {
            var that = this;
            var QP = new QueryParameters();
            QP.Add("Id", "INT", id);

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

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

                        if (data && data.Message) {
                            var failureCode = "UNKNOWN";
                            failureCode = (data[0].Message) ? data[0].Message : failureCode;

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

                            if (success != null && _.isFunction(success))
                                success.call(this, that, ids);
                        }
                    } else {
                        if (!data.Message)
                            data.Message = 'UNKNOWN';

                        error.call(this, that, data.Message);
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        removeItem: function (id, success, error) {
            var model = this.get(id);
            if (model) {
                var that = this;
                var QP = new QueryParameters();

                QP.Add('@id', 'INT', id);

                Core.Json.CallProcedure(app.DatabaseNames.System + '.EVENT.RemoveAnalogChangeEvent', QP, {
                    onSuccess: function (data) {
                        if (data && data.Table && data.Table.length > 0) {
                            var data = data.Table[0];

                            if (data.Id) {
                                if (success != null && _.isFunction(success))
                                    success.call(this, that, data.Id);
                            }
                            else {
                                if (data.Message)
                                    error.call(this, that, data.Message);
                                else
                                    error.call(this, that);
                            }
                        } else {
                            error.call(this, that);
                        }
                    },
                    onError: function (data) {
                        if (error != null && _.isFunction(error))
                            error.call(this, that);
                    },
                    Async: true,
                    Secured: true,
                }, app.ConnectionStrings.app);
            }
        },
    });


        //ANALOG EDGE EVENTS
        EventTypes.Models.AnalogEdgeEvent = Backbone.Epoxy.Model.extend({
            defaults: {
                id: null,
                name: null,
                tagId: null,
                edge: null,
                lowerThreshold: null,
                delta: null,
                stabilizationTime: null,
                tolerance: null,
                active: null
            },

            parse: function (obj) {
                return {
                    id: obj.Id,
                    name: obj.Name,
                    tagId: obj.TagId,
                    edge: obj.Edge,
                    lowerThreshold: obj.LowerThreshold,
                    delta: obj.Delta,
                    stabilizationTime: obj.Stabilizationtime,
                    tolerance: obj.Tolerance,
                    active: obj.Active,
                };
            },
        });

        EventTypes.Collections.AnalogEdgeEvents = Backbone.Collection.extend({
            model: EventTypes.Models.AnalogEdgeEvent,
            fetch: function (opt) {
                var that = this,
                    qp = new Core.Database.QueryParameters(),
                    options = opt ? _.clone(opt) : {};


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

                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', 999999);


                Core.Json.CallProcedure(
                    app.DatabaseNames.System + '.EVENT.GetAnalogEdgeEvents',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

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

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

                                    var method = 'set';


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

                                    that[method](newColl, { from: 'fetch' })
                                        .trigger('fetch', that, 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); }
                        },
                        Async: options.async,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );

                return this;
            },
            upsertItem: function (id, props, success, erro) {
                var that = this;
                var QP = new QueryParameters();
                QP.Add("Id", "INT", id);

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

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

                            if (data && data.Message) {
                                var failureCode = "UNKNOWN";
                                failureCode = (data[0].Message) ? data[0].Message : failureCode;

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

                                if (success != null && _.isFunction(success))
                                    success.call(this, that, ids);
                            }
                        } else {
                            if (!data.Message)
                                data.Message = 'UNKNOWN';

                            error.call(this, that, data.Message);
                        }
                    },
                    Async: true,
                    Secured: true,
                }, app.ConnectionStrings.app);
            },
            removeItem: function (id, success, error) {
                var model = this.get(id);
                if (model) {
                    var that = this;
                    var QP = new QueryParameters();

                    QP.Add('@id', 'INT', id);

                    Core.Json.CallProcedure(app.DatabaseNames.System + '.EVENT.RemoveAnalogEdgeEvent', QP, {
                        onSuccess: function (data) {
                            if (data && data.Table && data.Table.length > 0) {
                                var data = data.Table[0];

                                if (data.Id) {
                                    if (success != null && _.isFunction(success))
                                        success.call(this, that, data.Id);
                                }
                                else {
                                    if (data.Message)
                                        error.call(this, that, data.Message);
                                    else
                                        error.call(this, that);
                                }
                            } else {
                                error.call(this, that);
                            }
                        },
                        onError: function (data) {
                            if (error != null && _.isFunction(error))
                                error.call(this, that);
                        },
                        Async: true,
                        Secured: true,
                    }, app.ConnectionStrings.app);
                }
            },
        });


    ////subview for the subnavbar controls
    //EventTypes.Views.SubnavBarControls = Backbone.Epoxy.View.extend({
    //    id: 'event-types-subnavbar-controls',
    //    title: '',
    //    template: 'event-types',

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

    //        this.bindEvents();
    //    },
    //    render: function (container, onComplete) {
    //        var that = this;
    //        var thatContainer = (container) ? container : (this.options.container) ? this.options.container : null;
    //        var onViewComplete = (onComplete) ? onComplete : function () { };

    //        //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/configuration/' + 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;

    //                var ctx = {
    //                    editable: (($.inArray('AdminUserRole', app.models.user.get('roles')) != -1
    //                        || $.inArray('SupervisorUserRole', app.models.user.get('roles')) != -1) ? true : false),
    //                };

    //                //loading the view and appeding it to the views's $el.
    //                that.$el.html(tmp(
    //                    _.extend({}, ctx, (that.model) ? that.model.toJSON() : {})
    //                ));

    //                that.applyBindings();

    //                that.append(thatContainer, that.$el);

    //            }, true, customPath);
    //        }, customPath, 'subnavbar_controls');

    //    },
    //    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
    //    },

    //    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;
    //        }
    //    },
    //    close: function () {
    //        this.options.state = app.view_states.closed;

    //        this.remove();
    //        this.unbind();
    //    },
    //    show: function () {
    //        this.options.state = app.view_states.shown;

    //        this.bindEvents();
    //        this.$el.show();
    //    },
    //    hide: function () {
    //        this.options.state = app.view_states.hidden;

    //        this.$el.hide();
    //        this.unbind();
    //        this.stopListening();
    //    },
    //});

    // Required, return the module for AMD compliance.
    return EventTypes;

});
