//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/modal2',
  'moment',

  'custom-screens/chemistry-samples/chemistry-samples',
  'custom-screens/slag-chemistry-samples/slag-chemistry-samples',
  'modules/views/delays-1/delays-1',

  'modules/arc-length-setting/arc-length-setting',
  'modules/bucket/bucket',
  'modules/eaf-process/eaf-process',
  'modules/eaf-process-bucket/eaf-process-bucket',
  'modules/eaf-process-phase/eaf-process-phase',
  'modules/electrode-change-reason',
  'modules/furnace/furnace',
  'modules/grade/grade',
  'modules/heat/heat',
  'modules/ladle/ladle',
  'modules/material/material',
  'modules/operator/operator',
  'modules/process-addition/process-addition',
  'modules/process-consumption/process-consumption',
  'modules/process-temperature/process-temperature',
  'modules/regulation-mode/regulation-mode',
  'modules/user-property/user-property',

  'js/backgrid-0.3.5/extensions/add-row-cell/backgrid-add-row-cell',
  'js/backgrid-0.3.5/extensions/button-cell/backgrid-button-cell',
  'backgrid/calendar-cell',
  'backgrid/moment-cell',
  //'js/jquery.clearsearch/jquery.clearsearch',
  'js/jquery.mask',
  'js/jquery.scrollIntoView/jquery.scrollIntoView',
  'js/jquery.selectonfocus/jquery.selectonfocus',
  'js/jquery.timepicker/jquery.timepicker',
  'js/typeahead.extended/typeahead.extended',

  'backgrid/time-cell', //Depends on the time jquery.timepicker
],
function (app, T, Backgrid, Modal, moment, ChemistrySamplesView, SlagChemistrySamplesView, DelaysManagerView, ArcLengthSetting, Bucket, EafProcess, EafProcessBucket, EafProcessPhase, ElectrodeChangeReason, Furnace, Grade, Heat, Ladle, Material, Operator, ProcessAddition, ProcessConsumption, ProcessTemperature, RegulationMode, UserProperty) {

    //Get current user Eaf furnace code property to use it to filter processes navigation.
    var eafFurnaceProp = UserProperty.Collections.CurrentUserProperties.findWhere({ code: 'EAF_FURNACE', });

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            mainView: true,

            arcLengthSettings: [],
            buckets: [],
            delaysNotDeclaredCount: 0,
            editingProcess: true,
            electrodeChangeReasons: [],
            furnaceCode: null,
            furnaces: {},
            grades: [],
            heatId: null,
            ladles: [],
            materials: [],
            navigating: false,
            operators: [],
            processId: -1, //To get current process.
            //Regulation modes are different for each furnace. But this is temporaly.
            //That is why items for furnace B are hardcoded. In the future both
            //furnaces will have the same list of items.
            //Revert all this stuff when both furnaces have the same items.
            //regulationModes: [],
            regulationModesA: [],
            regulationModesB: [],
            search: '',
            userFurnaceCode: null,

            hasData: false,
            isLoading: false,
            hasDataProcess: false,
            isLoadingProcess: false,
        },
        fetchDropdown: function (options) {
            var that = this,
                qp = null;

            var opt = _.extend(
                { error: function () { }, success: function () { }, },
                options
            );

            if (opt.params) {
                //Check if params is a query parameters instance or not.
                if (opt.params.GetQueryParameter) {
                    qp = opt.params;
                }
                else {
                    qp = new QueryParameters();

                    for (var pname in opt.params)
                        qp.Add(pname, 'VARCHAR', opt.params[pname]);
                }
            }

            //qp.Add('@onlyEnabled', 'BIT', 1);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + ".EAF.SearchHeats",
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                var records = resp.Table;
                                opt.success(records);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },

                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        computeds: {
            userHasAccess: {
                deps: ['mainView', 'furnaceCode', 'userFurnaceCode'],
                get: function (mainView, furnaceCode, userFurnaceCode) {
                    return ((mainView == false) || ((furnaceCode == userFurnaceCode) || (userFurnaceCode == -1)));
                },
            },
            furnaceName: {
                deps: ['furnaceCode', 'furnaces'],
                get: function (furnaceCode, furnaces) {
                    return ((furnaceCode) && (furnaces) && (furnaces[furnaceCode]))
                                ? furnaces[furnaceCode].name
                                : null;
                }
            },
            hasArcLengthSettings: {
                deps: ['arcLengthSettings'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            hasGrades: {
                deps: ['grades'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            hasLadles: {
                deps: ['ladles'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            hasOperators: {
                deps: ['operators'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            hasRegulationModes: {
                deps: ['regulationModes'],
                get: function (value) {
                    return ((value) && (value.length > 0));
                }
            },
            //Regulation modes are different for each furnace. But this is temporaly.
            //That is why items for furnace B are hardcoded. In the future both
            //furnaces will have the same list of items.
            //Revert all this stuff when both furnaces have the same items.
            regulationModes: {
                deps: ['furnaceCode', 'regulationModesA', 'regulationModesB'],
                get: function (furnaceCode, regulationModesA, regulationModesB) {
                    return (furnaceCode == 1)
                                ? regulationModesA
                                : regulationModesB;
                }
            },
        },
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'eaf-process',
        id: 'eaf-process',
        className: 'eaf-process-screen',
        title: 'EAF Process',
        events: function () {
            return {
                'click .btn-change-electrode': this.changeElectrodeBtn_click,
                'click .btn-ship': this.shipBtn_click,
                'click .delays-anchor-link': this.delaysAnchorLink_click,
                'click #getPreviousItemBtn': this.getPreviousItemBtn_click,
                'click #getNextItemBtn': this.getNextItemBtn_click,
                'keypress input[type="text"].process-info-field-value': this.processInfoFieldValueTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
                //'click #refreshBtn': this.refreshBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,

        additions: null,
        buckets: null,
        bucketDetails: null,
        consumptions: null,
        consumptionsCommon: null,
        consumptionsSidewall: null,
        consumptionCodesCommon: ['CARBON', 'INJECTED_LIME', 'LANCE_CARBON', 'LANCE_OXYGEN', 'SIDEWALL_CARBON', ],
        consumptionCodesSidewall: {
            naturalGas: ['NATURAL_GAS_BURNER_1', 'NATURAL_GAS_BURNER_2', 'NATURAL_GAS_BURNER_3', 'NATURAL_GAS_BURNER_4', 'NATURAL_GAS_BURNER_5',],
            oxygen: ['OXYGEN_BURNER_1', 'OXYGEN_BURNER_2', 'OXYGEN_BURNER_3', 'OXYGEN_BURNER_4', 'OXYGEN_BURNER_5',],
        },
        phases: null,
        process: null,
        //processLastFetch: null,
        subviews: null,
        temperatures: null,
        viewParams: null,
        searchTbx: null,
        searchItems: null,
        delaysManagerView: null,
        displayChemistry: true, //Do not add this prop to the model because it will not be dynamic. It means that if the prop changes after view is initialized, it will have no efects.
        chemistrySamplesView: null,
        slagChemistrySamplesView: null,

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

            var that = this;

            _.extend(this, options);

            if (!this.model) {
                this.model = new Screen.Models.Main({
                    userFurnaceCode: (eafFurnaceProp) ? eafFurnaceProp.get('value') : null,
                });
            }

            if (!this.process)
                this.process = new Screen.Models.Process();

            this.additions = new (ProcessAddition.Collections.ProcessAdditions.extend({
                model: ProcessAddition.Models.ProcessAddition.extend({
                    procedures: {
                        create: app.DatabaseNames.MES + '.EAF.CreateAdditionManual',
                        get: app.DatabaseNames.MES + '.EAF.GetAdditions',
                        update: app.DatabaseNames.MES + '.EAF.UpdateAddition',
                        remove: app.DatabaseNames.MES + '.EAF.RemoveAddition',
                    },
                    editableAttrs: ['materialId', 'timestamp', 'weight',],
                }),
                //Modify comparator to put first the objects with isNew=true to prevent sorting while editing the new object.
                comparator: function (a, b) {
                    var valA = a.get('isNew'),
                        valB = b.get('isNew');

                    if (valA != valB) {
                        return (valA == true) ? -1 : 1;
                    }
                    else {
                        valA = new moment(a.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate(),
                        valB = new moment(b.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate();

                        return (valA < valB)
                                    ? -1
                                    : (valA > valB)
                                        ? 1
                                        : 0;
                    }
                },
            }))();

            this.buckets = new (EafProcessBucket.Collections.EafProcessBuckets.extend({
                model: EafProcessBucket.Models.EafProcessBucket.extend({
                    editableAttrs: ['bucketId', 'othersWeight', 'scrapWeight', 'timestamp',],
                }),
                //Modify comparator to put first the objects with isNew=true to prevent sorting while editing the new object.
                comparator: function (a, b) {
                    var valA = a.get('isNew'),
                        valB = b.get('isNew');

                    if (valA != valB) {
                        return (valA == true) ? -1 : 1;
                    }
                    else {
                        valA = new moment(a.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate(),
                        valB = new moment(b.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate();

                        return (valA < valB)
                                    ? -1
                                    : (valA > valB)
                                        ? 1
                                        : 0;
                    }
                },
            }))();

            var ProcessConsumptionByCode = ProcessConsumption.Models.ProcessConsumption.extend({
                idAttribute: 'code',
                procedures: {
                    get: app.DatabaseNames.MES + '.EAF.GetConsumptions',
                    removeManualVariable: app.DatabaseNames.MES + '.EAF.RemoveProcessManualVariable',
                    update: app.DatabaseNames.MES + '.EAF.UpdateConsumptionManual',
                },
            });

            this.consumptions = new (ProcessConsumption.Collections.ProcessConsumptions.extend({
                model: ProcessConsumptionByCode,
            }))();
            this.consumptionsCommon = new ProcessConsumption.Collections.ProcessConsumptions();
            this.consumptionsSidewall = new ProcessConsumption.Collections.ProcessConsumptions();

            _.each(this.consumptionCodesCommon, function (code) {
                var model = new ProcessConsumptionByCode({
                    code: code,
                });

                that.consumptions.add(model);
                //that.consumptionsCommon.add(model);
            });

            _.each([].concat(this.consumptionCodesSidewall.naturalGas, this.consumptionCodesSidewall.oxygen), function (code) {
                var model = new ProcessConsumptionByCode({
                    code: code,
                });

                that.consumptions.add(model);
                that.consumptionsSidewall.add(model);
            });

            this.phases = new EafProcessPhase.Collections.EafProcessPhases();

            this.temperatures = new (ProcessTemperature.Collections.ProcessTemperatures.extend({
                model: ProcessTemperature.Models.ProcessTemperature.extend({
                    procedures: {
                        create: app.DatabaseNames.MES + '.EAF.CreateTemperatureManual',
                        get: app.DatabaseNames.MES + '.EAF.GetTemperatures',
                        update: app.DatabaseNames.MES + '.EAF.UpdateTemperature',
                        remove: app.DatabaseNames.MES + '.EAF.RemoveTemperature',
                    },
                    editableAttrs: ['carbon', 'oxygen', 'temperature', 'timestamp'],
                }),
                //Modify comparator to put first the objects with isNew=true to prevent sorting while editing the new object.
                comparator: function (a, b) {
                    var valA = a.get('isNew'),
                        valB = b.get('isNew');

                    if (valA != valB) {
                        return (valA == true) ? -1 : 1;
                    }
                    else {
                        valA = new moment(a.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate(),
                        valB = new moment(b.get('timestamp'), 'YYYY-MM-DD HH:mm:ss.SSS').toDate();

                        return (valA < valB)
                                    ? -1
                                    : (valA > valB)
                                        ? 1
                                        : 0;
                    }
                },
            }))();


            this.bindingSources = {
                process: this.process,
                phases: this.phases,
            };

            ArcLengthSetting.Collections.ArcLengthSettings.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('arcLengthSettings', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Bucket.Collections.Buckets.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('buckets', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            ElectrodeChangeReason.Collections.ElectrodeChangeReasons.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('electrodeChangeReasons', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Furnace.Collections.Furnaces.fetch({
                async: false,
                success: function (records) {
                    var data = {};

                    _.each(records, function (obj) {
                        data[obj.code] = obj;
                    });

                    try {
                        that.model.set('furnaces', data);
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Grade.Collections.Grades.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('grades', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Ladle.Collections.Ladles.fetch({

                async: false,
                success: function (records) {
                    try {
                        that.model.set('ladles', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Material.Collections.Materials.fetch({
                params: {
                    area: 'EAF',
                    furnace: (that.model.get('furnaceCode') != null) ?
                        (that.model.get('furnaceCode') != -1) ? that.model.get('furnaceCode') : null
                        : parseInt(that.options.viewParams.furnaceCode, 10)
                },
                async: false,
                success: function (records) {
                    try {

                        that.model.set('materials', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            Operator.Collections.Operators.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('operators', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            RegulationMode.Collections.RegulationModes.fetch({
		        //Regulation modes are different for each furnace. But this is temporaly.
		        //That is why items for furnace B are hardcoded. In the future both
		        //furnaces will have the same list of items.
		        //Revert all this stuff when both furnaces have the same items.
                params: {
                    furnaceCode: 1,
                    //furnaceCode: (options.viewParams.furnaceCode) ? parseInt(options.viewParams.furnaceCode, 10) : null,
                },
                async: false,
                success: function (records) {
                    try {
                        that.model.set('regulationModesA', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });
            RegulationMode.Collections.RegulationModes.fetch({
                //Regulation modes are different for each furnace. But this is temporaly.
                //That is why items for furnace B are hardcoded. In the future both
                //furnaces will have the same list of items.
                //Revert all this stuff when both furnaces have the same items.
                params: {
                    furnaceCode: 2,
                    //furnaceCode: (options.viewParams.furnaceCode) ? parseInt(options.viewParams.furnaceCode, 10) : null,
                },
                async: false,
                success: function (records) {
                    try {
                        that.model.set('regulationModesB', _.map(records, function (obj) { return { value: obj.id, label: obj.name, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });


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


            //Initialize subviews here to then add events to their model on bind event method.
            if (this.displayChemistry == true) {
                this.subviews.chemistrySamplesView =
                this.chemistrySamplesView = new ChemistrySamplesView.Views.Main({
                    model: new ChemistrySamplesView.Models.Main({
                        editionEnabled: false,
                        mainView: false,
                    }),
                    parent: this,

                    eafProcess: this.process,
                });
            }

            this.subviews.delaysManagerView =
            this.delaysManagerView = new DelaysManagerView.Views.Main({
                parent: this,
                editionEnabled: this.model.get('mainView'),
                procedures: {
                    get: app.DatabaseNames.MES + '.EAF.GetDelays',
                },
            });

            this.subviews.slagChemistrySamplesView =
            this.slagChemistrySamplesView = new SlagChemistrySamplesView.Views.Main({
                model: new SlagChemistrySamplesView.Models.Main({
                    editionEnabled: false,
                    mainView: false,
                }),
                parent: this,

                eafProcess: this.process,
            });


            this.bindEvents();
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.additions, 'backgrid:action', this.collection_backgrid_action)
                .listenTo(this.additions, 'change', this.collection_change)
                .listenTo(this.buckets, 'backgrid:action', this.collection_backgrid_action)
                .listenTo(this.buckets, 'change', this.collection_change)
                .listenTo(this.consumptions, 'change', this.collection_change)
                .listenTo(this.consumptions, 'fetch', this.consumptions_fetch)
                .listenTo(this.delaysManagerView.model.get('delaySplits'), 'add change remove reset', _.debounce(this.delaysManagerView_model_delaySplits_addChangeRemoveReset, 200))
                .listenTo(this.model, 'change:heatId change:processId', this.model_change_pickers)
                .listenTo(this.process, 'change', this.process_change)
                .listenTo(this.process, 'change:heatName', this.process_change_heatName)
                .listenTo(this.process, 'fetch', this.process_fetch)
                .listenTo(this.temperatures, 'backgrid:action', this.collection_backgrid_action)
                .listenTo(this.temperatures, 'change', this.collection_change);
        },
        _refresh: function (opt) {
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }

            this.refreshProcess(opt);

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

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (fixedParams) {
            if (fixedParams.furnaceCode)
                fixedParams.furnaceCode = parseInt(fixedParams.furnaceCode, 10);
            if (fixedParams.processId)
                fixedParams.processId = parseInt(fixedParams.processId, 10);

            this.model.set(fixedParams);
        },
        render: function (container, viewParams) {
            var that = this,
                modelAttrs = this.model.toJSON();

            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(_.extend(
                                modelAttrs,
                                {
                                    displayChemistry: that.displayChemistry,
                                }
                            )));

                            that.phaseChartView = Backbone.Epoxy.View.extend({
                                template: Handlebars.compile(that.$el.find('#phase_chart_view').html()),
                                initialize: function () {
                                    this.render();
                                },
                                render: function() {
                                    this.$el.html(this.template(this.model.toJSON()));
                                    return this;
                                },
                            });

                            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')


                            if (modelAttrs.mainView == true) {
                                that.searchTbx = that.$el.find("#searchTbx").typeaheadExtended({
                                    items: Infinity,
                                    minLength: 0,
                                    source: _.bind(that.getSearchControlSource, that),
                                    updater: function (item) {
                                        var match;
                                        try {
                                            match = that.selectItemFromSearchComboItem(item);
                                        }
                                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                        finally {
                                            if (match)
                                                return match.heatName;
                                            else
                                                return item;
                                        }
                                    }
                                });
                            }

                            if (modelAttrs.editingProcess == true) {
                                $.jMaskGlobals.watchDataMask = true;

                                that.$el.find('.input-date').datepicker();

                                that.$el.find('.input-time').jqtimepicker({
                                    showOn: false,
                                    timeFormat: 'H:i:s',
                                });

                                //Only bind click event to those items with data variable name set.
                                that.$el.find('.manual-lock-btn[data-variable-name]').bind('click', _.bind(that.manualLockBtn_click, that));
                            }


                            var fn_gridCheckEditionEnable = function (a, b, c) {
                                return that.model.get('editingProcess');
                            };

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [].concat([
                                    {
                                        name: 'materialId',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_additions_material_col'),
                                        cell: Backgrid.SelectCell.extend({
                                            className: 'select-cell align-center-cell materialId',
                                            optionValues: _.map(that.model.get('materials'), function (obj) { return [obj.label, obj.value, ]; }),
                                        }),
                                    },
                                    {
                                        name: 'weight',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_additions_weight_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell weight',
                                            decimals: 2,
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_additions_timestamp_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-right-cell timestamp-cell date-cell timestamp',
                                            formatter: Backgrid.Extension.DatetimeToDateFormatter.extend({
                                                columnName: 'timestamp',
                                                displayFormat: app.translate([that, app], 'mmddyyyy'),
                                                modelDateFormat: 'YYYY-MM-DD',
                                            }),
                                            editor: Backgrid.Extension.CalendarCellEditor.extend({
                                                dateFormat: 'mm/dd/yy',
                                                momentFormat: app.translate([that, app], 'mmddyyyy'),
                                            }),
                                        }),
                                        headerCell: Backgrid.HeaderCell.extend({
                                            attributes: {
                                                colspan: 2,
                                            },
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-left-cell timestamp-cell time-cell timestamp',
                                            formatter: Backgrid.Extension.DatetimeToTimeFormatter.extend({
                                                columnName: 'timestamp',
                                                displayFormat: app.translate([that, app], 'HH:mm:ss'),
                                                modelDateFormat: 'YYYY-MM-DD',
                                            }),
                                            editor: Backgrid.Extension.TimeCellEditor.extend({
                                                showOn: false,
                                            }),
                                        }),
                                        headerCell: Backgrid.HeaderCell.extend({
                                            attributes: {
                                                style: 'display: none;',
                                            }
                                        }),
                                    },
                                ], ((modelAttrs.editingProcess == true) ? [{
                                    cell: Backgrid.Extension.ButtonCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                    }),
                                    headerCell: Backgrid.Extension.AddRowHeaderCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_header_cell_template').html()),
                                    }),
                                }] : [])
                                ),
                                collection: that.additions,
                            });
                            that.$el.find('.process-additions-grid-container').append(grid.render().el);

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [].concat([
                                    {
                                        name: 'bucketId',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_bucket_col'),
                                        cell: Backgrid.SelectCell.extend({
                                            className: 'select-cell align-center-cell bucketId',
                                            optionValues: _.map(that.model.get('buckets'), function (obj) { return [obj.label, obj.value, ]; }),
                                        }),
                                    },
                                    {
                                        name: 'scrapWeight',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_scrap_weight_col'),
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'number-cell align-center-cell scrapWeight',
                                        }),
                                    },
                                    {
                                        name: 'fluxWeight1',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_fluxWeight1_col'),
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'number-cell align-center-cell fluxesWeight',
                                            
                                        }),
                                    },
                                    {
                                        name: 'fluxWeight2',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_fluxWeight2_col'),
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'number-cell align-center-cell othersWeight',
                                            
                                        }),
                                    },
                                    {
                                        name: 'fluxWeight3',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_fluxWeight3_col'),
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'number-cell align-center-cell othersWeight',
                                            
                                        }),
                                    },
                                    {
                                        name: 'fluxWeight4',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_fluxWeight4_col'),
                                        cell: Backgrid.IntegerCell.extend({
                                            className: 'number-cell align-center-cell othersWeight',
                                            
                                        }),
                                    },
                                    {
                                        name: 'othersWeight',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_others_weight_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell othersWeight',
                                            decimals: 0,
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_buckets_timestamp_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell timestamp-cell date-cell timestamp',
                                            formatter: Backgrid.Extension.DatetimeToDateFormatter.extend({
                                                columnName: 'timestamp',
                                                displayFormat: app.translate([that, app], 'mmddyyyy'),
                                                modelDateFormat: 'YYYY-MM-DD',
                                            }),
                                            editor: Backgrid.Extension.CalendarCellEditor.extend({
                                                dateFormat: 'mm/dd/yy',
                                                momentFormat: app.translate([that, app], 'mmddyyyy'),
                                            }),
                                        }),
                                        headerCell: Backgrid.HeaderCell.extend({
                                            attributes: {
                                                colspan: 2,
                                            },
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell timestamp-cell time-cell timestamp',
                                            formatter: Backgrid.Extension.DatetimeToTimeFormatter.extend({
                                                columnName: 'timestamp',
                                                displayFormat: app.translate([that, app], 'HH:mm:ss'),
                                                modelDateFormat: 'YYYY-MM-DD',
                                            }),
                                            editor: Backgrid.Extension.TimeCellEditor.extend({
                                                showOn: false,
                                            }),
                                        }),
                                        headerCell: Backgrid.HeaderCell.extend({
                                            attributes: {
                                                style: 'display: none;',
                                            }
                                        }),
                                    },
                                ], ((modelAttrs.editingProcess == true) ? [{
                                    cell: Backgrid.Extension.ButtonCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_cell_template_buckets').html()),
                                        render: function () {
                                            this.$el.html(this.template({
                                                editingProcess: modelAttrs.editingProcess,
                                            }));

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

                                            this.checkMode();

                                            this.delegateEvents();

                                            return this;
                                        },
                                    }),
                                    headerCell: Backgrid.Extension.AddRowHeaderCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_header_cell_template').html()),
                                    }),
                                }] : [{
                                    cell: Backgrid.Extension.ButtonCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_cell_template_buckets').html()),
                                        render: function () {
                                            this.$el.html(this.template({
                                                editingProcess: modelAttrs.editingProcess,
                                            }));

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

                                            this.checkMode();

                                            this.delegateEvents();

                                            return this;
                                        },
                                    })
                                }])
                                ),
                                collection: that.buckets,
                            });
                            that.$el.find('.process-buckets-grid-container').append(grid.render().el);

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [
                                    {
                                        name: 'name',
                                        label: app.translate([that, app], 'process_consumptions_name_col'),
                                        editable: false,
                                        cell: Backgrid.StringCell.extend({
                                            className: Backgrid.StringCell.prototype.className + ' align-center-cell',
                                        }),
                                    },
                                    //{
                                    //    name: 'status',
                                    //    label: app.translate([that, app], 'process_consumptions_status_col'),
                                    //    cell: MakeCellManualAutomatic(Backgrid.BooleanCell).extend({
                                    //        decimals: 2,
                                    //        process: that.process,
                                    //        variableName: function () {
                                    //            return this.model.get('code') + '.STATUS';
                                    //        },
                                    //    }),
                                    //},
                                    //{
                                    //    name: 'flowRate',
                                    //    label: app.translate([that, app], 'process_consumptions_flow_rate_col'),
                                    //    cell: MakeCellManualAutomatic(Backgrid.NumberCell).extend({
                                    //        decimals: 2,
                                    //        process: that.process,
                                    //        variableName: function () {
                                    //            return this.model.get('code') + '.FLOWRATE';
                                    //        },
                                    //    }),
                                    //},
                                    {
                                        name: 'counter',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_consumptions_counter_col'),
                                        cell: MakeCellManualAutomatic(Backgrid.IntegerCell).extend({
                                            process: that.process,
                                            variableName: function () {
                                                return this.model.get('code') + '.COUNTER';
                                            },
                                        }),
                                    },
                                ],
                                collection: that.consumptionsCommon,
                            });
                            that.$el.find('.process-consumptions-grid-container').append(grid.render().el);

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [
                                    {
                                        name: 'code',
                                        label: app.translate([that, app], 'process_phases_code_col'),
                                        editable: false,
                                        cell: Backgrid.StringCell.extend({
                                            className: Backgrid.StringCell.prototype.className + ' align-left-cell',
                                            template: Handlebars.compile('<div class="bullet phase-{{order}}-color"></div><span>{{value}}</span>'),
                                            render: function () {
                                                //this.$el.removeClass(function (index, css) {
                                                //        return (css.match(/(^|\s)phase-[0-9]{1,}-color\S+/g) || []).join(' ');
                                                //    })
                                                //    .addClass(
                                                //        Backgrid.StringCell.prototype.className 
                                                //            + ' align-center-cell'
                                                //            + ' phase-' + this.model.get('order') + '-color'
                                                //    );

                                                this.$el.html(this.template({
                                                    value: this.formatter.fromRaw(this.model.get(this.column.get('name')), this.model),
                                                    order: this.model.get('order'),
                                                }));

                                                this.delegateEvents();

                                                return this;
                                            },
                                        }),
                                    },
                                    {
                                        name: 'energy',
                                        editable: false,
                                        label: app.translate([that, app], 'process_phases_energy_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            decimals: 2,
                                        }),
                                    },
                                    {
                                        name: 'carbon',
                                        editable: false,
                                        label: app.translate([that, app], 'process_phases_carbon_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            decimals: 0,
                                        }),
                                    },
                                    {
                                        name: 'naturalGas',
                                        editable: false,
                                        label: app.translate([that, app], 'process_phases_natural_gas_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            decimals: 0,
                                        }),
                                    },
                                    {
                                        name: 'oxygen',
                                        editable: false,
                                        label: app.translate([that, app], 'process_phases_oxygen_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            decimals: 0,
                                        }),
                                    },
                                      {
                                          name: 'o2ss',
                                          editable: false,
                                          label: app.translate([that, app], 'process_phases_o2ss_col'),
                                          cell: Backgrid.NumberCell.extend({
                                              decimals: 0,
                                          }),
                                      },
                                ],
                                collection: that.phases,
                            });
                            that.$el.find('.process-phases-grid-container').append(grid.render().el);

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [].concat([
                                    {
                                        name: 'temperature',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_temperatures_temperature_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell temperature',
                                            decimals: 0,
                                        }),
                                    },
                                    {
                                        name: 'oxygen',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_temperatures_oxygen_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell oxygen',
                                            decimals: 0,
                                        }),
                                    },
                                    {
                                        name: 'carbon',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_temperatures_carbon_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'number-cell align-center-cell carbon',
                                            decimals: 3,
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'process_temperatures_timestamp_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell timestamp-cell date-cell timestamp',
                                            formatter: Backgrid.Extension.DatetimeToTimeFormatter.extend({
                                                columnName: 'timestamp',
                                                displayFormat: app.translate([that, app], 'HH:mm:ss'),
                                                modelDateFormat: 'YYYY-MM-DD',
                                            }),
                                            editor: Backgrid.Extension.TimeCellEditor.extend({
                                                showOn: false,
                                            }),
                                        }),
                                        headerCell: Backgrid.HeaderCell.extend({
   
                                        }),
                                    },

                                ], ((modelAttrs.editingProcess == true) ? [{
                                    cell: Backgrid.Extension.ButtonCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                    }),
                                    headerCell: Backgrid.Extension.AddRowHeaderCell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_header_cell_template').html()),
                                    }),
                                }] : [])
                                ),
                                collection: that.temperatures,
                            });
                            that.$el.find('.process-temperatures-grid-container').append(grid.render().el);


                            var container = that.$el.find(".process-consumptions-sidewalls-grid-container"),
                                subtemplate = Handlebars.compile(that.$el.find('#consumable_sidewall_col_template').html()),
                                consumptionsSidewallCount = that.consumptionsSidewall.length / 2;

                            var colWidth = Math.floor(100 / (consumptionsSidewallCount));

                            for (var i = 0; i < consumptionsSidewallCount; i++) {
                                var view = new Screen.Views.ConsumpitonSidewall({
                                    model: new Screen.Models.ConsumpitonSidewall({
                                        editingProcess: modelAttrs.editingProcess,
                                    }),
                                    parent: that,

                                    oxygenConsumption: that.consumptionsSidewall.get(that.consumptionCodesSidewall.oxygen[i]),
                                    naturalGasConsumption: that.consumptionsSidewall.get(that.consumptionCodesSidewall.naturalGas[i]),
                                    process: that.process,
                                });

                                view.$el.html(subtemplate());
                                view.applyBindings();

                                view.$el.css({ width: colWidth + "%", });

                                that.append(container, view.$el);
                            }

                            if (that.displayChemistry == true) {
                                that.chemistrySamplesView.preRender(viewParams);
                                that.chemistrySamplesView.render(that.$el.find(".chemistry-samples-info-container"), viewParams);
                            }

                            that.slagChemistrySamplesView.preRender(viewParams);
                            that.slagChemistrySamplesView.render(that.$el.find(".slag-chemistry-samples-info-container"), viewParams);

                            that.delaysManagerView.preRender(viewParams);
                            that.delaysManagerView.render(that.$el.find(".delays-grid-container"), viewParams);


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


                            //Set model with view params here to prevent changes on the model when the view bindings are applied.
                            var fixedParams = _.extend({}, viewParams);

                            if (fixedParams.furnaceCode)
                                fixedParams.furnaceCode = parseInt(fixedParams.furnaceCode, 10);
                            if (fixedParams.processId)
                                fixedParams.processId = parseInt(fixedParams.processId, 10);

                            that.model.set(fixedParams);


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

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

                            if (modelAttrs.mainView == true)
                                that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },

        getNextProcess: function (next) {
            var that = this;

            this.model.set('navigating', true);

            this.process.getNextProcess({
                params: {
                    next: next,
                    furnaceCode: this.model.get('furnaceCode'),
                },
                success: function (model, nextProcess) {
                    try {
                        if ((nextProcess) && (nextProcess.id)) {
                            if (nextProcess.id == that.model.get('processId'))
                                that.model.set('navigating', false);

                            that.model.set('processId', nextProcess.id);
                        }
                        else {
                            that.model.set('navigating', false);

                            if (next)
                                app.views.topMessages.showMessage(app.translate([that, app], 'no_next_process'), { stay: 5 * 1000, });
                            else
                                app.views.topMessages.showMessage(app.translate([that, app], 'no_previous_process'), { stay: 5 * 1000, });
                        }
                    }
                    catch (Error) {
                        console.error(Error.stack);

                        that.model.set('navigating', false);
                    }
                },
                error: function () {
                    that.model.set('navigating', false);
                },
            });
        },
        getSearchControlSource: function (query, process) {
            var that = this,
                opt = {
                    params: {
                        furnaceCode: this.model.get('furnaceCode'),
                    },
                };


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


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

                            if (records) {
                                var items = [],
                                    data = [];
                                data = _.map(records, function (obj) {
                                    return {
                                        heatName : obj.HeatName,
                                        start : obj.StartString,
                                        id : obj.Id,
                                        heatId : obj.HeatId,
                                        furnaceCode : obj.FurnaceCode,
                                    }

                                });

                                _.each(data, function (obj) {
                                    //var legend = obj.heatName;
                                    var legend = obj.heatName + '  -  ' + new moment(obj.start, 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM-DD');

                                    that.searchItems[legend] = obj;

                                    items.push(legend);
                                });
                            }

                            process(items);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                }
            ));
        },
        refreshProcess: function (options) {
            var that = this,
                attrs = this.model.toJSON(),
                opt = _.extend({}, { params: {}, }, options);
           

            if ((opt.refresh == true) || (opt.reset == true))
                this.model.set('isLoadingProcess', true);

            this.process.fetch(_.extend({}, opt, {
                params: {
                    id: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                    //Fetch summarized data to get yield info.
                    summarizedData: true,
                },
                success: function (model, records) {
                    setTimeout(
                        function () {
                            that.model.set({
                                isLoadingProcess: false,
                                navigating: false,
                            });
                        },
                        1000
                    );
                },
                error: function () {
                    setTimeout(
                        function () {
                            that.model.set({
                                isLoadingProcess: false,
                                navigating: false,
                            });
                        },
                        1000
                    );
                },
            }));

            this.additions.fetch(_.extend(opt, {
                refresh: true,
                params: {
                    processId: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                },
            }));
            this.buckets.fetch(_.extend(opt, {
                refresh: true,
                params: {
                    processId: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                },
            }));
            this.consumptions.fetch(_.extend(opt, {
                refresh: true,
                params: {
                    processId: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                },
            }));
            this.phases.fetch(_.extend(opt, {
                refresh: true,
                params: {
                    processId: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                },
            }));
            this.temperatures.fetch(_.extend(opt, {
                refresh: true,
                params: {
                    processId: attrs.processId,
                    furnaceCode: attrs.furnaceCode,
                    heatId: attrs.heatId,
                },
            }));
        },
        selectItemFromSearchComboItem: function (value) {
            var item = this.searchItems[value];

            if (item)
                this.model.set('processId', item.id);

            return item;
        },

        changeElectrodeBtn_click: function (e) {
            try {
                var that = this,
                    processAttrs = this.process.toJSON(),
                    phaseCode = $(e.currentTarget).data('phaseCode'),
                    electrodeRef;

                switch (phaseCode) {
                    case 'A':
                        electrodeRef = '1';
                        break;
                    case 'B':
                        electrodeRef = '2';
                        break;
                    case 'C':
                        electrodeRef = '3';
                        break;
                    default:
                        break;
                }
                

                var modal = new Screen.Views.ElectrodeChangeModal({
                    model: new Screen.Models.ElectrodeChangeModal({
                        currentElectrodeHeatsCount: processAttrs['electrode' + electrodeRef + 'HeatsCount'],
                        currentElectrodeSupplier: processAttrs['electrode' + electrodeRef + 'Supplier'],
                        currentElectrodeWeight: processAttrs['electrode' + electrodeRef + 'Weight'],
                        electrodeChangeId: processAttrs['electrode' + electrodeRef + 'ChangeId'],
                        electrodeChangeReasons: this.model.get('electrodeChangeReasons'),
                        heatName: processAttrs.heatName,
                        phaseCode: phaseCode,
                        processId: processAttrs.id,
                    }),
                    template: Handlebars.compile(this.$el.find('#electrode_change_modal_template').html()),
                });


                this.listenToOnce(modal, 'finish', function (modal, data) {
                    if (data.result == 'SUCCESS') {
                        var params = that.model.toJSON();

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

                modal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        collection_backgrid_action: function (model, action) {
            try {
                var that = this;

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

                        this.listenToOnce(modal, "continue", function (modal) {
                            try {
                                model.remove({
                                    success: function (model, resp, opt) {
                                        try {
                                            model.collection.remove(model);

                                            that.process.setRawManualVariables(resp.Table);
                                        }
                                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    },
                                    error: function (model, errorMsg) {
                                        try {
                                            app.views.topMessages.showMessage(app.translate([that, app], errorMsg), { stay: 10000, });
                                        }
                                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                    }
                                });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });

                        modal.show();
                        break;
                    case 'SAVE':
                        var attrs = model.toJSON(),
                            params = {
                                processId: that.process.get('id'),
                            };


                        _.each(model.editableAttrs, function (attr) { params[attr] = attrs[attr]; });


                        model.create({
                            params: params,
                            success: function (model, resp, opt) {
                                try {
                                    model.set('isNew', false, { from: 'save' });

                                    that.process.setRawManualVariables(resp.Table1);
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            },
                            error: function (model, errorMsg) {
                                try {
                                    app.views.topMessages.showMessage(app.translate([that, app], errorMsg), { stay: 10000, });
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            }
                        });
                        break;
                    case 'DISCARD':
                        model.collection.remove(model);
                        break;
                    case 'GOTO':
                        try {
                            app.router.navigate(
                                app.router.resolveURL(
                                    'scrap-usage',
                                    {
                                        start: new moment(model.get('timestamp'), 'YYYY-MM-DD HH:mm:ss').format('YYYYMMDDHHmmss'),
                                        end: new moment(model.get('timestamp'), 'YYYY-MM-DD HH:mm:ss').format('YYYYMMDDHHmmss')
                                    },
                                    false
                                ),
                                { trigger: true, }
                            );
                        }
                        catch (Error) { console.error(Error.stack); }
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        collection_change: function (model, value, opt) {
            try {
                var that = this;

                if (arguments.length < 3) opt = value;

                if ((opt.from != 'fetch') && (opt.from != 'save') && (!model.get('isNew'))) {
                    model.update({
                        params: model.changed,
                        success: function (model, resp) {
                            try {
                                that.process.setRawManualVariables(resp.Table1);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        error: function (model, errorMsg) {
                            try {
                                app.views.topMessages.showMessage(app.translate([that, app], errorMsg), { stay: 10000, });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                    });
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        consumptions_fetch: function (coll, resp, opt) {
            try {
                var that = this,
                    cons = [];
                
                this.consumptions.each(function (model) {
                    if (that.consumptionCodesCommon.indexOf(model.get('code')) != -1)
                        cons.push(model);
                });

                this.consumptionsCommon.set(cons);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        delaysAnchorLink_click: function (e) {
            try {
                this.$el.find('.delays-anchor-target').scrollIntoView(false);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        delaysManagerView_model_delaySplits_addChangeRemoveReset: function (coll, resp, opt) {
            try {
                this.model.set(
                    'delaysNotDeclaredCount',
                    this.delaysManagerView.model.get('delaySplits').where({ code: 'NOTDECLARED', }).length
                );
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        getNextItemBtn_click: function (e) {
            try {
                this.getNextProcess(true);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        getPreviousItemBtn_click: function (e) {
            try {
                this.getNextProcess(false);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        processInfoFieldValueTbx_keypress: function (e) {
            try {
                var keyCode = e.which || e.keyCode;

                //if (keyCode == 13) {
                //    var controls = $('input.process-info-field-value');

                //    var nextControl = controls.eq(controls.index(e.target) + 1);

                //    if (nextControl)
                //        nextControl.focus();
                //}
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        manualLockBtn_click: function (e) {
            try {
                var that = this;

                this.process.removeManualVariable({
                    params: {
                        variableName: $(e.target).data('variable-name'),
                    },
                    error: function (model, msg) {
                        try {
                            app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 10000, });
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                })
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        model_change_pickers: function (model, value, opt) {
            try {
                var params = this.model.toJSON();

                if (params.mainView == true) {
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {}
                            ),
                            false
                        ),
                        { trigger: false, }
                    );
                }

                this._refresh({
                    reset: true,
                    params: _.extend(
                        {},
                        params,
                        {}
                    ),
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        process_change: function (model, value, opt) {
            try {
                var that = this;
                
                if (arguments.length < 3) opt = value;
                if (opt.from != 'fetch') {
                    model.update({
                        params: model.changed,
                        error: function (model, errorMsg) {
                            try {
                                app.views.topMessages.showMessage(app.translate([that, app], errorMsg), { stay: 10000, });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        }
                    });
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        process_change_heatName: function (model, value, opt) {
            try {
                this.model.set('search', this.process.get('heatName'));
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        process_fetch: function (model, resp, opt) {
            try {
                var attrs = this.process.toJSON();


                if (this.displayChemistry == true) {
                    this.chemistrySamplesView.model.set(
                        {
                            heatId: attrs.heatId,
                        },
                        { silent: true, }
                    );
                    this.chemistrySamplesView._refresh({
                        refresh: true,
                    });
                }


                this.delaysManagerView.options.MYREFERENCES.subviews.subnavbarControls.model.set(
                    {
                        from: (attrs.start) ? attrs.start.substring(0, 23) : attrs.start,
                        to: (attrs.end) ? attrs.end.substring(0, 23) : attrs.end,
                        lineProductionItemId: attrs.furnaceCode,
                    },
                    { silent: true, }
                );

                this.delaysManagerView.refresh({ refresh: true, });


                this.slagChemistrySamplesView.model.set(
                    {
                        heatId: attrs.heatId,
                    },
                    { silent: true, }
                );
                this.slagChemistrySamplesView._refresh({
                    refresh: true,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        searchTbx_keypress: function (e) {
            try {
                var keyCode = e.which || e.keyCode;

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

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

                        if (!item) {
                            item = _.findWhere(this.searchItems, { heatName: search, });

                            if (item)
                                this.model.set('processId', item.id);
                            else
                                app.views.topMessages.showMessage(app.translate([this, app], 'no_match'), { stay: 5 * 1000, });
                        }
                    }
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        shipBtn_click: function (e) {
            try {
                var that = this;

                var modal = new Modal.Views.Main({
                    focusOk: false,
                    focusSelector: '#btn-cancel',
                    title: app.translate([this, app], "ship_modal_confirm_title"),
                    message: app.translate([this, app], "ship_modal_confirm_message"),
                    buttons_type: "CONTINUE-CANCEL",
                });

                this.listenToOnce(modal, "continue", function (modal) {
                    try {
                        that.process.ship({
                            success: function (model, resp, opt) {
                                try {
                                    app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'), { stay: 10000, });
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            },
                            error: function (model, errorMsg) {
                                try {
                                    app.views.topMessages.showMessage(app.translate([that, app], errorMsg), { stay: 10000, });
                                }
                                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            }
                        });
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                });

                modal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        showSearchItemsBtn_click: function (e) {
            try {
                if ((this.searchItems) && (this.searchItems.length > 0))
                    this.searchTbx.typeaheadExtended('show');
                else
                    this.searchTbx.typeaheadExtended('lookup');
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },

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

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

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

                this.options.onappend(this);
            }

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

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

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

            this.stopAutoRefresh();

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

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

            this.hideSubviews();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        hideSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.hide();
            });
        },
        preRender: function () {
            app.models.subnavbar.set("subnavbar", false);
        },
        reRender: function (viewParams) {
            try {
                this.refresh(viewParams);
            } catch (Error) { }
        },
        startAutoRefresh: function () {
            try {
                if (this.autoRefresh.enabled !== true) {
                    var that = this;

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

                    this.autoRefresh.enabled = true;

                    //use a timeout to execute the first refresh to return the handle to the start function caller.
                    //So when the caller finish it will do the first refresh.
                    this.autoRefresh.toid = setTimeout(
                        function () { that._refresh(); },
                        1
                    );
                }
            } catch (error) { console.error((error.stack) ? 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;
        },
    });

    Screen.Models.Process = EafProcess.Models.EafProcess.extend({
        defaults: _.extend(
            {},
            EafProcess.Models.EafProcess.prototype.defaults,
            {
                yield: null,
            }
        ),
        
        computeds: {
            endTapDate: {
                deps: ['endTap'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM-DD') : value;
                },
                set: function (value) {
                    var dateObj = new moment(value, app.translate(app, 'MM/DD/YYYY'));

                    if (dateObj.isValid()) {
                        var time = this.get('endTapTime');

                        return {
                            endTap: dateObj.format('YYYY-MM-DD')
                                    + ' ' + ((time) ? time : '00:00:00'),
                        };
                    }

                    return { endTap: null, };
                },
            },
            endTapTime: {
                deps: ['endTap'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('HH:mm:ss') : value;
                },
                set: function (value) {
                    if (('' + value).indexOf(':') != -1) {
                        if (value) {
                            var date = this.get('endTapDate');

                            return {
                                endTap: ((date) ? date : new moment().format('YYYY-MM-DD'))
                                        + ' ' + value,
                            };
                        }

                        return { endTap: null, };
                    }
                },
            },
            powerOn$: {
                deps: ['powerOn'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    var result;

                    value = '' + value;

                    if (value) {
                        if (value.indexOf(':') != -1) {
                            var split = value.split(':');

                            result = parseInt(split[0], 10) * 60 + parseInt(split[1], 10);
                        }
                        else {
                            result = parseInt(value, 10) * 60;
                        }
                    }
                    else {
                        result = 0;
                    }

                    return { powerOn: result, };
                },
            },
            startDate: {
                deps: ['start'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM-DD') : value;
                },
                set: function (value) {
                    var dateObj = new moment(value, app.translate(app, 'MM/DD/YYYY'));

                    if (dateObj.isValid()) {
                        var time = this.get('startTime');

                        return {
                            start: dateObj.format('YYYY-MM-DD')
                                    + ' ' + ((time) ? time : '00:00:00'),
                        };
                    }

                    return { start: null, };
                },
            },
            startTime: {
                deps: ['start'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('HH:mm:ss') : value;
                },
                set: function (value) {
                    if (('' + value).indexOf(':') != -1) {
                        if (value) {
                            var date = this.get('startDate');

                            return {
                                start: ((date) ? date : new moment().format('YYYY-MM-DD'))
                                        + ' ' + value,
                            };
                        }

                        return { start: null, };
                    }
                },
            },
            startTapDate: {
                deps: ['startTap'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM-DD') : value;
                },
                set: function (value) {
                    var dateObj = new moment(value, app.translate(app, 'MM/DD/YYYY'));

                    if (dateObj.isValid()) {
                        var time = this.get('startTapTime');

                        return {
                            startTap: dateObj.format('YYYY-MM-DD')
                                    + ' ' + ((time) ? time : '00:00:00'),
                        };
                    }

                    return { startTap: null, };
                },
            },
            startTapTime: {
                deps: ['startTap'],
                get: function (value) {
                    return (value) ? new moment(value, 'YYYY-MM-DD HH:mm:ss.SSS').format('HH:mm:ss') : value;
                },
                set: function (value) {
                    if (('' + value).indexOf(':') != -1) {
                        if (value) {
                            var date = this.get('startTapDate');

                            return {
                                startTap: ((date) ? date : new moment().format('YYYY-MM-DD'))
                                        + ' ' + value,
                            };
                        }

                        return { startTap: null, };
                    }
                },
            },
        },

        //Override to get summaized data
        parse: function (obj, objManualVariables, objSummarized) {
            if (!objSummarized) objSummarized = {};

            return _.extend(EafProcess.Models.EafProcess.prototype.parse.apply(this, arguments), {
                yield: objSummarized.Yield,
            });
        },
        parseResponse: function (resp, opt) {
            if ((resp) && (resp.Table)) {
                if (resp.Table.length > 0) {
                    this.set(
                        this.parse(resp.Table[0], resp.Table1, resp.Table2[0]),
                        _.extend({}, opt, { from: 'fetch' })
                    );
                }

                return true;
            }

            return false;
        },
    });

    function MakeCellManualAutomatic(cellView) {
        return cellView.extend({
            className: cellView.prototype.className + ' manual-automatic-cell',
            manualLockBtnTemplate: Handlebars.compile('<i class="fa fa-lock manual-lock-btn"></i>'),
            variableName: null,

            manualLockBtn: null,

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

                this.listenTo(this.process, 'change:manualVariables', this.process_change_manualVariables);
            },
            getVariableName: function () {
                if (_.isFunction(this.variableName) == true)
                    return this.variableName.apply(this);
                else
                    return this.variableName;
            },
            render: function () {
                cellView.prototype.render.apply(this, arguments);

                if (!this.manualLockBtn) {
                    this.manualLockBtn = $(this.manualLockBtnTemplate());

                    if ((Backgrid.callByNeed(this.column.editable(), this.column, this.model)) == true)
                        this.$el.on('click', '.manual-lock-btn', _.bind(this.manualLockBtn_click, this));
                }

                this.update();

                return this;
            },
            update: function () {
                var varName = this.getVariableName();            

                if (_.findWhere(this.process.get('manualVariables'), { name: varName, }))
                    this.manualLockBtn.appendTo(this.$el);
                else
                    this.manualLockBtn.detach();
            },

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

                    this.model.removeManualVariable({
                        params: {
                            variableId: _.findWhere(this.process.get('manualVariables'), { name: this.getVariableName(), }).id,
                        },
                        success: function (model, resp) {
                            try {
                                that.process.setRawManualVariables(resp.Table1);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        error: function (model, msg) {
                            try {
                                app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 10000, });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                    });

                    e.stopPropagation();
                }
                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); };
            },
            process_change_manualVariables: function (model, value, opt) {
                try {
                    this.update();
                }
                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); };
            },
        });
    };

    Screen.Models.ConsumpitonSidewall = Backbone.Epoxy.Model.extend({
        defaults: {
            editingProcess: true,
        },
    });

    Screen.Views.ConsumpitonSidewall = Backbone.Epoxy.View.extend({
        className: 'col',
        events: function () {
            var evts = {};

            if (this.model.get('editingProcess') == true)
                evts['click .manual-lock-btn[data-variable-name]'] = _.bind(this.manualLockBtn_click, this);

            return evts;
        },

        oxygenConsumption: null,
        naturalGasConsumption: null,

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

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

            this.bindingSources = {
                naturalGas: this.naturalGasConsumption,
                oxygen: this.oxygenConsumption,
                process: this.process,
            };

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

        manualLockBtn_click: function (e) {
            try {
                var that = this,
                    target = $(e.target),
                    model;


                switch (target.data('code').replace(/(.+)_[0-9]+/, '$1')) {
                    case 'OXYGEN_BURNER':
                        model = this.oxygenConsumption;
                        break;
                    case 'NATURAL_GAS_BURNER':
                        model = this.naturalGasConsumption;
                        break;
                }


                model.removeManualVariable({
                    params: {
                        variableId: _.findWhere(this.process.get('manualVariables'), { name: target.data('variable-name'), }).id,
                    },
                    success: function (model, resp) {
                        try {
                            that.process.setRawManualVariables(resp.Table1);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    error: function (model, msg) {
                        try {
                            app.views.topMessages.showMessage(app.translate([that.parent, app], msg), { stay: 10000, });
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                })
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
    });

    Screen.Models.CreateHeatModal = Backbone.Epoxy.Model.extend({
        defaults: {
            gradeId: null,
            ladleId: null,
            name: null,
            steelWeight: null,

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

    Screen.Views.CreateHeatModal = Modal.Views.SimpleModal.extend({
        initialize: function (options) {
            _.extend(this, options);

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

            this.bindEvents();

            return this;
        },

        acceptBtn_click: function (e) {
            try {
                this.model.set({
                    errorMsg: '',
                    processing: true,
                });

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


                this.rollset.remove(
                    function (model, id) {
                        try {
                            that.finish({ result: 'SUCCESS', });

                            that.hide();
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    function (model, errorMsg) {
                        try {
                            that.model.set({
                                errorMsg: app.translate([that.parent, app], errorMsg),
                                processing: false,
                            });
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    }
                );
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
    });

    Screen.Models.ElectrodeChangeModal = Backbone.Epoxy.Model.extend({
        defaults: {
            heatName: null,
            phaseCode: null,
            processId: null,
            electrodeChangeId: null,
            electrodeChangeReasons: [],

            currentElectrodeHeatsCount: null,
            currentElectrodeSupplier: null,
            currentElectrodeWeight: null,

            newElectrodeComments: null,
            newElectrodeSize: null,
            newElectrodeSupplier: null,
            //newElectrodeWeight: null,
            newElectrodeChangeReasonId: null,

            processing: false,
        },        
    });

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

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

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

            this.bindEvents();

            return this;
        },
        save: function () {
            try
            {
                var that = this,
                    attrs = this.model.toJSON();

                this.model.set('processing', true);

                var qp = new QueryParameters();
                qp.Add('id', 'VARCHAR', attrs.electrodeChangeId);
                qp.Add('comments', 'VARCHAR', attrs.newElectrodeComments);
                qp.Add('electrodeChangeReasonId', 'VARCHAR', attrs.newElectrodeChangeReasonId);
                qp.Add('size', 'VARCHAR', attrs.newElectrodeSize);
                qp.Add('supplier', 'VARCHAR', attrs.newElectrodeSupplier);

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.ELT.UpdateElectrodeChange',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (resp && !resp.Message) {
                                    that.finish({ result: 'SUCCESS' });
                                    that.hide();
                                }
                                else {
                                    var msg = (resp.Message) ? resp.Message : 'SERVER_RESPONSE_NOT_VALID';

                                    console.error(new Error(msg).stack);
                                    app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 10000, });
                                }
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            finally {
                                that.model.set('processing', false);
                            }
                        },
                        onError: function (msg) {
                            try {
                                console.error(new Error(msg).stack);

                                //Override msg variable to display a human message.
                                msg = 'SERVER_RESPONSE_NOT_VALID';

                                app.views.topMessages.showMessage(app.translate([that, app], msg), { stay: 10000, });
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                            finally {
                                that.model.set('processing', false);
                            }
                        },
                        Async: true,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );
            }
            catch (error) {
                this.model.set('processing', false);

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

        acceptBtn_click: function (e) {
            try {
                this.save();
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
    });

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