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

  'modules/chemistry-sample',
  'modules/chemistry-sample-id',
  'modules/chemistry-sample-type',
  'modules/eaf-process/eaf-process',

  'js/backgrid-0.3.5/extensions/add-row-cell/backgrid-add-row-cell',
  'js/backgrid-0.3.5/extensions/button-cell/backgrid-button-cell',
  'js/backgrid-0.3.5/extensions/valid-min-max-cell/backgrid-valid-min-max-cell',
  'backgrid/calendar-cell',
  'backgrid/moment-cell',
  //'js/jquery.clearsearch/jquery.clearsearch',
  'js/jquery.mask',
  '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, ChemistrySample, ChemistrySampleId, ChemistrySampleType, EafProcess) {

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

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

            editionEnabled: true,
            heatId: -1, //To get current eafProcess.
            navigating: false,
            search: '',

            sampleTypes: [],

            hasData: false,
            isLoading: false,
            hasDataProcess: false,
            isLoadingProcess: false,
        },
        fetchHeats: 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: {
                get: function () {
                    return true;
                },
            },
        },
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'chemistry-samples',
        id: 'chemistry-samples',
        title: 'Chemistries',
        events: function () {
            return {
                'click #getPreviousItemBtn': this.getPreviousItemBtn_click,
                'click #getNextItemBtn': this.getNextItemBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,
        viewParams: null,

        eafProcess: null,
        items: null,
        searchTbx: null,
        searchItems: 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();

            this.eafProcess = new EafProcess.Models.EafProcess();

            this.items = new (ChemistrySample.Collections.ChemistrySamples.extend({
                model: ChemistrySample.Collections.ChemistrySamples.prototype.model.extend({
                    editableAttrs: ['comments', 'sampleIdCode', 'typeCode', 'timestamp', ].concat(app.chemistryElements),
                }),
                //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 = {
                eafProcess: this.eafProcess,
            };


            ChemistrySampleId.Collections.ChemistrySampleIds.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('sampleIds', _.map(records, function (obj) {
                            return {
                                value: obj.code,
                                label: obj.code,

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

            ChemistrySampleType.Collections.ChemistrySampleTypes.fetch({
                async: false,
                success: function (records) {
                    try {
                        that.model.set('sampleTypes', _.map(records, function (obj) { return { value: obj.code, label: obj.code, }; }));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                },
            });


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


            this.bindEvents();
        },
        bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.eafProcess, 'change:heatName', this.eafProcess_change_heatName)
                .listenTo(this.items, 'backgrid:action', this.collection_backgrid_action)
                .listenTo(this.items, 'change', this.collection_change)
                .listenTo(this.model, 'change:heatId', this.model_change_pickers);
        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }

            this.refreshHeat(opt);

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

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (fixedParams) {
            if (fixedParams.heatId)
                fixedParams.heatId = parseInt(fixedParams.heatId, 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(modelAttrs));

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


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

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [].concat(
                                    [{
                                        name: 'typeCode',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'samples_type_col'),
                                        cell: Backgrid.SelectCell.extend({
                                            className: 'select-cell align-center-cell typeCode',
                                            optionValues: _.map(that.model.get('sampleTypes'), function (obj) { return [obj.label, obj.value, ]; }),
                                        }),
                                    },
                                    {
                                        name: 'sampleIdCode',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'samples_order_col'),
                                        cell: Backgrid.SelectCell.extend({
                                            className: 'select-cell align-center-cell order',
                                            optionValues: function () {
                                                var typeCode = this.model.get('typeCode');

                                                if (typeCode) {
                                                    return _.map(
                                                        _.where(that.model.get('sampleIds'), { chemistrySampleTypeCode: typeCode, }),
                                                        function (obj) { return [obj.label, obj.value, ]; }
                                                    );
                                                }
                                                else {
                                                    return _.map(that.model.get('sampleIds'), function (obj) { return [obj.label, obj.value, ]; });
                                                }
                                            },
                                        }),
                                    },
                                    {
                                        name: 'gradeName',
                                        editable: false,
                                        label: app.translate([that, app], 'samples_grade_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell gradeName',
                                        }),
                                    },
                                    {
                                        name: 'timestamp',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'samples_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;',
                                            }
                                        }),
                                    },],                                
                                    _.map(app.chemistryElements, function (obj) {
                                        return {
                                            name: obj,
                                            editable: fn_gridCheckEditionEnable,
                                            label: app.translate([that, app], obj),
                                            cell: Backgrid.Extension.MakeCellValidMinMax(Backgrid.NumberCell).extend({
                                                className: 'number-cell valid-min-max-cell element-' + obj,
                                                decimals: 4,
                                                minProp: 'min' + obj,
                                                maxProp: 'max' + obj,
                                                invalidMinMessage: function (value, limit, includeLimit) {
                                                    return app.translate([that, app], 'samples_element_min_reached_legend', [limit.toFixed(4)]);
                                                },
                                                invalidMaxMessage: function (value, limit, includeLimit) {
                                                    return app.translate([that, app], 'samples_element_max_reached_legend', [limit.toFixed(4)]);
                                                },
                                            }),
                                            headerCell: Backgrid.HeaderCell.extend({
                                                className: 'element-' + obj,
                                            }),
                                        };
                                    }),
                                    _.map(app.chemistryCalculatedElements, function (obj) {
                                        return {
                                            name: obj,
                                            editable: false,
                                            label: app.translate([that, app], obj),
                                            cell: Backgrid.NumberCell.extend({
                                                className: 'number-cell element-' + obj,
                                                decimals: 4,
                                            }),
                                            headerCell: Backgrid.HeaderCell.extend({
                                                className: 'element-' + obj,
                                            }),
                                        };
                                    }),
                                    {
                                        name: 'comments',
                                        editable: fn_gridCheckEditionEnable,
                                        label: app.translate([that, app], 'samples_comments_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-left-cell comments',
                                            attributes: function () {
                                                return {
                                                    title: this.model.get(this.options.column.get('name')),
                                                };
                                            },
                                        }),
                                    },
                                    ((modelAttrs.editionEnabled == 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.items,
                            });
                            that.$el.find('.samples-grid-container').append(grid.render().el);


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


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

                            if (fixedParams.heatId)
                                fixedParams.heatId = parseInt(fixedParams.heatId, 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.eafProcess.getNextProcess({
                params: {
                    next: next,
                },
                success: function (model, nextProcess) {
                    try {
                        if ((nextProcess) && (nextProcess.heatId)) {
                            that.model.set({
                                heatId: nextProcess.heatId,
                                navigating: false,
                            });
                        }
                        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) ? error.stack : new 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.fetchHeats(_.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); }
                    },
                }
            ));
        },
        refreshHeat: function (options) {
            var that = this,
                attrs = this.model.toJSON(),
                opt = _.extend({}, { params: {}, }, options);

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

            this.eafProcess.fetch(_.extend(opt, {
                params: {
                    id: (attrs.heatId != -1) ? null : -1,
                    heatId: (attrs.heatId != -1) ? attrs.heatId : null,
                    timezoneCode: app.models.user.get('timezoneCode'),
                },
                //success: function () {
                //    that.model.set({
                //        isLoadingProcess: false,
                //        navigating: false,
                //    });
                //},
                //error: function () {
                //    that.model.set({
                //        isLoadingProcess: false,
                //        navigating: false,
                //    });
                //},
            }));

            this.items.fetch(_.extend(opt, {
                params: {
                    heatId: attrs.heatId,
                    timezoneCode: app.models.user.get('timezoneCode'),
                    heatName: attrs.heatName, 
                },
                success: function () {
                    that.model.set({
                        isLoadingProcess: false,
                        navigating: false,
                    });
                },
                error: function () {
                    that.model.set({
                        isLoadingProcess: false,
                        navigating: false,
                    });
                },
            }));
        },
        selectItemFromSearchComboItem: function (value) {
            var item = this.searchItems[value];

            if (item)
                this.model.set('heatId', item.heatId);

            return item;
        },

        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.eafProcess.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 = {
                                heatId: that.eafProcess.get('heatId'),
                                timezoneCode: app.models.user.get('timezoneCode'),
                            };


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

                        ////Elements data xml parameter
                        //params.elements = app.jsonArrayToXml(attrs, app.chemistryElements);


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

                                    //that.eafProcess.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 'MOVE':
                        var modal = new Screen.Views.HeatEditModal({
                            model: new Screen.Models.HeatEditModal({
                                sampleId: model.get('id'),
                            }),
                            template: Handlebars.compile(that.$el.find('#heat_edit_modal_template').html()),
                            //that.templates.addExistingModal = 
                        });


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

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

                        modal.show();
                        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: _.extend(
                            {
                                timezoneCode: app.models.user.get('timezoneCode'),
                            },
                            model.changed
                        ),
                        //success: function (model, resp) {
                        //    try {
                        //        that.eafProcess.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); }
        },
        eafProcess_change_heatName: function (model, value, opt) {
            try {
                this.model.set('search', this.eafProcess.get('heatName'));
            }
            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); }
        },
        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_heatName: function (model, value, opt) {
        //    try {
        //        this.model.set('search', this.eafProcess.get('heatName'));
        //    }
        //    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('heatId', item.heatId);
                            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); }
        },
        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.HeatEditModal = Backbone.Epoxy.Model.extend({
        defaults: {
            processing: false,
            heatId: -1,
            navigating: false,
            search: '',
            sampleId: null,
        }
    });

    Screen.Views.HeatEditModal = Modal.Views.SimpleModal.extend({
        className: Modal.Views.SimpleModal.prototype.className + ' heat-edit-modal',

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

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

            this.eafProcess = new EafProcess.Models.EafProcess();

            this.bindingSources = {
                eafProcess: this.eafProcess,
            };

            this.bindEvents();

            return this;
        },
        bindEvents: function () {
            Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);

            //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.eafProcess, 'change:heatName', this.eafProcess_change_heatName)
                //.listenTo(this.items, 'backgrid:action', this.collection_backgrid_action)
                //.listenTo(this.items, 'change', this.collection_change)
                .listenTo(this.model, 'change:heatId', this.model_change_pickers);
        },
        refreshHeat: function (options) {
            var that = this,
                attrs = this.model.toJSON(),
                opt = _.extend({}, { params: {}, }, options);

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

            this.eafProcess.fetch(_.extend(opt, {
                params: {
                    id: (attrs.heatId != -1) ? null : -1,
                    heatId: (attrs.heatId != -1) ? attrs.heatId : null,
                    timezoneCode: app.models.user.get('timezoneCode'),
                },
                //success: function () {
                //    that.model.set({
                //        isLoadingProcess: false,
                //        navigating: false,
                //    });
                //},
                //error: function () {
                //    that.model.set({
                //        isLoadingProcess: false,
                //        navigating: false,
                //    });
                //},
            }));
        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            //if (this.autoRefresh.toid != null) {
            //    clearTimeout(this.autoRefresh.toid);
            //    this.autoRefresh.toid = null;
            //}

            this.refreshHeat(opt);

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

            //    this.autoRefresh.toid = setTimeout(
            //        function () { that._refresh(); },
            //        this.autoRefresh.every
            //    );
            //}
        },
        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); }
        },
        eafProcess_change_heatName: function (model, value, opt) {
            try {
                this.model.set('search', this.eafProcess.get('heatName'));
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        save: function () {
            var qp = new QueryParameters();
            qp.Add('sampleId', 'INT', this.model.get('sampleId'));
            qp.Add('newHeatId', 'INT', this.eafProcess.get('heatId'));

            var that = this;
            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAB.ChangeHeatOfSampleChemistry',
                qp,
                {
                    onSuccess: function (resp) {
                        console.log("SP Called");
                        console.log(resp);
                        if (resp && !resp.Message) {
                            that.finish({ result: 'SUCCESS' });
                            that.hide();
                        }
                        else
                            alert("SERVER ERROR");
                    },
                    onError: function (resp, err) {
                        console.error("Calling SP failed");
                        console.log(resp);
                        alert("CAN'T REACH SERVER");
                    },
                    Async: true,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );
        },

        acceptBtn_click: function (e) {
            try {
                this.save();
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
        events: function () {
            return {
                'click #getPreviousItemBtn': this.getPreviousItemBtn_click,
                'click #getNextItemBtn': this.getNextItemBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
                'click #acceptBtn': this.acceptBtn_click,
            };
        },
        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('heatId', item.heatId);
                            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); }
        },
        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); }
        },
        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); }
        },
        getNextProcess: function (next) {
            var that = this;

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


            this.eafProcess.getNextProcess({
                params: {
                    next: next,
                },
                success: function (model, nextProcess) {
                    try {
                        if ((nextProcess) && (nextProcess.heatId)) {
                            that.model.set({
                                heatId: nextProcess.heatId,
                                navigating: false,
                            });
                        }
                        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) ? error.stack : new Error(error).stack);

                        that.model.set('navigating', false);
                    }
                },
                error: function () {
                    that.model.set('navigating', false);
                },
            });
        },
        eafProcess: null,
        selectItemFromSearchComboItem: function (value) {
            var item = this.searchItems[value];

            if (item)
                this.model.set('heatId', item.heatId);

            return item;
        },
        searchItems: null,
        getSearchControlSource: function (query, process) {
            var that = this,
                opt = {
                    params: {
                        //furnaceCode: this.model.get('furnaceCode'),
                    },
                };


            if (query)
                opt.params.search = query;
            EafProcess.Collections.EafProcesses.fetch(_.extend(
                opt,
                {
                    success: function (records) {
                        try {
                            that.searchItems = {};

                            if (records) {
                                var items = [];

                                _.each(records, 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); }
                    },
                }
            ));
        },
        render: function (container, viewParams) {
            var that = this,
                modelAttrs = this.model.toJSON();

            this.viewParams = viewParams;

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

            //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/chemistry-samples/';
            //var customPath = '/app/custom-screens/' + this.template + '/';
            //template: Handlebars.compile(that.$el.find('#heat_edit_modal_template').html()),
            //template: Handlebars.compile($('#heat_edit_modal_template').html()),



            //T.render.call(
            //    this,
            //    'chemistry-samples',
            //    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(modelAttrs));

                            //that.applyBindings();

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


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

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

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

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

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