//SCREEN-BOILERPLATE

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

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

  //templates-loader: this loads templates async.
  'js/templates-loader',
  'backgrid',
  'modules/modal',
    
  //'backgrid/infinator',
  'js/jquery.clearsearch/jquery.clearsearch',
],

function (app, T, Backgrid, Modal) {

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

    Screen.Models.Item = Backbone.Epoxy.Model.extend({
        defaults: {
            gradeGroupId: null,

            slagHeatsPercentageMin: null,
            slagHeatsPercentageMax: null,
            temperaturesPercentageMin: null,
            temperaturesPercentageMax: null,

            carbonCostPerTonMin: null,
            carbonCostPerTonMax: null,
            energyCostPerTonMin: null,
            energyCostPerTonMax: null,
            limeCostPerTonMin: null,
            limeCostPerTonMax: null,
            naturalGasCostPerTonMin: null,
            naturalGasCostPerTonMax: null,
            oxygenCostPerTonMin: null,
            oxygenCostPerTonMax: null,
            eafTotalCostPerTonMin: null,
            eafTotalCostPerTonMax: null,
        },
        idAttribute: 'gradeGroupId',

        parse: function (objs) {
            var result = {};
            if (objs) {
                var obj = objs[0];

                result = {
                    gradeGroupId: obj.GradeGroupId,
                };

                _.each(objs, function (obj) {
                    switch (obj.Code.toUpperCase()) {
                        case 'CARBON_COST_PER_TON_MAX':
                            result.carbonCostPerTonMax = obj.Value;
                            break;
                        case 'CARBON_COST_PER_TON_MIN':
                            result.carbonCostPerTonMin = obj.Value;
                            break;
                        case 'ENERGY_COST_PER_TON_MAX':
                            result.energyCostPerTonMax = obj.Value;
                            break;
                        case 'ENERGY_COST_PER_TON_MIN':
                            result.energyCostPerTonMin = obj.Value;
                            break;
                        case 'LIME_COST_PER_TON_MAX':
                            result.limeCostPerTonMax = obj.Value;
                            break;
                        case 'LIME_COST_PER_TON_MIN':
                            result.limeCostPerTonMin = obj.Value;
                            break;
                        case 'NATURAL_GAS_COST_PER_TON_MAX':
                            result.naturalGasCostPerTonMax = obj.Value;
                            break;
                        case 'NATURAL_GAS_COST_PER_TON_MIN':
                            result.naturalGasCostPerTonMin = obj.Value;
                            break;
                        case 'OXYGEN_COST_PER_TON_MAX':
                            result.oxygenCostPerTonMax = obj.Value;
                            break;
                        case 'OXYGEN_COST_PER_TON_MIN':
                            result.oxygenCostPerTonMin = obj.Value;
                            break;
                        case 'SLAG_HEATS_PERCENTAGE_MAX':
                            result.slagHeatsPercentageMax = obj.Value;
                            break;
                        case 'SLAG_HEATS_PERCENTAGE_MIN':
                            result.slagHeatsPercentageMin = obj.Value;
                            break;
                        case 'TAP_TEMPERATURES_PERCENTAGE_MAX':
                            result.temperaturesPercentageMax = obj.Value;
                            break;
                        case 'TAP_TEMPERATURES_PERCENTAGE_MIN':
                            result.temperaturesPercentageMin = obj.Value;
                            break;
                        case 'EAF_TOTAL_COST_PER_TON_MAX':
                            result.eafTotalCostPerTonMax = obj.Value;
                            break;
                        case 'EAF_TOTAL_COST_PER_TON_MIN':
                            result.eafTotalCostPerTonMin = obj.Value;
                            break;
                        default:
                            break;
                    }
                });
            }

            return result;
        },
    });

    Screen.Collections.Items = Backbone.Collection.extend({
        model: Screen.Models.Item,

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

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

            qp.Add('@gradeGroupId', 'INT', options.params.gradeGroupId);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.CAT.GetGradeGroupAttributes',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table,
                                    newColl;
                                newColl = that.model.prototype.parse(records);

                                that.set(newColl, { from: 'fetch' })
                                    .trigger('fetch', that, records);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
    });

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            items: null,

            hasData: false,
            isLoading: true,


            gradeGroups: [],
            gradeGroupId: 1,

            gradeGroupAbbrev: null,
        },
        computeds: {
            hasGradeGroups: {
                deps: ['gradeGroups'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            slagData: {
                deps: ['gradeGroupId'],
                get: function (value) {
                    if (value) return true; 
                    else return false;
                }
            },
            smartData: {
                deps: ['gradeGroupId'],
                get: function (value) {
                    if (value) return true;
                    else return false;
                }
            },
        },

        initialize: function () {
            this.fetchPickers();
            this.attributes.items = new Screen.Collections.Items();
            this.attributes.slagLimits = new Screen.Collections.SlagLimits();
            this.attributes.smartArc = new Screen.Collections.SmartArc();
       
        },


        fetchPickers: function (params, options) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                opt = _.extend({ async: true, }, options);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.CAT.GetGradeGroups',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                that.set('gradeGroups', _.map(resp.Table, function (obj) {
                                    return { value: obj.Id, label: obj.Name, abbrev: obj.Abbrev };
                                }));
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(new Error(resp.Message).stack);
                                else
                                    console.error(new Error('SERVER_RESPONSE_NOT_VALID').stack);
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },

    });


    Screen.Models.SlagLimits = Backbone.Epoxy.Model.extend({
        defaults: {
            gradeGroupId: null,

            MgOMin: null,
            MgOMax: null,
            FeOMin: null,
            FeOMax: null,
            B3Min: null,
            B3Max: null,
        },
        idAttribute: 'gradeGroupId',

        parse: function (objs) {
            var result = {};
            if (objs) {
                var obj = objs[0];

                result = {
                    gradeGroupId: obj.GradeGroupId,
                };

                _.each(objs, function (obj) {
                    switch (obj.Code) {
                        case 'SLAG_B3_MAX_LIMIT':
                            result.B3Max = obj.Value;
                            break;
                        case 'SLAG_B3_MIN_LIMIT':
                            result.B3Min = obj.Value;
                            break;
                        case 'SLAG_FeO_MAX_LIMIT':
                            result.FeOMax = obj.Value;
                            break;
                        case 'SLAG_FeO_MIN_LIMIT':
                            result.FeOMin = obj.Value;
                            break;
                        case 'SLAG_MgO_MAX_LIMIT':
                            result.MgOMax = obj.Value;
                            break;
                        case 'SLAG_MgO_MIN_LIMIT':
                            result.MgOMin = obj.Value;
                            break;
                        default:
                            break;
                    }
                });
            }

            return result;
        },
    });


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

        setDataColl: function (records) {
            var newColl,
                that = this;

            newColl = that.model.prototype.parse(records);
            that.set(newColl);
        },
    });


    Screen.Models.SmartArc = Backbone.Epoxy.Model.extend({
        defaults: {
            gradeGroupId: null,

            TemperatureAim: null,
            O2PPMAim: null,
            B3RatioAim: null,
            FeOAim: null,
            MgOAim: null,

        },
        idAttribute: 'gradeGroupId',

        parse: function (objs) {
            var result = {};
            if (objs) {
                var obj = objs[0];

                result = {
                    gradeGroupId: obj.GradeGroupId,
                };

                _.each(objs, function (obj) {
                    switch (obj.Code) {
                        case 'SMARTARC_TEMPERATURE_AIM':
                            result.TemperatureAim = obj.Value;
                            break;
                        case 'SMARTARC_O2PPM_AIM':
                            result.O2PPMAim = obj.Value;
                            break;
                        case 'SMARTARC_B3RATIO_AIM':
                            result.B3RatioAim = obj.Value;
                            break;
                        case 'SMARTARC_FeO_AIM':
                            result.FeOAim = obj.Value;
                            break;
                        case 'SMARTARC_MgO_AIM':
                            result.MgOAim = obj.Value;
                            break;
                        default:
                            break;
                    }
                });
            }

            return result;
        },
    });

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

        setDataColl: function (records) {
            var newColl,
                that = this;

            newColl = that.model.prototype.parse(records);
            that.set(newColl);
        },
    });


    //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.
    Screen.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return 'kpi-variables';
        } catch (Error) { }
    }

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'kpi-variables',
        id: 'kpi-variables',
        title: 'KPI Variables',
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        isCacheable: false,
        events: function () {
            return {
            };
        },
        autoRefresh: null,
        subviews: null,
        viewParams: null,

        minMaxEafItemColl: null,
        minMaxSlagColl: null,
        minMaxSmartArc: null,

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

            var that = this;

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

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

            this.minMaxEafItemColl = new (Backbone.Collection.extend({
                model: Backbone.Model.extend({
                    idAttribute: 'order',
                }),
                comparator: 'order',
            }))();

            this.minMaxSlagColl = new (Backbone.Collection.extend({
                model: Backbone.Model.extend({
                    idAttribute: 'order',
                }),
                comparator: 'order',
            }))();

            this.minMaxSmartArc = new (Backbone.Collection.extend({
                model: Backbone.Model.extend({
                    idAttribute: 'order',
                }),
                comparator: 'order',
            }))();


            this.subviews = {
                subnavbarControls: new Screen.Views.SubnavBarControls({
                    model: this.model,
                    parent: this,
                    container: app.views.subnavbar.getSectionContainer(1, 12),
                    events: function () {
                        return {
                            //'click .add-item': _.bind(that.addNewBtn_click, that),
                        };
                    },
                }),
            };


            this.bindEvents();
        },
        render: function (container, viewParams) {
            var that = this;

            this.viewParams = viewParams;

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

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

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

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

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

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

                            that.subviews.subnavbarControls.render();

                            var grid = that.options.itemsGrid = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'label',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                            render: function () {
                                                Backgrid.StringCell.prototype.render.apply(this, arguments);

                                                var value = this.model.get('code');

                                                if (value == 'MIN') {
                                                    this.$el.removeClass('max-row-header')
                                                        .addClass('min-row-header');
                                                }
                                                else {
                                                    this.$el.removeClass('min-row-header')
                                                        .addClass('max-row-header');
                                                }

                                                return this;
                                            },
                                        }),
                                    },
                                    {
                                        name: 'energyCostPerTon',
                                        label: app.translate(that, 'energy_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'oxygenCostPerTon',
                                        label: app.translate(that, 'oxygen_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'naturalGasCostPerTon',
                                        label: app.translate(that, 'natural_gas_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'carbonCostPerTon',
                                        label: app.translate(that, 'carbon_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'limeCostPerTon',
                                        label: app.translate(that, 'lime_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'eafTotalCostPerTon',
                                        label: app.translate(that, 'eaf_total_cost_per_ton_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'slagHeatsPercentage',
                                        label: app.translate(that, 'slag_heats_percentage_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'temperaturesPercentage',
                                        label: app.translate(that, 'temperatures_percentage_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                ],
                                collection: that.minMaxEafItemColl,
                            });
                            that.$el.find('.eaf-variables-items-grid-container').append(grid.render().el);


                            //Slag
                            var grid = that.options.itemsGrid = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'label',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell max-min-column',
                                            render: function () {
                                                Backgrid.StringCell.prototype.render.apply(this, arguments);

                                                var value = this.model.get('code');
                                                if (value == 'MIN') {
                                                    this.$el.removeClass('max-row-header')
                                                        .addClass('min-row-header');
                                                }
                                                else {
                                                    this.$el.removeClass('min-row-header')
                                                        .addClass('max-row-header');
                                                }

                                                return this;
                                            },
                                        }),
                                    },
                                    {
                                        name: 'MgO',
                                        label: app.translate(that, 'MgO_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'FeO',
                                        label: app.translate(that, 'FeO_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'B3',
                                        label: app.translate(that, 'B3_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                ],
                                collection: that.minMaxSlagColl,
                            });
                            that.$el.find('.slag-variables-items-grid-container').append(grid.render().el);



                            //Smart Arc
                            var grid = that.options.itemsGrid = new Backgrid.Grid({
                                className: 'backgrid table table-hover',
                                columns: [
                                    {
                                        name: 'label',
                                        label: '',
                                        editable: false,
                                        sortable: false,
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell max-min-column',
                                            render: function () {
                                                Backgrid.StringCell.prototype.render.apply(this, arguments);

                                                var value = this.model.get('code');
                                                if (value == 'AIM') {
                                                    this.$el.addClass('aim-row-header');
                                                }

                                                return this;
                                            },
                                        }),
                                    },
                                    {
                                        name: 'TemperatureAim',
                                        label: app.translate(that, 'TemperatureAim_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'O2PPMAim',
                                        label: app.translate(that, 'O2PPMAim_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'B3RatioAim',
                                        label: app.translate(that, 'B3RatioAim_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'FeOAim',
                                        label: app.translate(that, 'FeOAim_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                    {
                                        name: 'MgOAim',
                                        label: app.translate(that, 'MgOAim_col'),
                                        editable: true,
                                        sortable: false,
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell',
                                        }),
                                    },
                                ],
                                collection: that.minMaxSmartArc,
                            });
                            that.$el.find('.smart-arc-variables-items-grid-container').append(grid.render().el);

                            var fixedParams = _.extend({}, viewParams);

                            that.model.set('gradeGroupAbbrev', fixedParams.sectionParam1);
                            //end

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

                            //Call first refresh.
                            that.autoRefresh.enabled = false;
                            that._refresh()
                            //that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.minMaxEafItemColl, 'change', this.minMaxEafItemColl_changed)
                .listenTo(this.minMaxSlagColl, 'change', this.minMaxSlagColl_changed)
                .listenTo(this.minMaxSmartArc, 'change', this.minMaxSmartArc_changed)
                //.listenTo(this.model.get('items'), 'add remove', this.collectionAddRemove)
                .listenTo(this.model.get('items'), 'fetch', this.collection_fetch)
                .listenTo(this.model, 'change:gradeGroupAbbrev', this.gradeGroupAbbrev_changed)
                .listenTo(this.model, 'change:gradeGroupId', this.model_change_pickers);

        },
        gradeGroupAbbrev_changed: function () {
            var params = this.model.toJSON();
            var grade = _.findWhere(params.gradeGroups, { abbrev: params.gradeGroupAbbrev });
            if (grade && grade.value && grade.value != null)
                this.model.set({ gradeGroupId: grade.value });
        },

        _refresh: function (opt) {

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

            this.refreshItemsColl(opt);

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

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

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

            if (opt.reset == true)
                this.model.set('isLoading', true);

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

            itemsColl.fetch(_.extend(
                opt,
                {
                    params: _.extend(
                        modelAttrs,
                        opt.params,
                        {
                            refresh: opt.refresh,
                            reset: opt.reset,

                            gradeGroupId: (opt.params.gradeGroupId)
                                ? (opt.params.gradeGroupId != '0')
                                    ? opt.params.gradeGroupId
                                    : null
                                : (modelAttrs.gradeGroupId != '0')
                                    ? modelAttrs.gradeGroupId
                                    : null,
                            gradeGroupAbbrev: modelAttrs.gradeGroupAbbrev
                        }
                    ),
                }
            ));
        },

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

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

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

                this.options.onappend(this);
            }

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

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        startAutoRefresh: function () {
            try {
                if (this.autoRefresh.enabled !== true) {
                    var that = this;

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

                    this.autoRefresh.enabled = true;

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

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

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

            this.hideSubviews();
            this.stopAutoRefresh();

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

        updateMinMaxVariables: function (gradeGroupId, code, variablesChanged, success, error) {
            var that = this;
            var QP = new QueryParameters();
            var variables = [];
            var prefix = (code == 'MIN') ? 'Min' : 'Max';
            for (var prop in variablesChanged) {
                var fullProp = prop + prefix;

                switch (fullProp) {
                    case 'carbonCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'CARBON_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'carbonCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'CARBON_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;
                    case 'energyCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'ENERGY_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'energyCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'ENERGY_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;
                    case 'limeCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'LIME_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'limeCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'LIME_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;
                    case 'naturalGasCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'NATURAL_GAS_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'naturalGasCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'NATURAL_GAS_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;
                    case 'oxygenCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'OXYGEN_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'oxygenCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'OXYGEN_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;
                    case 'slagHeatsPercentageMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_HEATS_PERCENTAGE_MIN', value: variablesChanged[prop], });
                        break;
                    case 'slagHeatsPercentageMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_HEATS_PERCENTAGE_MAX', value: variablesChanged[prop], });
                        break;
                    case 'temperaturesPercentageMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'TAP_TEMPERATURES_PERCENTAGE_MIN', value: variablesChanged[prop], });
                        break;
                    case 'temperaturesPercentageMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'TAP_TEMPERATURES_PERCENTAGE_MAX', value: variablesChanged[prop], });
                        break;
                    case 'eafTotalCostPerTonMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'EAF_TOTAL_COST_PER_TON_MIN', value: variablesChanged[prop], });
                        break;
                    case 'eafTotalCostPerTonMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'EAF_TOTAL_COST_PER_TON_MAX', value: variablesChanged[prop], });
                        break;

                    case 'MgOMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_MgO_MAX_LIMIT', value: variablesChanged[prop], });
                        break;
                    case 'MgOMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_MgO_MIN_LIMIT', value: variablesChanged[prop], });
                        break;
                    case 'FeOMax':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_FeO_MAX_LIMIT', value: variablesChanged[prop], });
                        break;
                    case 'FeOMin':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_FeO_MIN_LIMIT', value: variablesChanged[prop], });
                        break;
                    case 'B3Max':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_B3_MAX_LIMIT', value: variablesChanged[prop], });
                        break;
                    case 'B3Min':
                        variables.push({ gradeGroupId: gradeGroupId, code: 'SLAG_B3_MIN_LIMIT', value: variablesChanged[prop], });
                        break;

                }
            }

            if (code == 'AIM') {
                for (var prop in variablesChanged) {
                    switch (prop) {
                        case 'TemperatureAim':
                            variables.push({ gradeGroupId: gradeGroupId, code: 'SMARTARC_TEMPERATURE_AIM', value: variablesChanged[prop], });
                            break;
                        case 'O2PPMAim':
                            variables.push({ gradeGroupId: gradeGroupId, code: 'SMARTARC_O2PPM_AIM', value: variablesChanged[prop], });
                            break;
                        case 'B3RatioAim':
                            variables.push({ gradeGroupId: gradeGroupId, code: 'SMARTARC_B3RATIO_AIM', value: variablesChanged[prop], });
                            break;
                        case 'FeOAim':
                            variables.push({ gradeGroupId: gradeGroupId, code: 'SMARTARC_FeO_AIM', value: variablesChanged[prop], });
                            break;
                        case 'MgOAim':
                            variables.push({ gradeGroupId: gradeGroupId, code: 'SMARTARC_MgO_AIM', value: variablesChanged[prop], });
                            break;
                    }
                }
            } 

            if (variables && variables[0]) {
                QP.Add('@gradeGroupId', 'INT', variables[0].gradeGroupId);
                QP.Add('@code', 'VARCHAR(50)', variables[0].code);
                QP.Add('@value', 'FLOAT', variables[0].value);

            }

            Core.Json.CallProcedure(app.DatabaseNames.MES + '.CAT.UpdateGradeGroupAttributes', QP, {
                onSuccess: function (data) {
                    //if (data && data.Table && data.Table.length > 0) {
                    //    var data = data.Table;

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

        collection_fetch: function (coll, resp) {
            try {

                this.model.get('slagLimits').setDataColl(resp);
                this.model.get('smartArc').setDataColl(resp);

                var obj = this.model.get('items').first().toJSON();
                var obj1 = this.model.get('smartArc').first().toJSON();
                var obj2 = this.model.get('slagLimits').first().toJSON();


                var minMaxEafData = [
                    {
                        gradeGroupId: obj.gradeGroupId,
                        label: app.translate([this, app], 'max_row_header_legend'),
                        code: 'MAX',
                        order: 0,

                        slagHeatsPercentage: obj.slagHeatsPercentageMax,
                        temperaturesPercentage: obj.temperaturesPercentageMax,

                        carbonCostPerTon: obj.carbonCostPerTonMax,
                        energyCostPerTon: obj.energyCostPerTonMax,
                        limeCostPerTon: obj.limeCostPerTonMax,
                        naturalGasCostPerTon: obj.naturalGasCostPerTonMax,
                        oxygenCostPerTon: obj.oxygenCostPerTonMax,
                        eafTotalCostPerTon: obj.eafTotalCostPerTonMax,
                    },
                    {
                        gradeGroupId: obj.gradeGroupId,
                        label: app.translate([this, app], 'min_row_header_legend'),
                        code: 'MIN',
                        order: 1,

                        slagHeatsPercentage: obj.slagHeatsPercentageMin,
                        temperaturesPercentage: obj.temperaturesPercentageMin,

                        carbonCostPerTon: obj.carbonCostPerTonMin,
                        energyCostPerTon: obj.energyCostPerTonMin,
                        limeCostPerTon: obj.limeCostPerTonMin,
                        naturalGasCostPerTon: obj.naturalGasCostPerTonMin,
                        oxygenCostPerTon: obj.oxygenCostPerTonMin,
                        eafTotalCostPerTon: obj.eafTotalCostPerTonMin,
                    },
                ];
                var minMaxSlagData = [
                    {
                        gradeGroupId: obj.gradeGroupId,
                        label: app.translate([this, app], 'max_row_header_legend'),
                        code: 'MAX',
                        order: 0,
                        MgO: obj2.MgOMax,
                        FeO: obj2.FeOMax,
                        B3: obj2.B3Max,
                    },
                    {
                        gradeGroupId: obj.gradeGroupId,
                        label: app.translate([this, app], 'min_row_header_legend'),
                        code: 'MIN',
                        order: 1,

                        MgO: obj2.MgOMin,
                        FeO: obj2.FeOMin,
                        B3: obj2.B3Min,
                    },
                ];

            
                var minMaxSmartArcData = [
                    {
                        gradeGroupId: obj.gradeGroupId,
                        label: app.translate([this, app], 'aim_row_header_legend'),
                        code: 'AIM',
                        order: 0,
                        TemperatureAim  : obj1.TemperatureAim
                        ,O2PPMAim        : obj1.O2PPMAim      
                        ,B3RatioAim      : obj1.B3RatioAim    
                        ,FeOAim          : obj1.FeOAim        
                        ,MgOAim          : obj1.MgOAim        
                    },
                    //{
                    //    gradeGroupId: obj.gradeGroupId,
                    //    label: app.translate([this, app], 'min_row_header_legend'),
                    //    code: 'MIN',
                    //    order: 1,
                    //    TemperatureAim: obj1.TemperatureAim
                    //    , O2PPMAim: obj1.O2PPMAim
                    //    , B3RatioAim: obj1.B3RatioAim
                    //    , FeOAim: obj1.FeOAim
                    //    , MgOAim: obj1.MgOAim    
                    //},
                ];



                this.minMaxEafItemColl.set(minMaxEafData, { from: 'fetch', });

                this.minMaxSlagColl.set(minMaxSlagData, { from: 'fetch', });

                this.minMaxSmartArc.set(minMaxSmartArcData, { from: 'fetch', });



                this.model.set({
                    hasData: (this.model.get('items').length > 0),
                    isLoading: false,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        minMaxEafItemColl_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;

            if (!fromFetch && !avoidSync) {
                this.updateMinMaxVariables(
                    m.get('gradeGroupId'),
                    m.get('code'),
                    m.changed,
                    function (ref, ids) { },
                    function (coll, msg) {
                        app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                        that._refresh();
                    }
                );
            }
        },

        minMaxSlagColl_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;

            if (!fromFetch && !avoidSync) {
                this.updateMinMaxVariables(
                    m.get('gradeGroupId'),
                    m.get('code'),
                    m.changed,
                    function (ref, ids) { },
                    function (coll, msg) {
                        app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                        that._refresh();
                    }
                );
            }
        },
        minMaxSmartArc_changed: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == 'fetch') ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            if (!fromFetch && !avoidSync) {
                this.updateMinMaxVariables(
                    m.get('gradeGroupId'),
                    m.get('code'),
                    m.changed,
                    function (ref, ids) { },
                    function (coll, msg) {
                        app.views.topMessages.showMessage(app.translate(app, msg), { stay: 10000, });
                        that._refresh();
                    }
                );
            }
        },
        model_change_pickers: function (model, value, opt) {
            try {
                var params = this.model.toJSON();
                var grade = _.findWhere(params.gradeGroups, { value: parseInt(params.gradeGroupId) });

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

                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                sectionParam1: 'kpivariables/' + grade.abbrev,

                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );

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

    //subview for the subnavbar controls
    Screen.Views.SubnavBarControls = Backbone.Epoxy.View.extend({
        id: 'kpi-variables-subnavbar-controls',
        title: '',
        template: 'kpi-variables',

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

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

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

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

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

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

                    that.applyBindings();

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

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

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

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

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

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

                this.options.onappend(this);
            }

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

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

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

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

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

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

});
