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

  'custom-screens/chemistry-samples/chemistry-samples',
  'custom-screens/eaf-process/eaf-process',
  'custom-screens/lf-process/lf-process',
  'modules/eaf-process/eaf-process',
  'modules/lf-process',
  'modules/user-property/user-property',

  'js/backgrid-0.3.5/extensions/valid-min-max-cell/backgrid-valid-min-max-cell',
  'js/jquery.scrollIntoView/jquery.scrollIntoView',
],
function (app, T, ChemistrySamplesView, EafProcessView, LfProcessView, EafProcess, LfProcess, UserProperty) {

    //Get current user Eaf furnace code property to use it to filter processes navigation and enable/disable edition button.
    var eafFurnaceProp = UserProperty.Collections.CurrentUserProperties.findWhere({ code: 'EAF_FURNACE', });
    //Get current user Lf furnace code property to use it to enable/disable edition button.
    var lfLadleFurnaceProp = UserProperty.Collections.CurrentUserProperties.findWhere({ code: 'LF_LADLE_FURNACE', });

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            editingProcess: false,
            eafFurnaceCode: (eafFurnaceProp) ? parseInt(eafFurnaceProp.get('value'), 10) : null,
            heatId: -1, //To get current eafProcess.
            lfLadleFurnaceCode: (lfLadleFurnaceProp) ? parseInt(lfLadleFurnaceProp.get('value'), 10) : null,
            navigating: false,
            search: '',
            hasData: false,
            isLoading: false,
            isLoadingLfProcesses: 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: {
        //},
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'heat',
        id: 'heat',
        className: 'heat-screen',
        title: 'Heat Report',
        events: function () {
            return {
                'click .anchor-link': this.anchorLink_click,
                'click #chemistryEditBtn': this.chemistryEditBtn_click,
                'click #eafEditBtn': this.eafEditBtn_click,
                'click #getPreviousItemBtn': this.getPreviousItemBtn_click,
                'click #getNextItemBtn': this.getNextItemBtn_click,
                'click #lfEditBtn': this.lfEditBtn_click,
                'keypress #searchTbx': this.searchTbx_keypress,
                'click #showSearchItemsBtn': this.showSearchItemsBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,

        eafProcess: null,
        eafProcessView: null,
        chemistrySamplesView: null,
        lfProcessesColl: null,
        lfProcessesCollFixed: null,
        lfProcessViews: [],
        subviews: null,
        viewParams: null,
        searchTbx: null,
        searchItems: null,

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

            var that = this;

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

            this.eafProcess = new EafProcessView.Models.Process();
            this.lfProcessesColl = new (LfProcess.Collections.LfProcesses.extend({
                model: LfProcessView.Models.Process,
                comparator: 'treatment',
            }))();
            this.lfProcessesCollFixed = new (LfProcess.Collections.LfProcesses.extend({
                model: LfProcessView.Models.Process,
                comparator: 'treatment',
            }))();

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


            this.subviews = {};
            this.autoRefresh = {
                enabled: false
                , toid: null
                , every: 60 * 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.model, 'change:heatId', this.model_change_pickers)
               this.listenTo(this.eafProcess, 'change:heatName', this.eafProcess_change_heatName)
                //.listenTo(this.lfProcessesColl, 'fetch', this.lfProcessesColl_fetch)
                //.listenTo(this.lfProcessesColl, 'reset', this.lfProcessesColl_reset);
        },
        _refresh: function (opt) {
            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;

            this.viewParams = viewParams;

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

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

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

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

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

                            that.lfProcessView = Screen.Views.LfProcess.extend({
                                parent: that,
                                template: Handlebars.compile(that.$el.find('#lf_process_template').html()),
                                ladleFurnaceCode: that.model.get('lfLadleFurnaceCode'),
                            });

                            that.lfProcessAnchorLinkView = Screen.Views.LfProcessAnchor.extend({
                                parent: that,
                                template: Handlebars.compile(that.$el.find('#lf_process_anchor_link_template').html()),
                            });

                            that.applyBindings();

                            Core.Include({
                                Widgets: ['IndustrialChart'],
                                Events: {
                                    onLoad: function () {
                                        //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: 3,
                                            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;
                                                }
                                            }
                                        });

                                        that.subviews.eafProcessView =
                                        that.eafProcessView = new EafProcessView.Views.Main({
                                            model: new EafProcessView.Models.Main({
                                                editingProcess: false,
                                                heatId: that.model.get('heatId'),
                                                mainView: false,
                                                processId: null,
                                                furnaceCode: null,
                                            }),
                                            parent: this,
                                            container: that.$el.find("#eafProcessInfoContainer"),
                                            viewParams: viewParams,
                                            displayChemistry: false,
                                            furnaceCode: this.furnaceCode,
                                            process: that.eafProcess,
                                        });
                                        that.eafProcessView.preRender(viewParams);
                                        that.eafProcessView.render(null, viewParams);

                                        that.eafChart = new IndustrialChart(
                                            that.$el.find('#eafChartContainer')[0],
                                            {
                                                View: { 
                                                    Title: app.translate([that, app], 'process_chart_title'),
                                                    Header: false,
                                                    DisplayScales: {
                                                        value: false,
                                                    },
                                                    Resize: true, 
                                                    Configuration: { 
                                                        CursorValue: true,
                                                    },
                                                },
                                                DatabaseParameters: {
                                                    ConnectionStringName: app.ConnectionStrings.app,
                                                    Procedure: app.DatabaseNames.MES + '.EAF.GetProcessChartData',
                                                    Secured: true,
                                                },
                                            }
                                        );



                                        that.lfChart = new IndustrialChart(
                                            that.$el.find('#lfChartContainer')[0],
                                            {
                                                View: {
                                                    //Title: app.translate([that, app], 'process_chart_title'),
                                                    Header: false,
                                                    DisplayScales: {
                                                        value: false,
                                                    },
                                                    Resize: true,
                                                    Configuration: {
                                                        CursorValue: true,
                                                    },
                                                },
                                                DatabaseParameters: {
                                                    ConnectionStringName: app.ConnectionStrings.app,
                                                    Procedure: app.DatabaseNames.MES + '.LF.GetProcessChartData',
                                                    Secured: true,
                                                },
                                            }
                                        );


                                        that.subviews.chemistrySamplesView =
                                        that.chemistrySamplesView = new ChemistrySamplesView.Views.Main({
                                            model: new ChemistrySamplesView.Models.Main({
                                                editionEnabled: false,
                                                heatId: that.model.get('heatId'),
                                                mainView: false,
                                            }),
                                            parent: this,
                                            container: that.$el.find("#chemistriesSamplesInfoContainer"),
                                            viewParams: viewParams,

                                            eafProcess: that.eafProcess,
                                        });
                                        that.chemistrySamplesView.preRender(viewParams);
                                        that.chemistrySamplesView.render(null, 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.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,
                                                {}
                                            ),
                                        });

                                        that.startAutoRefresh();
                                    },
                                },
                                ExternalWidgets: [],
                            });                            
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },

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

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

            try {
                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);
                    },
                });
            }
            catch (error) {
                this.model.set('navigating', false);

                throw new Error(error);
            }
        },
        getSearchControlSource: function (query, process) {

            
            var that = this,
                opt = { params: { }, };


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


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

                            if (records) {
                                var items = [];

                                _.each(records, function (obj) {
                                    var legend = obj.HeatName;
                                        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 ((opt.refresh == true) || (opt.reset == true)) {
                $('html, body').animate({ scrollTop: '0px', }, 'fast');

                this.model.set({
                    //isLoadingProcess: true,
                    isLoadingLfProcesses: true,
                });
            }

            var heatId = (attrs.heatId != -1) ? attrs.heatId : null,
                processId = (attrs.heatId != -1) ? null : -1;

            var qp = new QueryParameters();
            qp.Add('heatId', 'INT', heatId);
            qp.Add('id', 'INT', processId);


            if (opt.refresh == true) {
                this.eafChart.Clear();
                this.lfChart.Clear();
            }

            this.eafChart.RefreshData(qp);
            
            this.eafProcessView.model.set(
                {
                    heatId: heatId,
                    processId: processId,
                },
                { silent: true, }
            );
            this.eafProcessView._refresh();


            //If it is fetching a specific heat, fetch not eaf data now. 
            //Else, if it is fetching data of current heat, wait to get the heat id of eaf area to then fetch
            //the data of other areas.
            var fn_refreshNotEafAreas = function (heatId) {
                var qpLf = new QueryParameters();
                qpLf.Add('heatId', 'INT', heatId);

                that.lfChart.RefreshData(qpLf);

                that.lfProcessesColl.fetch(_.extend(opt, {
                    reset: true, //Specify a reset opt because current data should be merged with new one always.
                    params: {
                        heatId: heatId,
                    },
                    success: function (resp) {
                        try {
                            that.model.set('isLoadingLfProcesses', false);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    error: function (resp) {
                        try {
                            that.model.set('isLoadingLfProcesses', false);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                }));


                that.chemistrySamplesView.model.set(
                    {
                        heatId: heatId,
                    },
                    { silent: true, }
                );
                that.chemistrySamplesView._refresh({
                    refresh: true,
                });
            }

            if (heatId != null) {
                fn_refreshNotEafAreas(heatId);
            }
            else {
                this.listenToOnce(this.eafProcess, 'fetch', function (model, resp, opt) {
                    try {
                        fn_refreshNotEafAreas(that.eafProcess.get('heatId'));
                    }
                    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                });
            }
        },
        selectItemFromSearchComboItem: function (value) {
            var item = this.searchItems[value];

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

            return item;
        },

        chemistryEditBtn_click: function (e) {
            try {
                app.router.navigate(
                    app.router.resolveURL(
                        'chemistry-samples',
                        {
                            heatId: this.eafProcess.get('heatId'),
                        },
                        false
                    ),
                    { trigger: true, }
                );
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        anchorLink_click: function (e) {
            try {
                var obj = $(e.target);

                $('html, body').animate(
                    {
                        scrollTop: $(obj.data('anchorTarget')).offset().top + 'px',
                    },
                    'fast'
                );


                //var params = this.model.toJSON();

                //app.router.navigate(
                //    app.router.resolveURL(
                //        app.router.currentModule,
                //        _.extend(
                //            {},
                //            params,
                //            {
                //                section: obj.data('areaCode'),
                //            }
                //        ),
                //        false
                //    ),
                //    { trigger: false, }
                //);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        eafEditBtn_click: function (e) {
            try {
                app.router.navigate(
                    app.router.resolveURL(
                        'eaf-process',
                        {
                            furnaceCode: this.eafProcess.get('furnaceCode'),
                            processId: this.eafProcess.get('id'),
                        },
                        false
                    ),
                    { trigger: true, }
                );
            }
            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.getNextHeat(true);
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        getPreviousItemBtn_click: function (e) {
            try {
                this.getNextHeat(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();

                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); }
        },
        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.Views.LfProcess = Backbone.Epoxy.View.extend({
        className: 'row-fluid lf-process-view',
        events: function () {
            return {
                'click .edit-process-btn': this.editBtn_click,
            };
        },
        bindings: 'data-bind',
        bindingsApplied: false,
        bindingSources: null,

        parent: null,
        subview: null,
        ladleFurnaceCode: null,

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

            if (!this.model)
                this.model = new LfProcessView.Models.Process();

            this.bindingSources = {
                data: new Backbone.Epoxy.Model({ ladleFurnaceCode: this.ladleFurnaceCode, }),
            };

            this.bindEvents();

            this.render();
        },
        applyBindings: function () {
            if (this.bindingsApplied == false) {
                Backbone.Epoxy.View.prototype.applyBindings.apply(this);

                this.bindingsApplied = true;
            }
        },
        bindEvents: function () {
            this.listenTo(this.model.collection, 'fetch', this.model_collection_fetch);
        },
        render: function () {
            this.$el.html(this.template(this.model.toJSON()));

            this.applyBindings();

            this.subview = new LfProcessView.Views.Main({
                model: new LfProcessView.Models.Main({
                    editingProcess: false,
                    heatId: null,
                    mainView: false,
                    processId: this.model.get('id'),
                    ladleFurnaceCode: this.ladleFurnaceCode
                }),
                parent: this,
                container: this.$el.find(".process-info-container"),
                displayChemistry: false,
            });
            this.subview.preRender();
            this.subview.render(null, {});
            this.subview._refresh();

            return this;
        },

        editBtn_click: function (e) {
            try {
                app.router.navigate(
                    app.router.resolveURL(
                        'lf-process',
                        {
                            ladleFurnaceCode: this.model.get('ladleFurnaceCode'),
                            processId: this.model.get('id'),
                        },
                        false
                    ),
                    { trigger: true, }
                );
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        model_collection_fetch: function (coll, resp, opt) {
            try {
                this.subview._refresh();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
    });

    Screen.Views.LfProcessAnchor = Backbone.Epoxy.View.extend({
        tagName: 'a',
        className: 'anchor-link btn',
        attributes: {
            'data-bind': 'attr: { "data-anchor-target": format(".anchor-target-lf-$1", treatment), "data-area-code": format("lf-$1", treatment) }',
        },
        bindings: 'data-bind',

        parent: null,

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

            if (!this.model)
                this.model = new LfProcessView.Models.Process();

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

            this.applyBindings();

            return this;
        },
    });

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