//SCREEN-BOILERPLATE

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

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

  //templates-loader: this loads templates async.
  "js/templates-loader",

  "modules/modal",

  "handlebars",
  'moment',

  "js/jquery.floatThead/jquery.floatThead",
  "js/jquery.mask",

  //"backbone.paginator", 
  "backgrid/infinator",
],

function (app, T, Modal, Handlebars, moment) {

    //replace all "TagsExportConfiguration" with your view's name.
    var TagsExportConfiguration = { Models: {}, Views: {}, Collections: {} }; 

    TagsExportConfiguration.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            procedure: '',
            allTagsEnabled: null,
            tags: null,
            searchedTags: null,
            exportConfig: null,
        },
    });    

    //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.
    TagsExportConfiguration.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "tags-export-configuration"; 
        } catch (Error) { }
    }

    TagsExportConfiguration.enums = {};
    TagsExportConfiguration.enums.sources = { UI: "ui", FETCH: "fetch", UNKNOWN: "unknown", INTERNAL: "internal" }; 

    TagsExportConfiguration.Models.Tag = Backbone.Model.extend({
        defaults: {
            id: null,
            agentId: null, 
            rownum: null, 
            agentType: null,
            internal: null,
            agentName: null,
            name: null,
            alias: null,
            lineColor: null,
            scanRate: null,
            dataType: null,
            stringLength: null,
            unit: null,
            minUnit: null,
            maxUnit: null,
            enabled: null,
            _enabled: null,
            lastValue: null,

            grid_status: null,
            grid_message: null,
            grid_can_commit: true,
            lock_set: null, 

            changedAttrs: [],
        },
    });

    TagsExportConfiguration.Models.ExportConfig = Backbone.Epoxy.Model.extend({
        defaults: {
            active: null,
            targetConnectionString: null,
            interval: null,
            timeout: null,
            lastExportTimestamp: null,
            lastExportMessageCode: null,
            lastExportMessageText: null,
            lastExportStatus: null,
            lastModificationTimestamp: null,
            lastModificationUserName: null,
            volume: null,

            editing: false,
        },
        computeds: {
            intervalFormated: {
                deps: ['interval'],
                get: function (interval) {
                    var h = Math.floor(interval / 3600);
                    var m = Math.floor(interval % 3600 / 60);
                    var s = interval % 60;

                    return ((h < 10) ? '0' + h : h)
                            + ':' + ((m < 10) ? '0' + m : m)
                            + ':' + ((s < 10) ? '0' + s : s);
                },
                set: function (value) {
                    var split = value.split(':');

                    _.each(split, function (item, i) {
                        split[i] = '00'.slice(item.length) + item;
                    });

                    value = split.join(":");

                    value = value + '00:00:00'.slice(value.length);

                    split = value.split(':');

                    return { interval: parseInt(split[0], 10) * 60 * 60 + parseInt(split[1], 10) * 60 + parseInt(split[2], 10), };
                }
            },
            timeoutFormated: {
                deps: ['timeout'],
                get: function (timeout) {
                    var h = Math.floor(timeout / 3600);
                    var m = Math.floor(timeout % 3600 / 60);
                    var s = timeout % 60;

                    return ((h < 10) ? '0' + h : h)
                            + ':' + ((m < 10) ? '0' + m : m)
                            + ':' + ((s < 10) ? '0' + s : s);
                },
                set: function (value) {
                    var split = value.split(':');

                    _.each(split, function (item, i) {
                        split[i] = '00'.slice(item.length) + item;
                    });

                    value = split.join(":");

                    value = value + '00:00:00'.slice(value.length);

                    split = value.split(':');

                    return { timeout: parseInt(split[0], 10) * 60 * 60 + parseInt(split[1], 10) * 60 + parseInt(split[2], 10), };
                }
            },
        },

        editAttrs: [
            'active', 
            'interval', 
            'targetConnectionString',
            'timeout',
        ],
        i18n: { global: null, },
        lastFetch: null,

        fetch: function (opt) {
            var that = this;

            Core.Json.CallProcedure(
                app.DatabaseNames.IH + '.WEB.GetExportConfig',
                null,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp && resp.Table) {
                                that.lastFetch = that.parse(resp.Table[0]);

                                var obj = _.extend({}, that.lastFetch);

                                if (that.get('editing') == true) {
                                    _.each(that.editAttrs, function (item) {
                                        delete obj[item];
                                    });
                                }

                                that.set(obj, { from: 'fetch', });
                                that.trigger('fetch', that, resp, opt);
                            }
                            else {
                                console.error('Invalid server response.');
                            }
                        }
                        catch (Error) { console.error(Error); }
                    },
                    onError: function (errorMsg) {
                        try {
                            console.error(errorMsg);
                        }
                        catch (Error) { console.error(Error); }
                    },
                    Async: true,
                    //Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        parse: function (obj) {
            var objp = {
                active: obj.Active,
                targetConnectionString: obj.TargetConnectionString,
                interval: obj.Interval,
                timeout: obj.Timeout,
                lastExportTimestamp: obj.LastExportTimestampString,
                lastExportMessageCode: obj.LastExportMessage,
                lastExportMessageText: app.translate(this, obj.LastExportMessage),
                lastExportStatus: obj.LastExportStatus,
                lastModificationTimestamp: obj.LastModificationTimestampString,
                lastModificationUserName: obj.LastModificationUserName,
                volume: obj.Volume,
            };

            return objp;
        },
        cancelEdition: function () {
            this.set(_.extend({ editing: false, }, this.lastFetch));
        },
        confirmEdition: function (opt) {
            var that = this,
                //attrs = this.toJSON(),
                qp = new Core.Database.QueryParameters(),
                attrs = this.toJSON();

            if (!opt) opt = {};

            _.each(that.editAttrs, function (attr) {
                qp.Add('@' + attr, 'VARCHAR', attrs[attr]);
            });

            if (opt.params) {
                for (var pn in opt.params)
                    qp.Add('@' + pn, 'VARCHAR', opt.params[pn]);
            }
                

            //if (opt.params) {
            //    for (var pn in opt.params)
            //        qp.Add('@' + pn, 'VARCHAR', opt.params[pn]);

                //qp.Add('@active', 'BIT', attrs.active);
                //qp.Add('@targetConnectionString', 'VARCHAR', attrs.targetConnectionString);
                //qp.Add('@interval', 'INT', attrs.interval);
                //qp.Add('@timeout', 'INT', attrs.timeout);

                Core.Json.CallProcedure(
                    app.DatabaseNames.IH + '.WEB.SaveExportConfig',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (resp) {
                                    if (!resp.Message) {
                                        if (resp.Table) {
                                            that.lastFetch = that.parse(resp.Table[0]);

                                            that.set(that.parse(resp.Table[0]), { from: 'fetch', });

                                            if (opt.success) opt.success(that, resp);
                                            that.trigger('fetch', that, resp, opt);
                                        }
                                        else {
                                            console.error('Invalid server response.');

                                            if (opt.error) opt.error(that, resp, 'Invalid server response.');
                                        }
                                    }
                                    else {
                                        console.error(resp.Message);

                                        if (opt.error) opt.error(this, resp, resp.Message);
                                    }
                                }
                                else {
                                    console.error('Invalid server response.');

                                    if (opt.error) opt.error(this, resp, 'Invalid server response.');
                                }
                            }
                            catch (Error) { console.error(Error); }
                        },
                        onError: function (errorMsg) {
                            try {
                                console.error(errorMsg);
                            }
                            catch (Error) { console.error(Error); }
                        },
                        Async: true,
                        //Secured: true,
                    },
                    app.ConnectionStrings.app
                );
            //}

            return this;
        },
    });

    TagsExportConfiguration.Collections.ChangedTags = Backbone.Collection.extend({
        model: TagsExportConfiguration.Models.Tag,
        initialize: function () {
            this.listenTo(this, "change", this._tagChanged);
            this.listenTo(this, "add", this._tagAdded);
        },
        _tagChanged: function (model) {
            var changed = [];
            for (var i in model.changed) changed.push(i);
            model.set("changedAttrs", _.union(model.get("changedAttrs"), changed), { silent: true });
        },
        _tagAdded: function (model) {
            var changed = [];
            for (var i in model.changed) changed.push(i);
            model.set("changedAttrs", _.union(model.get("changedAttrs"), changed), { silent: true });
        }, 
    }); 

    TagsExportConfiguration.Collections.Tags = Backbone.Collection.extend({
        model: TagsExportConfiguration.Models.Tag,
        initialize: function (opt) {
            this.options = this.options || {};
            _.extend(this.options, {
                isFetching: false,
                currentPage: 1,
                pageSize: 50,
                fixedParameters: [],

                transaction_timestamp: null, 
            }, opt);

            _.bindAll(this); 
        }, 
        resetPagination: function(force){
            if (!this.options.isFetching || force == true){
                this.options.currentPage = 1; 
            }else{
                _.delay(this.resetPagination, 100); 
            }
        },
        getNextPage: function (options) {
            if (!this.options.isFetching) {
                this.options.currentPage++;
                options = (_.isObject(options)) ? options : {}; 
                this.fetch(_.extend(options, {
                    preprocessResponse: (this.options.preprocessResponseGetNextPage) ? this.options.preprocessResponseGetNextPage : null
                }));
            }
        },
        setFixedParameters: function (params) {
            var fixedParams = this.options.fixedParameters; 

            for (var i = 0, len = params.length; i < len; i++) {
                fixedParams = _.without(fixedParams, _.findWhere(fixedParams, { Name: params[i].Name }));
                fixedParams.push(params[i]); 
            }

            this.options.fixedParameters = fixedParams; 
        }, 
        fetch: function (options) {
            var ttimestamp = this.options.transaction_timestamp = new Date().getTime(); 
            this.options.isFetching = true;

            options = options ? _.clone(options) : {};
            if (options.parse === void 0) options.parse = true;
            var success = options.success;
            var collection = this;

            if (options.resetPagination) this.resetPagination(true);
            //options["showOnlyExportingTags"] = (_.isBoolean(options["showOnlyExportingTags"])) ? options["showOnlyExportingTags"] : false; 

            var that = this;
            var QP = new Core.Database.QueryParameters();

            if (_.has(options, "agentId")) QP.Add('@AgentID', 'INT', options.agentId);
            if (_.has(options, "adquiringId")) QP.Add('@AdquiringID', 'INT', options.adquiringId);
            if (_.has(options, "showOnlyExportingTags")) QP.Add('@OnlyExportingTags', 'BIT', options.showOnlyExportingTags);

            if (!options.refresh) {
                QP.Add('@FromRow', 'INT', (this.options.currentPage - 1) * this.options.pageSize);
                QP.Add('@RowsToFetch', 'INT', this.options.pageSize);
            } else {
                QP.Add('@FromRow', 'INT', 0);
                QP.Add('@ToRow', 'INT', this.options.currentPage * this.options.pageSize);
            }

            if (_.isArray(options.qps) || this.options.fixedParameters.length > 0) {
                var params = (_.isArray(options.qps)) ? options.qps : [];
                params = params.concat(this.options.fixedParameters); 

                _.each(params, function (qp) {
                    if (_.has(qp, 'Name') && _.has(qp, 'Type') && _.has(qp, 'Value'))
                        QP.Add(qp.Name, qp.Type, qp.Value); 
                }); 
            }

            Core.Json.CallProcedure(app.DatabaseNames.IH + ".WEB.GetTagsExportConfig", QP, {
                onSuccess: function (data) {
                    //checking transaction timestamp
                    if (ttimestamp != that.options.transaction_timestamp)
                        return;

                    if (data && data.Table) {
                        data = data.Table;

                        var resp = []; 
                        for (var i = 0, len = data.length; i < len; i++) {
                            var d = data[i];
                            var obj = _.clone(TagsExportConfiguration.Models.Tag.prototype.defaults);

                            _.extend(obj, {
                                id: d.TagID,
                                rownum: d.RowNum, 
                                agentId: d.AgentId, 
                                agentType: d.AgentType,
                                internal: d.Internal,
                                agentName: d.AgentName,
                                name: d.Name,
                                alias: (d.Alias == null) ? "" : d.Alias,
                                lineColor: (d.LineColor == null) ? "" : d.LineColor,
                                scanRate: (d.ScanRate == null) ? null : d.ScanRate,
                                dataType: (d.DataType == null) ? "" : d.DataType,
                                stringLength: (d.StringLength == null) ? "" : d.StringLength,
                                unit: (d.Unit == null) ? "" : d.Unit,
                                minUnit: (d.MinUnit == null) ? null : d.MinUnit,
                                maxUnit: (d.MaxUnit == null) ? null : d.MaxUnit,
                                enabled: (that.options.forceEnabled != null) ? that.options.forceEnabled : d.Enabled,
                                _enabled: d.Enabled,
                                lastValue: d.LastValue,
                            });

                            resp.push(obj);
                        }

                        delete options.agentId;
                        delete options.adquiringId;

                        //default is add, then if reset or set is found then setting to the correct method.
                        var method = 'add';
                        method = (options.reset) ? 'reset' : method;
                        method = (options.set) ? 'set' : method;

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

                        if (!options.beforeAlteringCollection || options.beforeAlteringCollection() == true) {
                            resp = (options.preprocessResponse) ? options.preprocessResponse(resp) : resp;

                            collection[method](resp, _.extend(options, { silent: false, source: TagsExportConfiguration.enums.sources.FETCH }));

                            //decreasing page since we couldn't get any data on this page.
                            if (resp.length == 0 && method == "add")
                                that.options.currentPage--;
                        }
                        
                        that.options.isFetching = false;

                        if (success) success(collection, resp, options); 
                    }
                }
            }, app.ConnectionStrings.app);

        }
    }); 

    TagsExportConfiguration.Collections.SearchedTags = TagsExportConfiguration.Collections.Tags.extend({
        search: function (searchQuery, options) {
            options = options ? _.clone(options) : {};
            this.resetPagination();
            
            this.options.fixedParameters = _.without(this.options.fixedParameters, _.findWhere(this.options.fixedParameters, { Name: "@SearchQuery" })); 

            var searchQueryQP = { Name: "@SearchQuery", Type: "VARCHAR", Value: searchQuery };
            this.options.fixedParameters.push(searchQueryQP);

            this.fetch(_.extend(options, {
                reset: true, 
            }));
        }, 
    }); 

    TagsExportConfiguration.Views.Main = Backbone.Epoxy.View.extend({
        template: "tags-export-configuration"
        , id: "tags-export-configuration"
        , title: "Configuración de Exportación de Tags"
        //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
        , askBeforeCloseOpt: {
            title: null,
            message: null,
        }
        , bindings: 'data-bind'
        , beforeClose: function () {
            if (!this.askBeforeCloseOpt.title || !this.askBeforeCloseOpt.message) {
                this.askBeforeCloseOpt.title = this.options.i18n[this.template].translate("unsaved_changes_modal_title").fetch();
                this.askBeforeCloseOpt.message = this.options.i18n[this.template].translate("unsaved_changes_modal_message").fetch();
            }

            var changedTags = this.model.get("changedTags");
            if (changedTags.length > 0) return false;
            else return true; 
        }
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            _.bindAll(this);

            if (this.options.viewParams) {
            }

            var model = new TagsExportConfiguration.Models.Main({
                procedure: "dbo.procedureName",
                tags: new TagsExportConfiguration.Collections.Tags({ preprocessResponseGetNextPage: this.preprocessResponse_keepChanges }),
                searchedTags: new TagsExportConfiguration.Collections.SearchedTags(),
                changedTags: new TagsExportConfiguration.Collections.ChangedTags(),
                exportConfig: new TagsExportConfiguration.Models.ExportConfig(),
            });

            this.model = model;

            this.options.MYREFERENCES = {
                autoRefresh: {
                    enabled: false
                    , toid: null
                }
                , subviews: {

                }
                , grid_instance: null
                , grids: {
                    "TAGS": { instance: null, el: null },
                    "SEARCHEDTAGS": { instance: null, el: null }, 
                }
                , isSearching: false
                , searchMode: false
                , isRefreshing: false
                , searchTerm: null

                //, requireLockColumns: ["enabled", "scanRate"]
            };
        }

        , render: function (container) {
            var that = this;
            var thatContainer = (container != null && container != undefined) ? container : this.options.container;

            //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/IHConfiguration/tags-export-configuration/";

            T.render.call(this, this.template, function (tmp) {

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

                    that.model.get('exportConfig').i18n.global = i18nJED;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)                   


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

                    //if (ctx.editable == false) app.views.topMessages.showMessage("Solo lectura.", { stay: 5000 }); 

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

                    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.options.MYREFERENCES.subviews.subnavbarControlsLeft = new TagsExportConfiguration.Views.SubnavBarControlsLeft({
                        parent: that
                        , container: that.$el.find('#subnavbarLeft')
                    });
                    that.options.MYREFERENCES.subviews.subnavbarControlsLeft.render();

                    that.options.MYREFERENCES.subviews.subnavbarControlsRight = new TagsExportConfiguration.Views.SubnavBarButtons({
                        parent: that
                        , container: that.$el.find('#subnavbarRight')
                    });


                    that.bindEvents();


                    var columns = [
                    {
                        name: "agentName",
                        label: app.translate(that, 'agent_name_col'),
                        editable: false,
                        sortable: false, 
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: "string-cell align-center-cell agentName",
                        })
                    },
                    {
                        name: "name",
                        label: app.translate(that, 'tag_name_col'),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            className: "string-cell align-center-cell name"
                        })
                    }
                    //, {
                    //    name: "rownum",
                    //    label: "rowNum",
                    //    editable: false,
                    //    cell: Backgrid.StringCell.extend({
                    //        className: "string-cell align-center-cell"
                    //    })
                    //}
                    //, {
                    //    name: "alias",
                    //    editable: false,
                    //    can_be_editable: false,
                    //    sortable: false,
                    //    label: app.translate(that, 'alias_col'),
                    //    cell: Backgrid.StringCell,
                    //}
                    , {
                        name: "scanRate",
                        editable: false,
                        can_be_editable: false,
                        sortable: false,
                        label: app.translate(that, 'scan_rate_col'),
                        cell: Backgrid.IntegerCell,
                    }
                    , {
                        name: "dataType",
                        editable: false,
                        sortable: false,
                        label: app.translate(that, 'type_col'),
                        cell: Backgrid.StringCell.extend({
                            className: "string-cell align-center-cell dataType"
                        })
                    }
                    //, {
                    //    name: "stringLength",
                    //    label: "String Length",
                    //    editable: false,
                    //    sortable: false,
                    //    cell: Backgrid.StringCell.extend({
                    //        orderSeparator: '',
                    //        className: "string-cell align-center-cell",
                    //    })
                    //}
                    , {
                        name: "unit",
                        label: app.translate(that, 'unit_col'),
                        editable: false, 
                        can_be_editable: false, 
                        sortable: false,
                        cell: Backgrid.StringCell,
                    }
                    , {
                        name: "minUnit",
                        label: app.translate(that, 'min_unit_col'),
                        editable: false,
                        can_be_editable: false,
                        sortable: false,
                        cell: Backgrid.NumberCell,
                    }
                    , {
                        name: "maxUnit",
                        label: app.translate(that, 'max_unit_col'),
                        editable: false,
                        can_be_editable: false,
                        sortable: false,
                        cell: Backgrid.NumberCell,
                    }
                    , {
                        name: "enabled",
                        label: app.translate(that, 'enabled_col'),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.Cell.extend({
                            template: _.template("<input class='enable-tag-checkbox' tabindex='-1' type='checkbox' />"),
                            initialize: function () {
                                Backgrid.Cell.prototype.initialize.apply(this, arguments);
                            },
                            events: {
                                "change .enable-tag-checkbox": "chkboxChanged",
                            },
                            chkboxChanged: function (e) {
                                if (ctx.editable && this.model.get("grid_can_commit"))
                                    this.model.set("enabled", $(e.target).is(":checked"));
                            },
                            render: function () {
                                this.$el.html(this.template());
                                if (!ctx.editable || !this.model.get("grid_can_commit")) this.$el.find(".enable-tag-checkbox").prop("disabled", true);

                                if (this.model.get("enabled")) this.$el.find(".enable-tag-checkbox").attr("checked", "checked");
                                this.highlightIfChanged();
                                this.delegateEvents();
                                return this;
                            },
                            className: "align-center-cell enabled",
                            highlightIfChanged: function () {
                                if ((_.indexOf(this.model.get("changedAttrs"), this.column.get("name")) != -1)
                                    || (that.model.get('allTagsEnabled') != null)) {
                                    this.$el.css("background-color", "#fefed0");
                                }
                                else {
                                    this.$el.css("background-color", "");
                                }
                            },
                        }),
                        headerCell: Backgrid.HeaderCell.extend({
                            render: function () {
                                this.$el.empty();
                                var column = this.column;
                                var allCbx = $('<input type="checkbox">')
                                                .prop('checked', that.model.get('allTagsEnabled'))
                                                .on('click', _.bind(that.addAllTagsToExportCheckbox_click, that));
                                this.$el.append(allCbx);

                                this.listenTo(that.model, 'change:allTagsEnabled', this.screenViewModel_change_allTagsEnabled);

                                this.$el.addClass(column.get("name"));
                                this.$el.addClass("select-all");
                                this.delegateEvents();
                                return this;
                            },

                            screenViewModel_change_allTagsEnabled: function (model, value, opt) {
                                try {
                                    this.$el.find('input').prop('checked', value);
                                }
                                catch (Error) { console.error(Error); }
                            }
                        }),
                    }
                    ];

                    // Initialize a new Grid instance
                    var grid;
                    that.options.MYREFERENCES.grids["TAGS"].instance = grid = new Backgrid.Grid({
                        header: Backgrid.Header.extend({
                            render: function () {
                                Backgrid.Header.prototype.render.apply(this, arguments);
                                //this.$el.affix({ offset: 10 });
                                return this; 
                            },
                            //className: "affix-theader", 
                        }),
                        className: "backgrid table table-hover tags-export-configuration-backgrid-table",
                        columns: columns,
                        collection: that.model.get("tags"),
                        footer: Backgrid.Extension.Infinator.extend({
                            scrollToTop: false
                        }), 
                    });

                    that.options.MYREFERENCES.grids["SEARCHEDTAGS"].instance = new Backgrid.Grid({
                        className: "backgrid table table-hover tags-export-configuration-backgrid-table",
                        columns: columns,
                        collection: that.model.get("searchedTags"),
                        footer: Backgrid.Extension.Infinator.extend({
                            scrollToTop: false,
                            enabled: false, 
                        }),
                    }); 

                    // Render the grid and attach the root to your HTML document
                    //that.$el.find(".tags-grid-container").append(grid.render().el);
                    //that.show_backgrid("TAGS"); 


                    var exportCfgView = new TagsExportConfiguration.Views.GeneralExportConfig({
                        model: that.model.get('exportConfig'),
                        el: that.$el.find('#generalExportCfgContainer'),
                        parent: that,
                    });
                    exportCfgView.render();

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

                    that.options.MYREFERENCES.subviews.subnavbarControlsRight.render(null, function () {
                        that._startAutoRefresh({ forceRedraw: true });
                        //that._autoRefresh({ forceRedraw: true }); 
                    });

                    //end
                }, true, customPath); 

            }, customPath);
        }

        , show_backgrid: function (opt) {
            var options = {
                name: "TAGS", 
            };

            options = _.extend(options, opt);

            var container = this.$el.find(".tags-grid-container");
            container.find(".tags-export-configuration-backgrid-table").floatThead('destroy');

            container.empty();

            var loading_poster = this.$el.find(".loading-poster");
            if (options.loading) {
                var loading_text = loading_poster.find(".loading-text").css("display", "none");
                var searching_text = loading_poster.find(".searching-text").css("display", "none");

                if (options.searching) searching_text.css("display", "block");
                else loading_text.css("display", "block"); 

                loading_poster.css("display", "block");
                return;
            } else {
                loading_poster.css("display", "none");
            }

            for (var g in this.options.MYREFERENCES.grids) this.options.MYREFERENCES.grids[g].instance.footer.setEnabled((g == options.name));

            //if (!this.options.MYREFERENCES.grids[options.name].el) {
            //    this.options.MYREFERENCES.grids[options.name].el = $("<div></div>");
            //    this.options.MYREFERENCES.grids[options.name].el.append(this.options.MYREFERENCES.grids[options.name].instance.render().el); 
            //}

            //container.append(this.options.MYREFERENCES.grids[options.name].el);
            container.append(this.options.MYREFERENCES.grids[options.name].instance.render().el);

            container.find(".tags-export-configuration-backgrid-table").floatThead({
                scrollingTop: function () {
                    try{
                        return $(".subnavbar.fixed-subnavbar").height() + $("header").height();
                    } catch (error) { return 111; }
                },
                zIndex:500, 
                useAbsolutePositioning: false,  
            });
        }

        , isScreenFilled: function () {
            var getWindowSize = (function () {
                var docEl = document.documentElement,
                    IS_BODY_ACTING_ROOT = docEl && docEl.clientHeight === 0,
                    b = document.body;

                // Used to feature test Opera returning wrong values
                // for documentElement.clientHeight.

                function isDocumentElementHeightOff() {
                    var d = document,
                        div = d.createElement('div'),
                        r;
                    div.style.height = "50000px";
                    d.body.insertBefore(div, d.body.firstChild);
                    r = d.documentElement.clientHeight > 49000;
                    d.body.removeChild(div);
                    return r;
                }

                if (typeof document.clientWidth === "number") {
                    return function () {
                        return {
                            width: document.clientWidth,
                            height: document.clientHeight
                        };
                    };
                } else if (IS_BODY_ACTING_ROOT || isDocumentElementHeightOff()) {
                    return function () {
                        return {
                            width: b.clientWidth,
                            height: b.clientHeight
                        };
                    };
                } else {
                    return function () {
                        return {
                            width: docEl.clientWidth,
                            height: docEl.clientHeight
                        };
                    };
                }
            })();

            var body = document.body, html = document.documentElement;

            var documentHeight = Math.max(body.scrollHeight, body.offsetHeight,
                                   html.clientHeight, html.scrollHeight, html.offsetHeight);

            return (!(getWindowSize().height >= documentHeight)); 
        }

        , 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 (options) {
            try {
                var that = this; 
                if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                    clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                    this.options.MYREFERENCES.autoRefresh.toid = null; 
                }
                this.options.MYREFERENCES.autoRefresh.enabled = true; 
                this.options.MYREFERENCES.autoRefresh.toid = setTimeout(function () { that._autoRefresh(options); }, 1);
            } catch (Error) { }
        }

        , _autoRefresh: function (options) {
            var that = this;
            options = options || {};

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

            //do not autorefresh if refreshing already
            if (!this.options.MYREFERENCES.isRefreshing && !this.options.MYREFERENCES.isSearching) {

                var fredraw = options.forceRedraw || false;
                delete options.forceRedraw;

                if (options.auto) {
                    options.collection = (this.options.MYREFERENCES.searchMode) ? "searchedTags" : "tags";
                }
                delete options.auto;

                this.refresh(fredraw, options);
            }

            if (this.options.MYREFERENCES.autoRefresh.enabled == true) {
                //refresh every one minute to avoid annoying freeze
                var autorefresh = function () { that._autoRefresh({ auto: true }); };
                //this.options.MYREFERENCES.autoRefresh.toid = setTimeout(autorefresh, (1000 * 60));
                this.options.MYREFERENCES.autoRefresh.toid = setTimeout(autorefresh, 5000);
            }
        }

        , _stopAutoRefresh: function () {
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }
            this.options.MYREFERENCES.autoRefresh.enabled = false;
        }

        , _agentAdquiringModelChanged: function (mm) {
            var that = this; 
            var prevAgentID = mm.previous("agentID");
            var prevAdquiringID = mm.previous("adquiringID"); 

            this.model.get("searchedTags").setFixedParameters([
                { Name: "" }
            ]);

            this.refresh(true);
            this.options.MYREFERENCES.subviews.subnavbarControlsRight.model.saveToLocalstorage();
            this.options.MYREFERENCES.subviews.subnavbarControlsLeft.clearSearchInput();

        }
        , preprocessResponse_keepChanges: function (resp) {
            var changed = this.model.get("changedTags").toJSON();
            var tags = this.model.get("tags"); 
            var respModels = [];
            var changedModels = [];

            //_.each(changed, function (i) {
            //    var m = _.findWhere(resp, { id: i.id });
            //    if (m) { respModels.push(m); changedModels.push(i); }
            //});

            //resp = _.difference(resp, respModels);

            //this.tagsConfigLockCheck(resp); 

            if (tags.length > 0) {
                _.each(resp, function (m, i) {
                    var t = tags.findWhere({ id: m.id });
                    if (t != null) {
                        m.grid_status = t.get("grid_status");
                        m.grid_message = t.get("grid_message");
                    }
                });
            }

            var newresp = [];
            if (changed.length > 0) {
                _.each(resp, function (m, i) {
                    var mo = null;
                    if (mo = _.findWhere(changed, { id: m.id })) {
                        newresp.push(mo);
                    } else newresp.push(m);
                });
            }

            //resp = resp.concat(changedModels);
            resp = (changed.length > 0) ? newresp : resp; 
            return resp;
        }
        , refresh: function (forceRedraw, opt) {
            this.options.MYREFERENCES.isRefreshing = true; 
            var options = {
                collection: "tags", 
            };
            opt = opt || {}; 
            options = _.extend(options, opt);

            var that = this;

            //Fetch general exporation config
            this.model.get('exportConfig').fetch();

            //Fetch tags export config
            forceRedraw = (forceRedraw == true) ? true : false; 

            var id = parseInt(this.options.MYREFERENCES.subviews.subnavbarControlsRight.model.get("agentID"), 10); 
            var subID = parseInt(this.options.MYREFERENCES.subviews.subnavbarControlsRight.model.get("adquiringID"), 10);
            var showOnlyExportingTags = this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("showOnlyExportingTags"); 

            var agentId = (id != -1) ? id : null; 
            var adquiringId = (subID != -1) ? subID : null;

            this.model.get(options.collection).setFixedParameters([
                { Name: "AgentID", Type: "INT", Value: agentId },
                { Name: "AdquiringID", Type: "INT", Value: adquiringId },
                { Name: "OnlyExportingTags", Type: "BIT", Value: showOnlyExportingTags },
            ]);

            if (forceRedraw) {
                this.show_backgrid({ loading: true });
                this.model.get(options.collection).fetch(_.extend(options, {
                    //agentId: agentId,
                    //adquiringId: adquiringId,
                    //showOnlyExportingTags: this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("showOnlyExportingTags"), 
                    reset: true,
                    resetPagination: true, 
                    success: function (c, r, o) {
                        that.options.MYREFERENCES.isRefreshing = false;
                        that.show_backgrid({ name: "TAGS" });
                        that.keepRefreshingTillScreenFilled(r, options.collection);
                    },
                    preprocessResponse: this.preprocessResponse_keepChanges,
                }));
            } else {
                this.model.get(options.collection).fetch(_.extend(options, {
                    //agentId: agentId,
                    //adquiringId: adquiringId,
                    //showOnlyExportingTags: this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("showOnlyExportingTags"),
                    set: true,
                    refresh: true,
                    success: function () {
                        that.options.MYREFERENCES.isRefreshing = false;
                    },
                    preprocessResponse: this.preprocessResponse_keepChanges,
                }));
            }
        }

        , keepRefreshingTillScreenFilled: function (resp, collectionName) {
            var that = this; 
            if (!this.isScreenFilled() && resp.length > 0) {
                this.model.get(collectionName).getNextPage({
                    success: function (col, resp, opt) {
                        that.keepRefreshingTillScreenFilled(resp, collectionName); 
                    }
                });
            }
        }

        , _getXML: function (data, cols) {

            function _toString(val) {
                return (val == null) ? "" : val.toString(); 
            }

            cols = (_.isArray(cols)) ? cols : [];
            cols = _.invoke(cols, "toUpperCase");

            var xml = null;
            if (!data.length) data = [data];
            try {
                xml = '<XMLRoot>';
                for (var r = 0; r < data.length; r++) {
                    rowObj = data[r];
                    var row = '<Row ';
                    for (var c in rowObj) {
                        if ((cols.length == 0) || (cols.length > 0 && _.indexOf(cols, c.toString().toUpperCase()) != -1)) {
                            row += ((Trim(c).replace(' ', '')).replace('[', '')).replace(']', '') + '="' + _toString(rowObj[c]) + '" ';
                        }
                    }
                    row += '/>';
                    row = row.replace(/#/g, '');
                    xml += row;
                }
                xml += '</XMLRoot>';
            } catch (Error) {
            }
            return xml;
        }

        , _gridRefreshComplete: function () {
        }

        , _searchTerm_change_immediate: function () {
            var searchTerm = this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("searchTerm");
            this.options.MYREFERENCES.searchTerm = searchTerm;
        }
        , _searchTerm_change: _.debounce(function () {
            this.doSearch.call(this); 
        }, 400)
        , doSearch: function () {
            var that = this;
            var searchTerm = this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("searchTerm");
            var isEmpty = !searchTerm.trim().length > 0;
            if (!isEmpty) {
                if (!this.options.MYREFERENCES.isSearching) this.show_backgrid({ loading: true, searching: true });

                this.options.MYREFERENCES.isSearching = true;
                this.options.MYREFERENCES.searchMode = true;
                var collection = this.model.get("searchedTags");

                var id = parseInt(this.options.MYREFERENCES.subviews.subnavbarControlsRight.model.get("agentID"), 10);
                var subID = parseInt(this.options.MYREFERENCES.subviews.subnavbarControlsRight.model.get("adquiringID"), 10);
                var showOnlyExportingTags = this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("showOnlyExportingTags");

                var agentId = (id != -1) ? id : null;
                var adquiringId = (subID != -1) ? subID : null;

                this.model.get("searchedTags").setFixedParameters([
                    { Name: "AgentID", Type: "INT", Value: agentId },
                    { Name: "AdquiringID", Type: "INT", Value: adquiringId },
                    { Name: "OnlyExportingTags", Type: "BIT", Value: showOnlyExportingTags },
                ]);

                collection.search(searchTerm, {
                    //agentId: agentId,
                    //adquiringId: adquiringId,
                    //showOnlyExportingTags: this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.get("showOnlyExportingTags"),
                    success: function (collection, resp) {
                        if (that.options.MYREFERENCES.searchTerm == searchTerm) {
                            //collection.set(that.model.get("changedTags").models, { add: false, remove: false, silent: true });
                            that.show_backgrid({ name: "SEARCHEDTAGS" });
                            that.options.MYREFERENCES.isSearching = false;

                            that.keepRefreshingTillScreenFilled(resp, "searchedTags");
                        }
                    },
                    beforeAlteringCollection: function () {
                        if (that.options.MYREFERENCES.searchTerm != searchTerm) {
                            return false;
                        }
                        return true;
                    },
                    preprocessResponse: this.preprocessResponse_keepChanges
                });
            } else {
                this.options.MYREFERENCES.isSearching = false;
                this.options.MYREFERENCES.searchMode = false;
                this.show_backgrid({ loading: true });
                setTimeout(function () { that.show_backgrid({ name: "TAGS" }); }, 1);
            }
        }
        , _showOnlyExportingTags_change: function () {
            if (this.options.MYREFERENCES.searchMode) {
                this.doSearch.call(this);
                this.refresh(false, { collection: "tags" }); 
            } else {
                this.refresh(true);
                //this.refresh(false, { collection: (this.options.MYREFERENCES.searchMode) ? "searchedTags" : "tags" });
            }
            this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model.saveToLocalstorage();
        }

        , bindEvents: function () {
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model, "change:searchTerm", this._searchTerm_change);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model, "change:searchTerm", this._searchTerm_change_immediate);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControlsLeft.model, "change:showOnlyExportingTags", this._showOnlyExportingTags_change); 

            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControlsRight.model, "change:agentID change:adquiringID", this._agentAdquiringModelChanged);

            this.listenTo(this.model.get("tags"), "change", this.tagsChanged);
            this.listenTo(this.model.get("searchedTags"), "change", this.searchedTagsChanged);
            this.listenTo(this.model, "change:allTagsEnabled", this.model_change_allTagsEnabled);

            //app.models.locksManager.listenToCategory(
            //    this,
            //    ["add", "remove"],
            //    ["AGENTDISCONNECTED", "TAGSCONFIGCHANGE", "SETPLCADDRESS", "DBSTARTMON", "DBSTOPMON", "DBFIXCONFLICTS", "ENABLE", "DISABLE", "UNREGISTER"],
            //    this.tagsConfigLockCheck
            //);
        }
        //, tagsConfigLockCheck: function (tags) {
        //    var locks = app.models.locksManager.getCategoryLocks(
        //        ["AGENTDISCONNECTED", "TAGSCONFIGCHANGE", "SETPLCADDRESS", "DBSTARTMON", "DBSTOPMON", "DBFIXCONFLICTS", "ENABLE", "DISABLE", "UNREGISTER"],
        //        null, true
        //    );

        //    if (_.isArray(tags)) {
        //        var agentIdsLocked = locks.pluck("agentId");
        //        _.each(_.filter(tags, function (m) { return _.indexOf(agentIdsLocked, m.agentId) != -1; }), function (m) {
        //            var lockName = locks.findWhere({ agentId: m.agentId }).get("name"); 
        //            m.grid_can_commit = false;
        //            m.lock_set = lockName; 
        //        }); 
        //    } else {
        //        var tags = this.model.get("tags");
        //        var search = this.model.get("searchedTags"); 

        //        var lockedModels = [];
        //        lockedModels = lockedModels.concat(tags.where({ grid_can_commit: false }), search.where({ grid_can_commit: false }));

        //        var modelsToLock = [];
        //        locks.forEach(function(model){
        //            var agentId = model.get("agentId");
        //            var models = []; 
        //            models = models.concat(tags.where({ agentId: agentId }), search.where({ agentId: agentId }));
        //            _.each(models, function (m) {
        //                var lockName = locks.findWhere({ agentId: m.get("agentId") }).get("name");
        //                m.set({ "grid_can_commit": false, "lock_set": lockName }, { source: TagsExportConfiguration.enums.sources.INTERNAL });
        //            });
        //            modelsToLock = modelsToLock.concat(models);
        //        });

        //        var modelsToUnlock = _.difference(lockedModels, modelsToLock);
        //        _.each(modelsToUnlock, function (m) {
        //            m.set({ "grid_can_commit": true, "lock_set": null }, { source: TagsExportConfiguration.enums.sources.INTERNAL });
        //        });

        //        //if (this.options.MYREFERENCES.searchMode) this.options.MYREFERENCES.grids["SEARCHEDTAGS"].instance.render();
        //        //else this.options.MYREFERENCES.grids["TAGS"].instance.render();
        //    }
        //}
        , searchedTagsChanged: function (model) {
            this.model.get("changedTags").set(model, { remove: false });
            this.model.get("tags").set(this.model.get("changedTags").models, { add: false, remove:false, silent: true }); 
        }

        , tagsChanged: function (model, opt) {
            var source = TagsExportConfiguration.enums.sources.UNKNOWN;
            source = (opt != null && opt != undefined && opt.source) ? opt.source : source; 

            if (source == TagsExportConfiguration.enums.sources.UI || source == TagsExportConfiguration.enums.sources.UNKNOWN)
                this.model.get("changedTags").set(model, { remove: false });
        }

        , model_change_allTagsEnabled: function (model, value, opt) {
            try {
                var enabled = value,
                    tagsColl = this.model.get('tags'),
                    searchTagsColl = this.model.get('searchedTags'),
                    changedTagsColl = this.model.get('changedTags');

                tagsColl.options.forceEnabled = 
                searchTagsColl.options.forceEnabled = enabled;

                if (enabled != null) {
                    tagsColl.each(function (model) {
                        model.set('enabled', enabled);
                    });
                    searchTagsColl.each(function (model) {
                        model.set('enabled', enabled);
                    });
                    changedTagsColl.each(function (model) {
                        model.set('enabled', enabled);
                    });
                }
            }
            catch (Error) { console.error(Error); }
        }

        , bindViewScopedEvents: function () {

        }

        , unbindViewScopedEvents: function () {
            for (var g in this.options.MYREFERENCES.grids) {
                this.options.MYREFERENCES.grids[g].instance.footer.setEnabled(false);
            }
            this._stopAutoRefresh(); 
        }

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

            this._stopAutoRefresh();

            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        }

        , closeSubviews: function () {
            _.each(this.options.MYREFERENCES.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.options.MYREFERENCES.subviews, function (sview) {
                sview.show();
            });
        }

        , hide: function () {
            this.options.state = app.view_states.hidden;

            this.hideSubviews(); 
            this.$el.hide();
            this.unbind();
            this.stopListening();
        }

        , hideSubviews: function () {
            _.each(this.options.MYREFERENCES.subviews, function (sview) {
                sview.hide(); 
            }); 
        }

        , preRender: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("notificationBar", false);
            app.models.subnavbar.set("dateTimeScopeControl", false); 
            app.models.subnavbar.set("subnavbar", false);
            //app.models.subnavbar.set("sections", "6-6"); 
        }

        , remove: function () {
            this.removeBindings();
            this.$el.remove();
            this.stopListening();
            return this;
        }

        , reRender: function () {
        }

        , saveConfiguration: function () {
            var that = this;
            var collection = this.model.get("changedTags");
            var json = collection.toJSON();

            //_.forEach(json, function (m) { m["requiresLock"] = false; });
            //_.forEach(_.filter(json, function (m) {
            //    return _.intersection(m.changedAttrs, that.options.MYREFERENCES.requireLockColumns).length > 0;
            //}), function (m) {
            //    m["requiresLock"] = true; 
            //});

            var xml = this._getXML(
                //json, ["id", "name", "alias", "lineColor", "scanRate", "dataType", "stringLength", "unit", "minUnit", "maxUnit", "enabled", "requiresLock"]);
                json, ["id", "enabled"]);

            var QP = new Core.Database.QueryParameters();
            QP.Add("XML", "XML", xml);
            QP.Add("AllTagsEnabled", "BIT", this.model.get('allTagsEnabled'));

            app.views.topMessages.showMessage(this.options.i18n[this.template].translate("top_message_saving_text").fetch(), { stay: 10000 });

            app.log.debug(this, ("Saving new tags configuration using XML [{{xml}}].").replace("{{xml}}", xml));
            Core.Json.CallProcedure(app.DatabaseNames.IH + ".WEB.[SaveTagsExportConfig]", QP, {
                onSuccess: this._handleSaveCatalog
            }, app.ConnectionStrings.app);
        }
        , _handleSaveCatalog: function (data) {

            var rowsState = data.Table;
            var rowsErrors = data.Table1;
            var rowsNotSaved = data.Table2; 
            //var rowsLocked = data.Table3; 
            //var transactionStatus = (data && data.Table4 && data.Table4[0]["Status"] == 1) ? true : false; 
            var transactionStatus = (data && data.Table3 && data.Table3[0]["Status"] == 1) ? true : false;

            var collection = this.model.get("changedTags");
            collection.forEach(function (model) {
                model.set({ grid_status: null, grid_message: null }); 
            }); 

            var error_models = []; 
            if (_.isArray(rowsErrors) && rowsErrors.length > 0) {
                _.each(rowsErrors, function (i) {
                    var m = collection.findWhere({ id: i.TagID });
                    m.set({ grid_status: "error", grid_message: i.Error });
                    error_models.push(m); 
                });
            }

            var not_saved_models = [];
            if (_.isArray(rowsNotSaved) && rowsNotSaved.length > 0) {
                _.each(rowsNotSaved, function (i) {
                    var m = collection.findWhere({ id: i.TagID });
                    not_saved_models.push(m);
                });
            }

            //var locked_models = [];
            //if (_.isArray(rowsLocked) && rowsLocked.length > 0) {
            //    _.each(rowsLocked, function (i) {
            //        var m = collection.findWhere({ id: i.TagID });
            //        locked_models.push(m); 
            //    }); 
            //}

            var saved_models = collection.models; //_.difference(collection.models, error_models, /*locked_models, */not_saved_models);
            _.each(saved_models, function (i) {
                i.set({ "changedAttrs": [] }, { silent: true });
            }); 

            this.model.get("tags").set(collection.models, { remove: false, add: false });
            this.model.get("searchedTags").set(collection.models, { remove: false, add: false });

            collection.remove(saved_models); 

            var container = this.$el.find(".tags-grid-container");
            container.find(".tags-export-configuration-backgrid-table").floatThead('destroy');

            if (this.options.MYREFERENCES.searchMode) this.options.MYREFERENCES.grids["SEARCHEDTAGS"].instance.render();
            else this.options.MYREFERENCES.grids["TAGS"].instance.render();

            container.find(".tags-export-configuration-backgrid-table").floatThead({
                scrollingTop: function () {
                    try {
                        return $(".subnavbar.fixed-subnavbar").height() + $("header").height();
                    } catch (error) { return 111; }
                },
                zIndex: 500,
                useAbsolutePositioning: false,
            });

            if (transactionStatus == true) {
                if (rowsErrors.length > 0) {
                    app.views.topMessages.showMessage(this.options.i18n[this.template].translate("top_message_some_changes_not_saved").fetch());
                } else {
                    this.model.set('allTagsEnabled', null);
                    app.views.topMessages.showMessage(this.options.i18n[this.template].translate("top_message_changes_saved").fetch());
                }
            } else {
                app.views.topMessages.showMessage(this.options.i18n[this.template].translate("top_message_error").fetch());
            }

            //if (locked_models.length > 0) {
            //    var agentNames = _.uniq(_.map(locked_models, function (m) { return m.get("agentName"); }));
            //    var modal = new Modal.Views.Main({
            //        id: "locked-agents"
            //        , title: this.options.i18n[this.template].translate("changes_on_locked_agents_not_made_title").fetch()
            //        , message: this.options.i18n[this.template].translate("changes_on_locked_agents_not_made").fetch(agentNames)
            //        , allowCancel: false
            //        , buttons_type: "OK"
            //    });

            //    modal.show(); 
            //}

        }
        , fetchExportVolumeData: function (opt) {
            var that = this;

            if (!opt) opt = {};

            Core.Json.CallProcedure(
                app.DatabaseNames.IH + '.WEB.GetExportVolumeData',
                null,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp) {
                                if (!resp.Message) {
                                    var data = resp.Table[0];

                                    var obj = {
                                        interval: data.Interval,
                                        tagsCount: data.TagsCount,
                                        tagsVolume: data.TagsVolume,
                                        tagsExportCount: data.TagsExportCount,
                                        tagsExportVolume: data.TagsExportVolume,
                                        targetRowSizeBytes: data.TargetRowSizeBytes,
                                    };

                                    if (opt.success) opt.success(obj);
                                }
                                else {
                                    console.error(resp.Message);

                                    if (opt.error) opt.error(resp, resp.Message);
                                }
                            }
                            else {
                                console.error('Invalid server response.');

                                if (opt.error) opt.error(resp, 'Invalid server response.');
                            }
                        }
                        catch (Error) { console.error(Error); }
                    },
                    onError: function (errorMsg) {
                        try {
                            console.error(errorMsg);
                        }
                        catch (Error) { console.error(Error); }
                    },
                    Async: true,
                    //Secured: true,
                },
                app.ConnectionStrings.app
            );
        }
        , addAllTagsToExport: function (opt) {
            var that = this;

            if (!opt) opt = {};

            Core.Json.CallProcedure(
                app.DatabaseNames.IH + '.WEB.AddAllTagsToExport',
                null,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp) {
                                if (!resp.Message) {
                                    if (opt.success) opt.success(that, resp);
                                }
                                else {
                                    console.error(resp.Message);

                                    if (opt.error) opt.error(this, resp, resp.Message);
                                }
                            }
                            else {
                                console.error('Invalid server response.');

                                if (opt.error) opt.error(this, resp, 'Invalid server response.');
                            }
                        }
                        catch (Error) { console.error(Error); }
                    },
                    onError: function (errorMsg) {
                        try {
                            console.error(errorMsg);
                        }
                        catch (Error) { console.error(Error); }
                    },
                    Async: true,
                    //Secured: true,
                },
                app.ConnectionStrings.app
            );
        }
        , removeAllTagsFromExport: function (opt) {
            var that = this;

            if (!opt) opt = {};

            Core.Json.CallProcedure(
                app.DatabaseNames.IH + '.WEB.RemoveAllTagsToExport',
                null,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp) {
                                if (!resp.Message) {
                                    if (opt.success) opt.success(that, resp);
                                }
                                else {
                                    console.error(resp.Message);

                                    if (opt.error) opt.error(this, resp, resp.Message);
                                }
                            }
                            else {
                                console.error('Invalid server response.');

                                if (opt.error) opt.error(this, resp, 'Invalid server response.');
                            }
                        }
                        catch (Error) { console.error(Error); }
                    },
                    onError: function (errorMsg) {
                        try {
                            console.error(errorMsg);
                        }
                        catch (Error) { console.error(Error); }
                    },
                    Async: true,
                    //Secured: true,
                },
                app.ConnectionStrings.app
            );
        }


        , addAllTagsToExportCheckbox_click: function (e) {
            try {
                this.model.set('allTagsEnabled', $(e.target).prop('checked'));
            }
            catch (Error) { console.error(Error); }
        }
        , addAllTagsToExportConfirmModal_continue: function (e) {
            try {
                var that = this;

                this.addAllTagsToExport({
                    success: function () {
                        try {
                            that._autoRefresh();
                        }
                        catch (Error) { console.error(Error); }
                    }
                });
            }
            catch (Error) { console.error(Error); }
        }
        , removeAllTagsFromExportBtn_click: function (e) {
            try {
                var that = this;

                this.fetchExportVolumeData({
                    success: function (data) {
                        try {
                            var modal = new Modal.Views.Main({
                                title: app.translate(that, "remove_all_tags_export_modal_confirm_title"),
                                message: app.translate(that, "remove_all_tags_export_modal_confirm_message", [data.tagsExportCount]),
                                buttons_type: "CONTINUE-CANCEL",
                            });

                            that.listenToOnce(modal, "continue", that.removeAllTagsFromExportConfirmModal_continue);

                            modal.show();
                        }
                        catch (Error) { console.error(Error); }
                    },
                });
            }
            catch (Error) { console.error(Error); }
        }
        , removeAllTagsFromExportConfirmModal_continue: function (e) {
            try {
                var that = this;

                this.removeAllTagsFromExport({
                    success: function () {
                        try {
                            that._autoRefresh();
                        }
                        catch (Error) { console.error(Error); }
                    }
                });
            }
            catch (Error) { console.error(Error); }
        }
    });

    TagsExportConfiguration.Models.SubnavBarButtons = Backbone.Model.extend({
        defaults: {
            agentID: ""
            , adquiringID: ""
        }
        , loadFromLocalstorage: function () {
            var agentID = localStorage.getItem("tags-export-configuration-agentID");
            var adquiringID = localStorage.getItem("tags-export-configuration-adquiringID");

            this.set({ agentID: agentID, adquiringID: adquiringID }, { silent: true }); 
        }
        , saveToLocalstorage: function () {
            var agentID = this.get("agentID");
            var adquiringID = this.get("adquiringID");

            localStorage.setItem("tags-export-configuration-agentID", agentID);
            localStorage.setItem("tags-export-configuration-adquiringID", adquiringID); 
        }
        , initialize: function () {
            //this.loadFromLocalstorage(); 
        }
    });

    //subview
    TagsExportConfiguration.Views.SubnavBarButtons = Backbone.View.extend({
        id: ""
        , title: ""
        , template: "tags-export-configuration"
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            if (this.options.viewParams) {
            }

            this.options.MYREFERENCES = {};

            this.model = new TagsExportConfiguration.Models.SubnavBarButtons({});

            this.bindEvents();
            _.bindAll(this);
        },

        events: function () {
            return {
                "click #saveConfiguration_button": this.saveConfiguration_button_click,
            };
        },

        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/IHConfiguration/tags-export-configuration/";

            T.render.call(this, this.template, function (tmp) {

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

                that.$el.html(tmp(ctx));

                Core.Include({
                    Widgets: []
                    , Events: {
                        onLoad: function () {

                            that.model.loadFromLocalstorage(); 
                            var mm = that.model;
                            var optionID = ""; 
                            if (mm.get("agentID") != null && mm.get("adquiringID") != null) {
                                optionID = mm.get("agentID") + "&" + mm.get("adquiringID");
                            }

                            that.options.MYREFERENCES.agentsSelect = new FormSelectBootstrap(that.$("#agentsSelect").get(0), {
                                value: optionID, 
                                DatabaseInfo: {
                                    optionsData: {
                                        ConnectionStringName: app.ConnectionStrings.app
                                        , DBEngine: ""
                                        , FixedParameters: []
                                        , Procedure:  app.DatabaseNames.IH + ".WEB.GetAgentsDDP"
                                    }
                                }
                                , Events: {
                                    onValueChange: [that.agentsSelectChanged]
                                    , onRefreshOptionsDataComplete: [that.optionsDataComplete]
                                }
                                , Templates: {
                                    "parent": "<option value=\"{{Id}}&{{SubID}}\" data-content='<span>{{Name}}</span><span class=\"label label-info pull-right\">{{Type}}</span>'></option>"
                                    , "child": "<option value=\"{{Id}}&{{SubID}}\" data-content='<div style=\"width: 10px;height: 12px;border: none;border-left: 1px solid #c5c5c5; border-bottom: 1px solid #c5c5c5; float:left; margin-right:6px;\"></div><span>{{Name}}</span><span class=\"label label-info pull-right\">{{Type}}</span>' ></option>"
                                }
                            });

                            that.options.MYREFERENCES.previousValues = {
                                agentsSelect: ""
                            };

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

                            onViewComplete();
                        }
                    }
                    , ExternalWidgets: [
                        { Name: 'FormWidgetBase', URL: '/IndustrialDashboard/Widgets/FormWidgets2/FormWidgetBase/', JS: ['FormWidgetBase.js'] }
                        , { Name: 'FormWidget', URL: '/IndustrialDashboard/Widgets/FormWidgets2/FormWidget/', JS: ['FormWidget.js'], CSS: ['FormWidget.css'] }
                    ]
                });

            }, customPath, "subnav_buttons_right_template");

            //end:
        }

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

        , optionsDataComplete: function () {
        }

        , refreshAgentsSelect: function () {
            try {
                this.options.MYREFERENCES.agentsSelect.RefreshOptionsData();
            } catch (Error) { }
        }

        , agentsSelectChanged: function (e) {
            var internalID = this.options.MYREFERENCES.agentsSelect.GetValue();
            var splitted = internalID.split("&");

            var id = splitted[0];
            var subID = splitted[1];

            this.model.set({
                agentID: id
                , adquiringID: subID
            });
        }

        , saveConfiguration_button_click: function (e) {
            try {
                var that = this;

                this.options.parent.fetchExportVolumeData({
                    success: function (data) {
                        try {
                            var allTagsEnabled = that.options.parent.model.get('allTagsEnabled'),
                                msgParams,
                                curTagsCount = data.tagsExportCount,
                                curVolume = data.tagsExportVolume * data.interval;

                            if (allTagsEnabled == null) {
                                var tagsChanged = that.options.parent.model.get('changedTags'),
                                    tagValuesCountPerSecond = 0,
                                    tagsCount = 0;

                                tagsChanged.each(function (model) {
                                    var attrs = model.toJSON();

                                    //Check if really changed
                                    if (attrs._enabled != attrs.enabled) {
                                        if (attrs.scanRate)
                                            tagValuesCountPerSecond += 1000 / attrs.scanRate * ((attrs.enabled == true) ? 1 : -1);

                                        if (attrs.enabled == true)
                                            tagsCount++;
                                        else
                                            tagsCount--;
                                    }
                                });

                                msgParams = [curTagsCount, curTagsCount + tagsCount, (curVolume / 1000000).toFixed(2), ((curVolume + tagValuesCountPerSecond * data.targetRowSizeBytes * data.interval) / 1000000).toFixed(2),];
                            }
                            else if (allTagsEnabled == true) {
                                var tagsChanged = that.options.parent.model.get('changedTags').where({ enabled: false, }),
                                    tagValuesCountPerSecond = 0;

                                _.each(tagsChanged, function (model) {
                                    var attrs = model.toJSON();

                                    if (attrs.scanRate)
                                        tagValuesCountPerSecond -= 1000 / attrs.scanRate;
                                });

                                msgParams = [curTagsCount, data.tagsCount - tagsChanged.length, (curVolume / 1000000).toFixed(2), ((data.tagsVolume * data.interval - tagValuesCountPerSecond * data.targetRowSizeBytes * data.interval) / 1000000).toFixed(2), ];
                            }
                            else {
                                var tagsChanged = that.options.parent.model.get('changedTags').where({ enabled: true, }),
                                    tagValuesCountPerSecond = 0;

                                _.each(tagsChanged, function (model) {
                                    var attrs = model.toJSON();

                                    if (attrs.scanRate)
                                        tagValuesCountPerSecond += 1000 / attrs.scanRate;
                                });

                                msgParams = [curTagsCount, tagsChanged.length, (curVolume / 1000000).toFixed(2), ((tagValuesCountPerSecond * data.targetRowSizeBytes * data.interval) / 1000000).toFixed(2), ];
                            }

                            var modal = new Modal.Views.Main({
                                title: app.translate(that.options.parent, 'save_tags_cfg_modal_title'),
                                message: app.translate(that.options.parent, 'save_tags_cfg_modal_message', msgParams),
                                buttons_type: 'CONTINUE-CANCEL',
                                focusOk: false,
                                focusSelector: '[data-buttonid="cancel"]',
                            });

                                that.listenTo(modal, "continue", function (e) {
                                    try {
                                        that.options.parent.saveConfiguration();
                                    }
                                    catch (Error) { console.error(Error); }
                                });

                                modal.show();
                            }
                        catch (Error) { console.error(Error); }
                    },
                });                    
            }
            catch (Error) { console.error(Error); }
        }

        , refresh: function (mm, force) {
            try {

                var internalID = this.options.MYREFERENCES.agentsSelect.GetValue();
                var splitted = internalID.split("&");

                var agentID = splitted[0];
                var adquiringID = splitted[1];

                if (mm && ((mm.changed["agentID"] || mm.changed["adquiringID"]) || force)) {
                    if (mm.get("agentID") != agentID || mm.get("adquiringID") != adquiringID){
                        var optionID = mm.get("agentID") + "&" + mm.get("adquiringID"); 
                        this.options.MYREFERENCES.agentsSelect.SetValue(optionID, { silent: true, force: true });
                    }
                }

            } catch (Error) { }
        }

        , checkTagsCount: function(c){
            if (c.length > 0) {
                this.$el.find("#saveConfiguration_button").prop("disabled", false);
            } else {
                this.$el.find("#saveConfiguration_button").prop("disabled", true);
            }
        }

        , bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model, "change", this.refresh);
            //this.listenTo(this.options.parent.model.get("changedTags"), "change", this.checkTagsCount); 
        }

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

        , reRender: function () {
        }
    });

    TagsExportConfiguration.Models.SubnavBarControlsLeft = Backbone.Model.extend({
        defaults: {
            searchTerm: "",
            showOnlyExportingTags: false, 
        }
        , loadFromLocalstorage: function () {
            var showOnlyExportingTags = localStorage.getItem("tags-export-configuration-showOnlyExportingTags");
            if (showOnlyExportingTags != null) {
                showOnlyExportingTags = (showOnlyExportingTags === 'true') ? true : (showOnlyExportingTags === 'false') ? false : null; 
            }

            this.set({ showOnlyExportingTags: ((_.isBoolean(showOnlyExportingTags)) ? showOnlyExportingTags : this.get("showOnlyExportingTags")) }, { silent: true });
        }
        , saveToLocalstorage: function () {
            var showOnlyExportingTags = this.get("showOnlyExportingTags");
            localStorage.setItem("tags-export-configuration-showOnlyExportingTags", showOnlyExportingTags);
        }
    });

    //subview for the subnavbar controls
    TagsExportConfiguration.Views.SubnavBarControlsLeft = Backbone.View.extend({
        id: "tags-export-configuration-subnavbar-controls-left"
        , title: ""
        , template: "tags-export-configuration"
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            if (this.options.viewParams) {
            }

            this.options.MYREFERENCES = {};

            this.model = new TagsExportConfiguration.Models.SubnavBarControlsLeft({});

            this.bindEvents();
            _.bindAll(this);
        },

        events: {
            "keyup #searchTerm_input": "_searchTerm_input_keyup",
            "change #show_only_exporting_tags_checkbox": "_showOnlyExportingTags_checkbox_click", 
        },

        render: function (container, onComplete) {
            var that = this;
            var thatContainer = (container) ? container : (this.options.container) ? this.options.container : null;
            var viewComplete = onComplete;

            //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/IHConfiguration/tags-export-configuration/";

            T.render.call(this, this.template, function (tmp) {

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

                that.append(thatContainer, that.$el); 
                if (viewComplete) viewComplete();

            }, customPath, "subnav_buttons_left_template");

        }

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

        , _searchTerm_input_keyup: function () {
            this.model.set("searchTerm", this.$("#searchTerm_input").val()); 
        }

        , _showOnlyExportingTags_checkbox_click: function (e) {
            var target = $(e.target);
            var checked = target.is(":checked");
            this.model.set("showOnlyExportingTags", checked); 
        }

        , clearSearchInput: function () {
            try {
                this.model.set("searchTerm", ""); 
            } catch (Error) { }
        }

        , refresh: function (mm, force) {
            try {
                if (mm && (mm.changed["searchTerm"] || force)) {
                    if (mm.get("searchTerm") != this.$("#searchTerm_input").val())
                        this.$("#searchTerm_input").val(this.model.get("searchTerm"));
                }
            } catch (Error) { }
        }        

        , bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model, "change", this.refresh);
        }

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

        , reRender: function () {
        }
    });

    TagsExportConfiguration.Views.GeneralExportConfig = Backbone.Epoxy.View.extend({
        id: "tags-export-configuration-general-export-config",
        template: "tags-export-configuration",
        bindings: 'data-bind',

        //exportModal: null,
        parent: null,

        events: function () {
            return {
                'blur #intervalTbx': this.intervalTbx_blur,
                'blur #timeoutTbx': this.timeoutTbx_blur,
                'click #cancelGeneralCfgBtn': this.cancelGeneralCfgBtn_click,
                'click #editGeneralCfgBtn': this.editGeneralCfgBtn_click,
                'click #saveGeneralCfgBtn': this.saveGeneralCfgBtn_click,
                'click #testConnectionBtn': this.testConnectionBtn_click,
                'click .toggleExportCfgBtn': this.toggleExportCfgBtn_click,
            };
        },

        initialize: function () {
            //this.listenTo(this.model, 'change', this.model_change);

            this.parent = this.options.parent;
        },

        confirmGeneralConfigEdition: function (ignoreOldData) {
            var that = this,
                params = {
                    ignoreOldData: (ignoreOldData === true),
                };

            //if (startDate) {
            //    params.start = startDate;
            //    params.timeZoneCode = app.models.user.get("timezoneCode");
            //}

            this.model.confirmEdition({
                params: params,
                success: function (model, resp) {
                    try {
                        that.model.set('editing', false);
                    }
                    catch (Error) { console.error(Error); }
                },
                error: function (model, resp, msg) {
                    try {
                        app.views.topMessages.showMessage(app.translate(that.parent, msg), { stay: 10000, });
                    }
                    catch (Error) { console.error(Error); }
                },
            });
        },
        render: function () {
            var that = this;

            var customPath = "/app/custom-screens/IHConfiguration/tags-export-configuration/";

            T.render.call(this, this.template, function (tmp) {

                that.$el.html(tmp());

                that.applyBindings();

                that.$el.find('#intervalTbx, #timeoutTbx').mask('00:00:00');

            }, customPath, "generalExportConfigTemplate");
        },
        fixTagsGridTableHeadPosition: function () {
            var container = this.parent.$el.find(".tags-grid-container");
            container.find(".tags-export-configuration-backgrid-table").floatThead('destroy');
            container.find(".tags-export-configuration-backgrid-table").floatThead({
                scrollingTop: function () {
                    try {
                        return $(".subnavbar.fixed-subnavbar").height() + $("header").height();
                    } catch (error) { return 111; }
                },
                zIndex: 500,
                useAbsolutePositioning: false,
            });
        },

        cancelGeneralCfgBtn_click: function (e) {
            try {
                this.model.cancelEdition();
            }
            catch (Error) { console.error(Error); }
        },
        editGeneralCfgBtn_click: function (e) {
            try {
                this.parent.$el.find('.exportCfgCollapse').toggle(true);
                this.parent.$el.find('.exportCfgExpand').toggle(false);

                this.fixTagsGridTableHeadPosition();
            }
            catch (Error) { console.error(Error); }
        },
        intervalTbx_blur: function(e) {
            try {
                this.model.set('intervalFormated', $(e.target).val());
            }
            catch (Error) { console.error(Error); }
        },
        saveGeneralCfgBtn_click: function (e) {
            try {
                var exportActive = this.model.get('active');

                if ((exportActive != this.model.lastFetch.active) && (exportActive == true)) {
                    var that = this;
                    
                    this.parent.fetchExportVolumeData({
                        success: function (data) {
                            try {
                                var lastExportTimestamp = new moment(that.model.get('lastExportTimestamp'), 'YYYY-MM-DD HH:mm:ss.SSS');

                                var modal = new Modal.Views.Main({
                                    title: app.translate(that.parent, 'save_cfg_active_modal_title'),
                                    message: app.translate(that.parent, 'save_cfg_active_modal_message', [
                                        lastExportTimestamp.format('YYYY-MM-DD HH:mm'),
                                        (data.tagsExportVolume * moment.duration(new moment(new Date()).diff(lastExportTimestamp)).asSeconds() / 1000000).toFixed(2),
                                    ]),
                                    buttons_type: 'CUSTOM-BUTTONS',
                                    custom_buttons: [
                                        {
                                            id: 'yes',
                                            btn_lbl: 'Sí',
                                            //classNames: 'btn-error',
                                        },
                                        {
                                            id: 'no',
                                            btn_lbl: 'No',
                                            classNames: 'btn-primary',
                                        },
                                        {
                                            id: 'cancel',
                                            btn_lbl: 'Cancelar',
                                            //classNames: 'btn-primary',
                                        },
                                    ],
                                    focusOk: false,
                                    focusSelector: '[data-buttonid="no"]',
                                });

                                that.listenTo(modal, "customButtonClicked", function (e) {
                                    try {
                                        switch (e.buttonid) {
                                            case 'cancel':
                                            default:
                                                modal.hide();
                                                break;
                                            case 'no':
                                                that.confirmGeneralConfigEdition();
                                                modal.hide();
                                                break;
                                            case 'yes':
                                                that.confirmGeneralConfigEdition(true);
                                                modal.hide();
                                                break;
                                        }
                                    }
                                    catch (Error) { console.error(Error); }
                                });

                                modal.show();
                            }
                            catch (Error) { console.error(Error); }
                        },
                    });
                }
                else {
                    this.confirmGeneralConfigEdition();
                }
            }
            catch (Error) { console.error(Error); }
        },
        testConnectionBtn_click: function (e) {
            try {
                var that = this;

                var btn = $(e.target).button('loading');

                var fn_modal_shown = function (e) {
                    try {
                        btn.button('reset');
                    }
                    catch (Error) { console.error(Error); }
                }

                $.ajax({
                    url: '/wcf/tagsExport/' + 'TestConnection',
                    //dataType: 'json',
                    contentType: 'application/json',
                    method: 'POST',
                    data: JSON.stringify({
                        ConnectionString: this.model.get('targetConnectionString'),
                        TargetType: 0, //Oracle 11g
                    }),
                    success: function (resp) {
                        try {
                            var msg;

                            if (resp && resp.Success == true) {
                                var msg = (resp.Data)
                                            ? resp.Data
                                            : 'test_connection_modal_success_message';
                            }
                            else {
                                msg = 'test_connection_modal_error_message';
                            }

                            var modal = new Modal.Views.Main({
                                title: app.translate(that.parent, 'test_connection_modal_title'),
                                message: app.translate(that.parent, msg),
                                buttons_type: 'OK',
                            });

                            that.listenTo(modal, 'shown', fn_modal_shown);

                            modal.show();
                        }
                        catch (Error) { console.error(Error); }
                    },
                    error: function (errorMsg) {
                        try {
                            var modal = new Modal.Views.Main({
                                title: app.translate(that.parent, 'test_connection_modal_title'),
                                message: app.translate(that.parent, 'test_connection_modal_error_message'),
                                buttons_type: 'OK',
                            });

                            that.listenTo(modal, 'shown', fn_modal_shown);

                            modal.show();
                        }
                        catch (Error) { console.error(Error); }
                    },
                    async: true,
                });
            }
            catch (Error) {
                console.error(Error);

                btn.button('reset');
            }
        },
        timeoutTbx_blur: function (e) {
            try {
                this.model.set('timeoutFormated', $(e.target).val());
            }
            catch (Error) { console.error(Error); }
        },
        toggleExportCfgBtn_click: function (e) {
            try {
                this.parent.$el.find('.exportCfgCollapse, .exportCfgExpand').toggle();

                this.fixTagsGridTableHeadPosition();
            }
            catch (Error) { console.error(Error); }
        },
    });

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

});
