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

  'modules/lf-process',

  'backgrid/computed-cell',
  'backgrid/duration-cell',
  'backgrid/infinator',
  'backgrid/moment-cell',
  'js/backgrid-0.3.5/extensions/valid-limit-cell/backgrid-valid-limit-cell',
],
function (app, T, Backgrid, moment, LfProcess) {

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            start: new moment().format('YYYY-MM-DD'),
            end: new moment().format('YYYY-MM-DD'),

            hasData: false,
            isLoading: false,
        },
        computeds: {
            start$: {
                deps: ['start'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    return { start: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                },
            },
            end$: {
                deps: ['end'],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    return { end: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                },
            },
        },
    });

    Screen.Models.LfProcess = LfProcess.Models.LfProcess.extend({
        defaults: _.extend(
            {},
            LfProcess.Models.LfProcess.prototype.defaults,
            {
            }
        ),

        parse: function (obj, objManualVariables, objSummarized, objValidLimits) {
            if (!objSummarized) objSummarized= {};
            if (!objValidLimits) objValidLimits = {};

            return _.extend(LfProcess.Models.LfProcess.prototype.parse.apply(this, arguments), {
            });
        },
    });

    Screen.Collections.LfProcesses = LfProcess.Collections.LfProcesses.extend({
        model: Screen.Models.LfProcess,

        parseResponse: function (resp, opt) {
            if ((resp) && (resp.Table)) {
                var that = this,
                    newColl,
                    validLimits = (resp.Table2) ? resp.Table2[0] : null;

                newColl = _.map(resp.Table, function (obj) {
                    return that.model.prototype.parse(obj, null, _.findWhere(resp.Table1, { Id: obj.Id, }), validLimits);
                });

                var method = ((opt.refresh) || ((opt.reset))) ? 'set' : 'add';

                var editingItems = _.where(this.toJSON(), { isNew: true });
                [].push.apply(newColl, editingItems);

                this[method](newColl, { from: 'fetch' });

                return true;
            }

            return false;
        },
        updateFixedParameters: function (params) {
            LfProcess.Collections.LfProcesses.prototype.updateFixedParameters.apply(this, arguments);

            this.fixedParameters.push({ name: 'summarizedData', value: true, type: 'VARCHAR', });
            this.fixedParameters.push({ name: 'includeValidLimits', value: true, type: 'VARCHAR', });
        },
    });

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'lf-production',
        id: 'lf-production',
        title: 'LMF Production',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                "click .btn-export-to-excel": this.exportToExcel,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,

        processes: null,
        subviews: null,
        viewParams: 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.processes = new (Screen.Collections.LfProcesses.extend({ pageSize: 50, }))();

            this.bindingSources = {};

            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.processes, 'backgrid:rowclick', this.processes_backgrid_rowclick);
            //this.listenTo(this.model, 'change:start change:end', 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.refreshProcesses(opt);

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

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (viewParams) {
            var fixedParams = _.extend({}, Screen.Models.Main.prototype.defaults, viewParams);

            if (viewParams.start)
                fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
            if (viewParams.end)
                fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');

            this.model.set(fixedParams);

            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    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.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.$el.find('.input-date').datepicker();
                            
                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed',
                                columns: [
                                    {
                                        name: 'heatName',
                                        label: app.translate([that, app], 'process_heat_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    //{
                                    //    name: 'productionDate',
                                    //    label: app.translate([that, app], 'process_production_date_col'),
                                    //    cell: Backgrid.Extension.MomentCell.extend({
                                    //        className: 'momment-cell align-center-cell',
                                    //        modelFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
                                    //        displayFormat: app.translate([that, app], 'MM/DD/YYYY'),
                                    //    }),
                                    //    editable: false,
                                    //},
                                    {
                                        name: 'start',
                                        label: app.translate([that, app], 'process_start_col'),
                                        cell: Backgrid.Extension.MomentCell.extend({
                                            className: 'momment-cell align-center-cell',
                                            modelFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
                                            displayFormat: app.translate([that, app], 'MM/DD/YYYY') + ' HH:mm',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'end',
                                        label: app.translate([that, app], 'process_end_col'),
                                        cell: Backgrid.Extension.MomentCell.extend({
                                            className: 'momment-cell align-center-cell',
                                            modelFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
                                            displayFormat: app.translate([that, app], 'MM/DD/YYYY') + ' HH:mm',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'crewId',
                                        label: app.translate([that, app], 'process_crew_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'gradeName',
                                        label: app.translate([that, app], 'process_grade_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'ladleName',
                                        label: app.translate([that, app], 'process_ladle_col'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'powerOn',
                                        label: app.translate([that, app], 'process_power_on_col'),
                                        cell: Backgrid.Extension.MakeCellValidLimit(Backgrid.StringCell).extend({
                                            className: 'string-cell align-center-cell',
                                            formatter: Backgrid.Extension.DurationFormatter.extend({
                                                displayFormat: 'm:s',
                                                modelFormat: 's',
                                            }),
                                            invalidMessage: function (value, limit) {
                                                return app.translate([that, app], 'process_power_on_invalid_value', [parseInt(limit / 60, 10), ]);
                                            },
                                            validLimitProp: 'powerOnValidLimit',
                                        }),
                                        editable: false,
                                    },
                                    //{
                                    //    name: 'powerOff',
                                    //    label: app.translate([that, app], 'process_power_off_col'),
                                    //    cell: Backgrid.StringCell.extend({
                                    //        className: 'string-cell align-center-cell',
                                    //        formatter: Backgrid.Extension.DurationFormatter.extend({
                                    //            displayFormat: 'm:s',
                                    //            modelFormat: 's',
                                    //        }),
                                    //    }),
                                    //    editable: false,
                                    //},
                                    {
                                        name: 'energy',
                                        label: app.translate([that, app], 'process_energy_col'),
                                        cell: Backgrid.NumberCell.extend({
                                            className: 'numeric-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    //{
                                    //    name: '',
                                    //    label: app.translate([that, app], 'process_energy_per_ton_col'),
                                    //    cell: Backgrid.Extension.MakeCellValidLimit(Backgrid.Extension.ComputedCell).extend({
                                    //        className: 'computed-cell align-center-cell',
                                    //        deps: ['energy', 'steelWeight', ],
                                    //        calculate: function (energy, steelWeight) {
                                    //            if (!energy) energy = 0;
                                    //            if (!steelWeight) steelWeight = 1;

                                    //            //Convert MWH to KWH.
                                    //            return (energy * 1000 / steelWeight).toFixed(2);
                                    //        },
                                    //        invalidMessage: function (value, limit) {
                                    //            return app.translate([that, app], 'process_energy_per_ton_invalid_value', [limit, ]);
                                    //        },
                                    //        validLimitProp: 'energyPerTonValidLimit',
                                    //        update: function () {
                                    //            var value = this.calculate.apply(this, _.map(this.deps, this.model.get, this.model)),
                                    //                limit = this.model.get(this.validLimitProp);

                                    //            if (this.validate(value, limit) == true) {
                                    //                this.$el.attr('title', '')
                                    //                        .removeClass('invalid');
                                    //            }
                                    //            else {
                                    //                var invMsg = ($.isFunction(this.invalidMessage) == true)
                                    //                                ? this.invalidMessage(value, limit)
                                    //                                : this.invalidMessage;

                                    //                this.$el.attr('title', invMsg)
                                    //                        .addClass('invalid');
                                    //            }
                                    //        },
                                    //    }),
                                    //    editable: false,
                                    //},
                                ],
                                collection: that.processes,
                                footer: Backgrid.Extension.Infinator.extend({
                                    scrollToTop: false,
                                }),
                                row: Backgrid.Row.extend({
                                    events: function () {
                                        return {
                                            'click': this.click,
                                        };
                                    },
                                    click: function (e) {
                                        try {
                                            this.model.trigger('backgrid:rowclick', this.model);
                                        }
                                        catch (Error) { console.error(Error.stack); }
                                    }
                                })
                            });
                            that.$el.find('.processes-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.start)
                                fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
                            if (fixedParams.end)
                                fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');

                            that.model.set(fixedParams);

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

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

                            //that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },

        refreshProcesses: function (options) {
            var attrs = this.model.toJSON(),
                opt = _.extend({}, options, { params: {}, });

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

            this.processes.fetch(_.extend(opt, {
                params: {
                    start: attrs.start,
                    end: new moment(attrs.end, 'YYYY-MM-DD').add('days', 1).format('YYYY-MM-DD'),
                },
            }));
        },
        exportToExcel: function () {
            var that = this,
                start = that.model.get('start'),
                end = that.model.get('end');


            var params = [
                { Name: '@fromRow', Type: 'INT', Value: -1 },
                { Name: '@toRow', Type: 'INT', Value: -1 },
                { Name: '@start', Type: 'DATETIME', Value: start, },
                { Name: '@end', Type: 'DATETIME', Value: end, },
                { Name: '@timezoneCode', Type: 'VARCHAR', Value: app.models.user.get("timezoneCode"), },
            ];

            var QP = new QueryParameters();

            _.each(params, function (qpParams) {
                QP.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });


            var data = {
                Data: [],
                ConnectionStringName: 'APP',
                FileName: 'LMF-Production',
                TemplateFileFullPath: 'generic.xls',
                SQLDataSources: [
                    {
                        Name: 'data',
                        DatabaseParameters: {
                            DBEngine: 'SQLSERVER',
                            Procedure: app.DatabaseNames.MES + '.LF.GetProcesses',
                            QueryParameters: QP,
                        },
                    },
                ]
            },
                chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                chari = 0;

            data.Data.push({
                SheetName: 'Data',
                RowsData: [{
                    CellsData:
                        [
                            { Column: chars[chari++], Value: 'Heat' },
                            { Column: chars[chari++], Value: 'Start' },
                            { Column: chars[chari++], Value: 'End' },
                            { Column: chars[chari++], Value: 'Shift' },
                            { Column: chars[chari++], Value: 'Grade' },
                            { Column: chars[chari++], Value: 'Ladle' },
                            { Column: chars[chari++], Value: 'On' },
                            { Column: chars[chari++], Value: 'MWH' },
                        ],
                }],
                StartRowIndex: 1,
            });
            chari = 0;

            data.Data.push({
                SheetName: 'Data',
                RowsData: [],
                StartRowIndex: 2,
                DataSourceName: 'data',
                DataSourceTableIndex: 0,
                SQLCellsData:
                    [
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'HeatName', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'StartString', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'EndString', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'ShiftId', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'GradeName', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'LadleName', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'PowerOnString', DataType: 'String' },
                        { ExcelColumnName: chars[chari++], SQLDataColumnName: 'Energy', DataType: 'Float' },

                    ],
            });

           

            Core.Export.Excel(
                data,
                function (resp) {
                    try {
                        if ((resp) && (resp.Success == true) && (resp.Data)) {
                            location.href = app.foldersRoot + '/excel/' + resp.Data;
                        }
                        else {
                            if ((resp) && (resp.Message))
                                console.error(resp.Message);
                            else
                                console.error('Server response not valid.');
                        }
                    }
                    catch (Error) { console.error(Error); }
                    that.model.setExportButtonExporting(false);
                },
                function (resp) {
                    that.model.setExportButtonExporting(false);
                    console.error(resp);
                }
            );
        },
        processes_backgrid_rowclick: function (model) {
            try {
                app.router.navigate(
                    app.router.resolveURL(
                        'heat',
                        {
                            heatId: model.get('heatId'),
                        },
                        false
                    ),
                    { trigger: true, }
                );
            }
            catch (Error) { console.error(Error.stack); }
        },
        //model_change_pickers: function (model) {
        //    try {
        //        var params = this.model.toJSON();

        //        app.router.navigate(
        //            app.router.resolveURL(
        //                app.router.currentModule,
        //                _.extend(
        //                    {},
        //                    params,
        //                    {
        //                        start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
        //                        end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
        //                    }
        //                ),
        //                false
        //            ),
        //            { trigger: false, }
        //        );

        //        this.refreshProcesses({
        //            reset: true,
        //            params: _.extend(
        //                {},
        //                params,
        //                {}
        //            ),
        //        });
        //    }
        //    catch (Error) { console.error(Error.stack); }
        //},
        refreshBtn_click: function (e) {
            try {
                var params = this.model.toJSON();

                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );

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

                window.scrollTo(0, 0);
            }
            catch (Error) { console.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); }
        },
        stopAutoRefresh: function () {
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }
            this.autoRefresh.enabled = false;
        },
    });

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