//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/modal2',
    'js/d3v4/d3.v4',

    'js/jquery.clearsearch/jquery.clearsearch',
    'js/backgrid-0.3.5/extensions/valid-min-max-cell/backgrid-valid-min-max-cell',

    'backgrid/calendar-cell',
    'backgrid/moment-cell',

    'js/jquery.timepicker/jquery.timepicker',
    'backgrid/time-cell'

],
    function (app, T, Backgrid, moment, Modal, d3) {
        //replace all 'Screen' with your view's name.
        var Screen = {
            Models: {},
            Views: {},
            Collections: {},
        };

        Screen.Collections.ItemsTPH = Backbone.Collection.extend({
            setDataColl: function (data) {
                var newColl,
                    that = this;
                newColl = data;
                that.set(newColl).trigger('fetch', that, data);
            },

        });


        Screen.Collections.ItemsProduction = Backbone.Collection.extend({
            setDataColl: function (data) {
                var newColl,
                    that = this;
                newColl = data;
                that.set(newColl).trigger('fetch', that, data);
            },

        });

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


                productionDate: new moment().subtract(1, 'days').format('MM/DD/YYYY'),

                shiftId: 'D',
                shifts: [],

                crewId: '-',

                hasData_caster1: false,
                isLoading_caster1: true,

                hasData_caster2: false,
                isLoading_caster2: true,


                hasData_allHeats: false,
                isLoading_allHeats: true,

                hasData_warehouseCosts: false,
                isLoading_warehouseCosts: true,

                tphValues: null

            },
            initialize: function () {
                this.itemsCaster1 = new Screen.Collections.ItemsCaster1();
                this.itemsCaster2 = new Screen.Collections.ItemsCaster2();
                this.itemsAllHeats = new Screen.Collections.ItemsAllHeats();
                this.itemsAllDelays = new Screen.Collections.ItemsAllDelays();
                this.itemsWarehouseCosts = new Screen.Collections.ItemsWarehouseCosts();
                this.itemsProduction = new Screen.Collections.ItemsProduction();
                this.itemsTPH = new Screen.Collections.ItemsTPH();
            },
            computeds: {
                hasData: {
                    deps: ['hasData_allHeats'],
                    get: function (heats) {
                        return (heats);
                    },
                },
                isLoading: {
                    deps: ['isLoading_allHeats', 'isLoading_caster2','isLoading_caster1'],
                    get: function (heats, caster2, caster1) {
                        /*return (heats && caster2 && caster1);*/
                        return caster1;
                    },
                },
  
            },

            fetchData: function (params) {
                var that = this,
                    qp = new Core.Database.QueryParameters();
                this.fixedParameters = [
                    { Name: '@ProductionDate', Type: 'DATE', Value: params.productionDate, },
                    { Name: '@ShiftId', Type: 'INT', Value: params.shiftId == '1' ? 1 : (params.shiftId == '2' ? 2 : null), },              
                ];
                _.each(this.fixedParameters, function (qpParams) {
                    qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                });


                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.CAS.GetShiftReport',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (resp) {
                                    var strands = null;
                                    var strandsCaster2 = null;
                                    if (resp.Table6) strands = resp.Table6;
                                    if (resp.Table7) strandsCaster2 = resp.Table7;
                                    if (resp.Table) that.itemsAllHeats.setDataColl(resp.Table, params.shiftId, params.productionDate, strands, strandsCaster2);
                                    if (resp.Table1) that.itemsCaster1.setDataColl(resp.Table1);
                                    if (resp.Table2) that.itemsWarehouseCosts.setDataColl(resp.Table2);
                                    if (resp.Table3) that.itemsProduction.setDataColl(resp.Table3);
                                    that.set({
                                        tphValues: resp.Table4[0],
                                        crewId: resp.Table[0].CrewId,
                                    })
                                    if (resp.Table) that.itemsTPH.setDataColl(resp.Table4);

                                }
                                else {
                                    if ((resp) && (resp.Message))
                                        console.error(new Error(resp.Message).stack);
                                    else
                                        console.error(new Error('SERVER_RESPONSE_NOT_VALID').stack);
                                }
                            }
                            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );

                return this;
            },
        });

        //the generate id method is called everytime a view is going to be shown by the router and returns and id that
        //is used by the router to store in cache (if it is cacheable) and to know the current shown view.
        //this is useful in case your view is reusable, and displays different data depending on url parameters 
        //(such as a catalog view, or a report that doesnt change in terms of UI but it does change in terms of data)
        //so you can always use the same view on the router but the cache can tell which view is which by using differents ids.
        Screen.generateID = function (viewParams) {
            try {
                //if the viewparams change the view id, then evaluate the viewparams here
                //and return the appropiate id.refreshbtn
                return 'caster-shift-report';
            } catch (Error) { }
        }

    

        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'caster-shift-report'
            , id: 'caster-shift-report'
            , title: 'Caster Shift Report'

            //default not cacheable, change this if you want the view to be cacheable
            // if the view is set as cacheable should also have a _refresh method to reset the view without erasing the DOM.
            , isCacheable: false
            , events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click #printBtn': this.printBtn_click,
                    'click #forwardNavBtn': this.forwardNavBtn_click,
                    'click #backNavBtn': this.backNavBtn_click,
                    "click .btn-export-to-excel": this.exportToExcel,
                };
            }
            , bindings: 'data-bind'

            , viewParams: null

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

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

                this.bindEvents();
            }


            , forwardNavBtn_click: function () {
                this.UpdateNav(true);
            }
            , backNavBtn_click: function () {
                this.UpdateNav(false);
            }

            , printBtn_click: function () {
                window.print();
                return false;
            }

            , refreshBtn_click: function (model) {
                this.UpdateURL();
                this.refresh();
            }


            , bindEvents: function () {
                this.listenTo(this.model.itemsCaster1, 'fetch', this.itemsCaster1_ready);
                this.listenTo(this.model.itemsCaster2, 'fetch', this.itemsCaster2_ready);

                this.listenTo(this.model, 'caster2_READY', this.caster1_chart);
                this.listenTo(this.model.itemsAllHeats, 'fetch', this.itemsAllHeats_ready);
                this.listenTo(this.model.itemsAllDelays, 'fetch', this.itemsAllDelays_ready);
                this.listenTo(this.model.itemsWarehouseCosts, 'fetch', this.itemsWarehouseCosts_ready);
            }

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

                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) {
                        //getInternationalizationData
                        if (!that.options.i18n) that.options.i18n = {};

                        app.getI18NJed(
                            that,
                            that.template,
                            function (i18nJED) {
                                //storing internationalization data
                                that.options.i18n[that.template] = i18nJED;
                                that.$el.html(tmp());
                                that.applyBindings();
                                that.append(thatContainer, that.$el);

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

                                // Log Book
                                var grid_caster1 = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                     
                                        {
                                            name: 'Title',
                                            label: 'Title',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Description',
                                            label: 'Description',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell description',
                                            }),
                                        },
                                        {
                                            name: 'Datetime',
                                            label: 'Hour',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'AssetName',
                                            label: 'Equipment',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'TypeName',
                                            label: 'Type',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'StatusCodeName',
                                            label: 'Status',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        //{
                                        //    name: 'Author',
                                        //    label: 'Author',
                                        //    editable: false,
                                        //    cell: Backgrid.StringCell.extend({
                                        //        className: 'string-cell align-center-cell author',
                                        //    }),
                                        //},
                                        
                                    ],
                                    collection: that.model.itemsCaster1,
                                    header: Backgrid.Header.extend({
                                        initialize: function (options) {
                                            Backgrid.Header.prototype.initialize.apply(this, arguments);
                                            this.listenTo(this.collection, 'backgrid:sort', this.collection_backgrid_sort);
                                        },
                                    }),
                                });
                                that.$el.find('.items-grid-container-caster-1').append(grid_caster1.render().el);

                                var grid_caster1_print = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [

                                        {
                                            name: 'Title',
                                            label: 'Title',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Description',
                                            label: 'Description',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell description',
                                            }),
                                        },
                                        {
                                            name: 'Datetime',
                                            label: 'Hour',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'AssetName',
                                            label: 'Equipment',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'TypeName',
                                            label: 'Type',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'StatusCodeName',
                                            label: 'Status',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsCaster1,
                                });
                                that.$el.find('.items-grid-container-caster-1-print').append(grid_caster1_print.render().el);

                                // Warehouse Costs
                                var grid_warehouseCosts = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                        {
                                            name: 'Department',
                                            label: 'Department',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MonthIssues',
                                            label: 'Issues',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MonthReturns',
                                            label: 'Returns',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Total',
                                            label: 'Total',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsWarehouseCosts,
                                });
                                that.$el.find('.items-grid-container-warehouseCosts').append(grid_warehouseCosts.render().el);

                                var grid_warehouseCosts_print = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                        {
                                            name: 'Department',
                                            label: 'Department',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MonthIssues',
                                            label: 'Issues',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MonthReturns',
                                            label: 'Returns',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Total',
                                            label: 'Total',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsWarehouseCosts,
                                    header: Backgrid.Header.extend({
                                        initialize: function (options) {
                                            Backgrid.Header.prototype.initialize.apply(this, arguments);
                                            this.listenTo(this.collection, 'backgrid:sort', this.collection_backgrid_sort);
                                        },
                                    }),
                                });
                                that.$el.find('.items-grid-container-warehouseCosts-print').append(grid_warehouseCosts_print.render().el);

                                // Production
                                var grid_caster2 = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                        {
                                            name: 'CasterNumber',
                                            label: 'Caster',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MeltOrderNumber',
                                            label: 'Melt Order',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'HeatName',
                                            label: 'Heat',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Grade',
                                            label: 'Grade',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Product',
                                            label: 'Product',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Pieces',
                                            label: 'Pieces',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell element shift-crew-column',
                                            }),
                                        },
                                        {
                                            name: 'Open',
                                            label: 'Open',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Close',
                                            label: 'Close',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'CastTime',
                                            label: 'Cast Min',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsProduction,
                                    header: Backgrid.Header.extend({
                                        initialize: function (options) {
                                            Backgrid.Header.prototype.initialize.apply(this, arguments);
                                            this.listenTo(this.collection, 'backgrid:sort', this.collection_backgrid_sort);
                                        },
                                    }),
                                });
                                that.$el.find('.items-grid-container-production').append(grid_caster2.render().el);

                                var grid_caster2_print = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                        {
                                            name: 'CasterNumber',
                                            label: 'Caster',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'MeltOrderNumber',
                                            label: 'Melt Order',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'HeatName',
                                            label: 'Heat',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Grade',
                                            label: 'Grade',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Product',
                                            label: 'Product',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Pieces',
                                            label: 'Pieces',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell element shift-crew-column',
                                            }),
                                        },
                                        {
                                            name: 'Open',
                                            label: 'Open',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'Close',
                                            label: 'Close',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'CastTime',
                                            label: 'Cast Min',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsProduction,
                                });
                                that.$el.find('.items-grid-container-production-print').append(grid_caster2_print.render().el);

                                 // TPH

                                var grid_thp_print = new Backgrid.Grid({
                                    className: 'grid-styles table',
                                    columns: [
                                        {
                                            name: 'S1TPH',
                                            label: 'Strand 1',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'S2TPH',
                                            label: 'Strand 2',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        }, {
                                            name: 'S3TPH',
                                            label: 'Strand 3',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        }, {
                                            name: 'S4TPH',
                                            label: 'Strand 4',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },

                                        {
                                            name: 'S5TPH',
                                            label: 'Strand 5',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                        {
                                            name: 'S6TPH',
                                            label: 'Strand 6',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        }, {
                                            name: 'S8TPH',
                                            label: 'Strand 8',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        }, {
                                            name: 'S9TPH',
                                            label: 'Strand 9',
                                            editable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell',
                                            }),
                                        },
                                    ],
                                    collection: that.model.itemsTPH,                                  
                                });
                                that.$el.find('.items-grid-container-tph-print').append(grid_thp_print.render().el);

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


                                if (fixedParams.productionDate)
                                    fixedParams.productionDate = new moment(fixedParams.productionDate, 'YYYYMMDD').format('MM/DD/YYYY');
                                if (fixedParams.shiftId)
                                    fixedParams.shiftId = fixedParams.shiftId;

                                that.model.set(fixedParams);
                                // refresh collection
                                that.refresh();
                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            }


            , refresh: function () {
                try {

                    var params = this.model.toJSON();


                    this.$el.find('.chart-CASTER-1').html('');
                    this.$el.find('.chart-CASTER-2').html('');
                    this.$el.find('.chart-CASTER-1-print').html('');
                    this.$el.find('.chart-CASTER-2-print').html('');
                    this.model.set({
                        isLoading_allHeats: true,
                        isLoading_caster1: true,
                        isLoading_caster2: true,

                        hasData_allHeats: false,
                        hasData_caster1: false,
                        hasData_caster2: false,

                        hasData_warehouseCosts: false,
                        isLoading_warehouseCosts: true,

                    });
                    var shift = '1';
                    if (params.shiftId == 'D') shift = '1';
                    else if (params.shiftId == 'N') shift = '2';

                    // reload collections 
                    this.model.fetchData({
                        productionDate: params.productionDate,
                        shiftId: shift,
                    });


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


            , forwardNavBtn_click: function () {
                this.UpdateNav(true);
            }
            , backNavBtn_click: function () {
                this.UpdateNav(false);
            }

            , UpdateNav: function (nav) {
                var params = this.model.toJSON();
                if (nav && this.model.get('shiftId') == 'N')
                    this.model.set('productionDate', new moment(params.productionDate, 'MM/DD/YYYY').add(1, 'day').format('MM/DD/YYYY'));

                if (!nav && this.model.get('shiftId') == 'D')
                    this.model.set('productionDate', new moment(params.productionDate, 'MM/DD/YYYY').subtract(1, 'day').format('MM/DD/YYYY'));


                if (this.model.get('shiftId') == 'N') this.model.set('shiftId', 'D');
                else
                    if (this.model.get('shiftId') == 'D') this.model.set('shiftId', 'N');

                this.UpdateURL();
                this.refresh();
            }

            , UpdateURL: function () {
                try {
                    var params = this.model.toJSON();

                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {
                                    productionDate: new moment(params.productionDate, "MM/DD/YYYY").format("YYYYMMDD"),
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            }

            , itemsWarehouseCosts_ready: function () {
                try {
                    var that = this;
                    setTimeout(
                        function () {
                            that.model.set({
                                hasData_warehouseCosts: (that.model.itemsWarehouseCosts.length > 0),
                                isLoading_warehouseCosts: false,
                            });
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            }
            , itemsCaster1_ready: function () {
                try {
                    var that = this;
                    setTimeout(
                        function () {
                            that.model.set({
                                hasData_caster1: (that.model.itemsCaster1.length > 0),
                                //isLoading_caster1: false,
                            });
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            }
            , itemsCaster2_ready: function () {
                try {
                    var that = this;
                    setTimeout(
                        function () {
                            that.model.set({
                                hasData_caster2: (that.model.itemsCaster2.length > 0),
                                isLoading_caster2: false,
                            });
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            }

            , itemsAllHeats_ready: function () {
                try {
                    var that = this;
                    setTimeout(
                        function () {
                            that.model.set({
                                hasData_allHeats: (that.model.itemsAllHeats.length > 0),
                                isLoading_allHeats: false,
                            });
                            that.caster2_chart();
                        },
                        100
                    );

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

           , caster1_chart: function () {
               var that = this;
                           
                setTimeout(
                    function () {
                        that.getChart(true);
                        that.getChartPrint(true);
                        /*that.model.trigger('caster1_READY', that);*/
                        that.model.set({
                            isLoading_caster1: false,
                        });
                    },
                    100
               );

            }
            , caster2_chart: function () {
                var that = this;
                setTimeout(
                    function () {
                        that.getChart(false);
                        that.getChartPrint(false);
                        that.model.trigger('caster2_READY', that);
                    },
                    100
                );


            }


            , getChartPrint(caster1) {
                var chartHeight = 180,
                    chartWeight = 1100,

                    dataHeight = chartHeight / 2,
                    delayHeight = chartHeight / 4,
                    divisions = 12,
                    pixelHour = chartWeight / divisions,
                    pixelMinute = pixelHour / 60,
                    separationPixels = 10,
                    axisHeight = 20,
                    startHourPixel = 0,
                    start = 0,
                    start_yPos = 0,
                    data = [],
                    size_letter = 10;

                var strandsData = [];

                if (caster1) {
                    _.each(this.model.itemsAllHeats.getHeats_caster1(), function (obj) {
                        data.push(obj);
                    })
                    _.each(this.model.itemsAllDelays.getDelay_caster1(), function (obj) {
                        data.push(obj);
                    });
                    _.each(this.model.itemsAllHeats.getStrandSpeeds(), function (obj) {
                        strandsData.push(obj);
                    });
                    var chart_class = ".chart-CASTER-1-print";
                } else {
                    _.each(this.model.itemsAllHeats.getHeats_caster2(), function (obj) {
                        data.push(obj);
                    })
                    _.each(this.model.itemsAllDelays.getDelay_caster2(), function (obj) {
                        data.push(obj);
                    });
                    _.each(this.model.itemsAllHeats.getCaster2StrandSpeeds(), function (obj) {
                        strandsData.push(obj);
                    });
                    var chart_class = ".chart-CASTER-2-print";
                }
                if (data.length > 0) {
                    var chart = d3.select(chart_class)
                        .attr("width", chartWeight + 40)
                        .attr("height", chartHeight + separationPixels + axisHeight)

                    ////Strands
                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1110 + "," + 40 + ")"; })
                        .text(function (d) { return caster1 ? 'S1' : 'S5'; })

                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1110 + "," + 55 + ")"; })
                        .text(function (d) { return caster1 ? 'S2' : 'S6'; })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1110 + "," + 70 + ")"; })
                        .text(function (d) { return caster1 ? 'S3' : 'S8'; })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1110 + "," + 85 + ")"; })
                        .text(function (d) { return caster1 ? 'S4' : 'S9'; })
                    // Append the horizontal lines
                    chart.append("rect")
                        .attr("class", "line")
                        .attr("width", chartWeight)
                        .attr("height", 0.5)
                        .style('opacity', 1)
                        .attr("transform", "translate(0," + dataHeight / 2 + ")")
                        .style('fill', '#404040')

                    chart.append("rect")
                        .attr("class", "line")
                        .attr("width", chartWeight)
                        .attr("height", 0.5)
                        .style('opacity', 1)
                        .attr("transform", "translate(0," + (parseFloat(dataHeight / 4) + parseFloat(dataHeight) + separationPixels) + ")")
                        .style('fill', '#404040')

                    var bar = chart.selectAll("g")
                        .data(data)
                        .enter().append("g")

                    //Append delays and heats
                    bar.append("rect")
                        .attr("width", function (d) { return (d.diffHours > 0) ? d.diffHours * pixelHour : 0; })
                        .attr("height", function (d) {
                            if (d.type == 'delay') return delayHeight;
                            return dataHeight;
                        })
                        .attr("transform", function (d) {
                            start = parseFloat(d.startHour);
                            start_yPos = (d.type == "heat") ? parseInt(0) : (dataHeight + separationPixels);
                            if (d.shift == "D") {
                                startHourPixel = start - 9;
                            }
                            else if (d.shift == "N") {
                                if (d.startHour >= 21) {
                                    startHourPixel = start - 21;
                                }
                                else if (d.startHour < 21) {
                                    startHourPixel = start + 3;
                                }
                            }
                            return "translate(" + startHourPixel * pixelHour + "," + start_yPos + ")";
                        })
                        .style('fill', function (d) { /*return d.color;*/ return '#eee' })
                        .style('opacity', 1)
                        .attr('stroke', '#404040')
                        .on('mouseover', function () {
                            d3.select(this)
                                .transition()
                                .duration(500)
                                .attr('stroke', 'red')
                                .attr('stroke-width', 2)
                        })
                        .on('mouseout', function () {
                            d3.select(this)
                                .transition()
                                .duration(500)
                                .attr('stroke', '#404040')
                                .attr('stroke-width', 1)
                        })
                        .append("svg:title")
                        .text(function (d) { return "Start: " + d.start + " " + "End: " + d.end + " Dur: " + d.duration })


                    //------------------------------------
                    //--- NEW STRANDS DRAW
                    //------------------------------------             
                    _.each(data, function (d) {
                            var strand = caster1 ? 1 : 5;
                            var strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            if (strs.length > 0) {
                                var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                                var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                                start = parseFloat(currentHeatInfo.startHour);

                                if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                                else {
                                    if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                    else startHourPixel = start + 3;
                                }


                                _.each(strandsInfo, function (obj, i) {
                                    bar.append("rect")
                                        .attr("width", function (d) { return pixelMinute; })
                                        .attr("height", function (d) { return (11.25); })
                                        .attr("transform", function (d) {
                                            y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                                : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                    : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                            var s = pixelMinute * i + startHourPixel * pixelHour;
                                            return "translate(" + s + "," + y + ")";
                                        })
                                        .style('fill', function (d) { return obj.Color })
                                        .style('opacity', 1)
                                        .attr('stroke', obj.Color)
                                });
                            }

                            strand = caster1 ? 2 : 6;
                            strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            if (strs.length > 0) {
                                var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                                var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                                start = parseFloat(currentHeatInfo.startHour);

                                if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                                else {
                                    if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                    else startHourPixel = start + 3;
                                }


                                _.each(strandsInfo, function (obj, i) {
                                    bar.append("rect")
                                        .attr("width", function (d) { return pixelMinute; })
                                        .attr("height", function (d) { return (11.25); })
                                        .attr("transform", function (d) {
                                            y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                                : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                    : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                            var s = pixelMinute * i + startHourPixel * pixelHour;
                                            return "translate(" + s + "," + y + ")";
                                        })
                                        .style('fill', function (d) { return obj.Color })
                                        .style('opacity', 1)
                                        .attr('stroke', obj.Color)
                                });
                            }


                            strand = caster1 ? 3 : 8;
                            strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            if (strs.length > 0) {
                                var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                                var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                                start = parseFloat(currentHeatInfo.startHour);

                                if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                                else {
                                    if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                    else startHourPixel = start + 3;
                                }


                                _.each(strandsInfo, function (obj, i) {
                                    bar.append("rect")
                                        .attr("width", function (d) { return pixelMinute; })
                                        .attr("height", function (d) { return (11.25); })
                                        .attr("transform", function (d) {
                                            y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                                : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                    : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                            var s = pixelMinute * i + startHourPixel * pixelHour;
                                            return "translate(" + s + "," + y + ")";
                                        })
                                        .style('fill', function (d) { return obj.Color })
                                        .style('opacity', 1)
                                        .attr('stroke', obj.Color)
                                });
                            }

                            strand = caster1 ? 4 : 9;
                            strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            if (strs.length > 0) {
                                var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                                var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                                start = parseFloat(currentHeatInfo.startHour);

                                if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                                else {
                                    if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                    else startHourPixel = start + 3;
                                }


                                _.each(strandsInfo, function (obj, i) {
                                    bar.append("rect")
                                        .attr("width", function (d) { return pixelMinute; })
                                        .attr("height", function (d) { return (11.25); })
                                        .attr("transform", function (d) {
                                            y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                                : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                    : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                            var s = pixelMinute * i + startHourPixel * pixelHour;
                                            return "translate(" + s + "," + y + ")";
                                        })
                                        .style('fill', function (d) { return obj.Color })
                                        .style('opacity', 1)
                                        .attr('stroke', obj.Color)
                                });
                            }
                        });
                

                    //-----------------------------------
                    //-----------------------------------
                    ////Append top text

                    bar.append("text")
                        .attr("class", "top_text")
                        .attr("y", function (d) {
                            return (d.type == "heat") ? (parseInt(0) + 2 * size_letter) : (dataHeight + separationPixels + 2 * size_letter);

                        })
                        .text(function (d) {
                            if (d.name) {
                                var text = ((d.name.length * size_letter) > (d.diffHours * pixelHour)) ? '' : d.name;
                                return text;
                            } else
                                return '';
                        })
                        .attr("id", function (d, i) { return "int_text" + "_" + i });

                    // Center the top text in the rectangle
                    chart.selectAll("g")
                        .select(".top_text")
                        .attr("x", function (d, i) {
                            var text_element = document.getElementById("int_text" + "_" + i);
                            var text_element_width = text_element.getBoundingClientRect().width;

                            start = parseFloat(d.startHour);
                            if (d.shift == "D") startHourPixel = start - 9;
                            else if (d.shift == "N") {
                                if (d.startHour >= 21) startHourPixel = start - 21;
                                else if (d.startHour < 21) startHourPixel = start + 3;
                            }
                            var rect_start = startHourPixel * pixelHour,
                                rect_width = d.diffHours * pixelHour;
                            return rect_start + rect_width - ((rect_width - text_element_width) / 2) + 10;

                        });

                    chart.selectAll("g")
                        .select(".bottom_text")
                        .attr("x", function (d, i) {
                            var text_element = document.getElementById("int_bottom_text" + "_" + i);
                            var text_element_width = text_element.getBoundingClientRect().width;
                            start = parseFloat(d.startHour);
                            if (d.shift == "D") startHourPixel = start - 9;
                            else if (d.shift == "N") {
                                if (d.startHour >= 21) startHourPixel = start - 21;
                                else if (d.startHour < 21) startHourPixel = start + 3;
                            }
                            var rect_start = startHourPixel * pixelHour,
                                rect_width = d.diffHours * pixelHour;

                            return rect_start + rect_width - ((rect_width - text_element_width) / 2) + 10;

                        });

                    //Select the correct scale
                    var params = this.model.toJSON();
                    if (params.shiftId == 'D') {
                        var scale = d3.scalePoint()
                            .domain(["9AM", "10AM", "11AM", "12PM", "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM"])
                            .range([0, chartWeight]);
                    } else if (params.shiftId == 'N') {
                        var scale = d3.scalePoint()
                            .domain(["9PM", "10PM", "11PM", "12AM", "1AM", "2AM", "3AM", "4AM", "5AM", "6AM", "7AM", "8AM", "9AM"])
                            .range([0, chartWeight]);
                    }
                    // Append x axis
                    var x_axis = d3.axisBottom()
                        .scale(scale);

                    chart.append("g")
                        .attr("class", "axis_label")
                        .attr("transform", "translate(0," + (chartHeight + separationPixels + 4) + ")")
                        .call(x_axis);

                    var array_id = [];
                    chart.selectAll("g")
                        .select(".tick text")
                        .attr("id", function (d, i) {
                            array_id.push(i);
                            return "text_hour" + "_" + i
                        });

                    chart.selectAll("g")
                        .select("#text_hour_" + array_id[1]).attr("x", 10);

                    chart.selectAll("g")
                        .select("#text_hour_" + array_id[13]).attr("x", -10);
                }
            }

            , getChart(caster1) {
                var offset = 30;

                var chartHeight = 180,
                    chartWeight = 1470,

                    dataHeight = chartHeight / 2,
                    delayHeight = chartHeight / 4,
                    divisions = 12,
                    pixelHour = (chartWeight) / divisions,
                    pixelMinute = pixelHour / 60,
                    separationPixels = 10,
                    axisHeight = 20,
                    startHourPixel = 0,
                    start = 0,
                    start_yPos = 0,
                    data = [],
                    size_letter = 10;
                var strandsData = [];

                var that = this;
                if (caster1) {
                    _.each(this.model.itemsAllHeats.getHeats_caster1(), function (obj) {
                        data.push(obj);
                    })
                    _.each(this.model.itemsAllDelays.getDelay_caster1(), function (obj) {
                        data.push(obj);
                    });
                    _.each(this.model.itemsAllHeats.getStrandSpeeds(), function (obj) {
                        strandsData.push(obj);
                    });
                    var chart_class = ".chart-CASTER-1";
                } else {
                    _.each(this.model.itemsAllHeats.getHeats_caster2(), function (obj) {
                        data.push(obj);
                    })
                    _.each(this.model.itemsAllDelays.getDelay_caster2(), function (obj) {
                        data.push(obj);
                    });
                    _.each(this.model.itemsAllHeats.getCaster2StrandSpeeds(), function (obj) {
                        strandsData.push(obj);
                    });
                    var chart_class = ".chart-CASTER-2";
                }
                if (data.length > 0) {
                    var chart = d3.select(chart_class)
                        .attr("width", 1650)
                        .attr("height", chartHeight + separationPixels + axisHeight)

                    var tph = this.model.get('tphValues');

                    //TPH
                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1550 + "," + 10 + ")"; })
                        .text(function (d) { return 'TPH' })

                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1550 + "," + 40 + ")"; })
                        .text(function (d) { return caster1 ? tph.S1TPH : tph.S5TPH })

                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1550 + "," + 55 + ")"; })
                        .text(function (d) { return caster1 ? tph.S2TPH : tph.S6TPH })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1550 + "," + 70 + ")"; })
                        .text(function (d) { return caster1 ? tph.S3TPH : tph.S8TPH })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1550 + "," + 85 + ")"; })
                        .text(function (d) { return caster1 ? tph.S4TPH : tph.S9TPH })

                    ////Strands
                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1500 + "," + 10 + ")"; })
                        .text(function (d) { return 'STRAND' })

                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1500 + "," + 40 + ")"; })
                        .text(function (d) { return caster1 ? '1' : '5'; })

                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1500 + "," + 55 + ")"; })
                        .text(function (d) { return caster1 ? '2' : '6'; })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1500 + "," + 70 + ")"; })
                        .text(function (d) { return caster1 ? '3' : '8'; })


                    chart.append("text")
                        .attr("class", "strand_text")
                        .attr("y", function (d) { return 0; })
                        .attr("transform", function (d) { return "translate(" + 1500 + "," + 85 + ")"; })
                        .text(function (d) { return caster1 ?'4' : '9'; })

                    // Append the horizontal lines
                    chart.append("rect")
                        .attr("class", "line")
                        .attr("width", chartWeight)
                        .attr("height", 0.5)
                        .style('opacity', 1)
                        .attr("transform", "translate(" + 0 + "," + dataHeight / 2 + ")")
                        .style('fill', '#404040')

                    chart.append("rect")
                        .attr("class", "line")
                        .attr("width", chartWeight)
                        .attr("height", 0.5)
                        .style('opacity', 1)
                        .attr("transform", "translate(" + 0 + "," + (parseFloat(dataHeight / 4) + parseFloat(dataHeight) + separationPixels) + ")")
                        .style('fill', '#404040')

                    var bar = chart.selectAll("g")
                        .data(data)
                        .enter().append("g")

                    //Append delays and heats
                    bar.append("rect")
                        .attr("width", function (d) { return (d.diffHours > 0) ? d.diffHours * pixelHour : 0; })
                        .attr("height", function (d) {
                            if (d.type == 'delay') return delayHeight;
                            return dataHeight;
                        })
                        .attr("transform", function (d) {
                            start = parseFloat(d.startHour);
                            start_yPos = (d.type == "heat") ? parseInt(0) : (dataHeight + separationPixels);
                            if (d.shift == "D") {
                                startHourPixel = start - 9;
                            }
                            else if (d.shift == "N") {
                                if (d.startHour >= 21) {
                                    startHourPixel = start - 21;
                                }
                                else if (d.startHour < 21) {
                                    startHourPixel = start + 3;
                                }
                            }
                            return "translate(" + startHourPixel * pixelHour + "," + start_yPos + ")";
                        })
                        .style('fill', function (d) { /*return d.color;*/ return '#eee'; })
                        .style('opacity', 1)
                        .attr('stroke', '#404040')
                        .on('mouseover', function () {
                            d3.select(this)
                                .transition()
                                .duration(500)
                                .attr('stroke', 'red')
                                .attr('stroke-width', 2)
                        })
                        .on('mouseout', function () {
                            d3.select(this)
                                .transition()
                                .duration(500)
                                .attr('stroke', '#404040')
                                .attr('stroke-width', 1)
                        })
                        .append("svg:title")
                        .text(function (d) { return "Heat: " + d.heatName + "Start: " + d.start + " Dur: " + d.duration })


                    //------------------------------------
                    //--- NEW STRANDS DRAW
                    //------------------------------------                
                    _.each(data, function (d) {
                        var strand = caster1 ? 1 : 5;
                        var strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                
                        if (strs.length > 0) {
                            var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                            var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            start = parseFloat(currentHeatInfo.startHour);
                            if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                            else {
                                if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                else startHourPixel = start + 3;
                            }


                            _.each(strandsInfo, function (obj, i) {
                                bar.append("rect")
                                    .attr("width", function (d) { return pixelMinute; })
                                    .attr("height", function (d) { return (11.25); })
                                    .attr("transform", function (d) {
                                        y =     obj.Strand === 1 || obj.Strand ===5 ? parseInt(30)
                                             : (obj.Strand === 2 || obj.Strand ===6 ? parseInt(45)
                                             : (obj.Strand === 3 || obj.Strand ===8 ? parseInt(60) : parseInt(75)));
                                        var s = pixelMinute * i + startHourPixel * pixelHour;
                                        return "translate(" + s + "," + y + ")";
                                    })
                                    .style('fill', function (d) { return obj.Color })
                                    .style('opacity', 1)
                                    .attr('stroke', obj.Color)
                            });
                        }

                        strand = caster1 ? 2 : 6;
                        strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                       
                        if (strs.length > 0) {
                            var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                            var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            start = parseFloat(currentHeatInfo.startHour);

                            if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                            else {
                                if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                else startHourPixel = start + 3;
                            }


                            _.each(strandsInfo, function (obj, i) {
                                bar.append("rect")
                                    .attr("width", function (d) { return pixelMinute; })
                                    .attr("height", function (d) { return (11.25); })
                                    .attr("transform", function (d) {
                                        y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                            : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                        var s = pixelMinute * i + startHourPixel * pixelHour;
                                        return "translate(" + s + "," + y + ")";
                                    })
                                    .style('fill', function (d) { return obj.Color })
                                    .style('opacity', 1)
                                    .attr('stroke', obj.Color)
                            });
                        }



                        strand = caster1 ? 3 : 8;
                        strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                 
                        if (strs.length > 0) {
                            var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                            var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            start = parseFloat(currentHeatInfo.startHour);

                            if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                            else {
                                if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                else startHourPixel = start + 3;
                            }


                            _.each(strandsInfo, function (obj, i) {
                                bar.append("rect")
                                    .attr("width", function (d) { return pixelMinute; })
                                    .attr("height", function (d) { return (11.25); })
                                    .attr("transform", function (d) {
                                        y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                            : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                        var s = pixelMinute * i + startHourPixel * pixelHour;
                                        return "translate(" + s + "," + y + ")";
                                    })
                                    .style('fill', function (d) { return obj.Color })
                                    .style('opacity', 1)
                                    .attr('stroke', obj.Color)
                            });
                        }

                        strand = caster1 ? 4 : 9;
                        strs = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
              
                        if (strs.length > 0) {
                            var currentHeatInfo = _.where(data, { heatName: d.heatName })[0];
                            var strandsInfo = _.where(strandsData, { HeatName: d.heatName, Strand: strand });
                            start = parseFloat(currentHeatInfo.startHour);

                            if (currentHeatInfo.shift === "D") startHourPixel = start - 9;
                            else {
                                if (currentHeatInfo.startHour >= 21) startHourPixel = start - 21;
                                else startHourPixel = start + 3;
                            }


                            _.each(strandsInfo, function (obj, i) {
                                bar.append("rect")
                                    .attr("width", function (d) { return pixelMinute; })
                                    .attr("height", function (d) { return (11.25); })
                                    .attr("transform", function (d) {
                                        y = obj.Strand === 1 || obj.Strand === 5 ? parseInt(30)
                                            : (obj.Strand === 2 || obj.Strand === 6 ? parseInt(45)
                                                : (obj.Strand === 3 || obj.Strand === 8 ? parseInt(60) : parseInt(75)));
                                        var s = pixelMinute * i + startHourPixel * pixelHour;
                                        return "translate(" + s + "," + y + ")";
                                    })
                                    .style('fill', function (d) { return obj.Color })
                                    .style('opacity', 1)
                                    .attr('stroke', obj.Color)
                            });
                        }
                    });


                    //-----------------------------------
                    //-----------------------------------

                    ////Append top text

                    bar.append("text")
                        .attr("class", "top_text")
                        .attr("y", function (d) {
                            return (d.type == "heat") ? (parseInt(0) + 2 * size_letter) : (dataHeight + separationPixels + 2 * size_letter);

                        })
                        .text(function (d) {
                            if (d.name) {
                                var text = ((d.name.length * size_letter) > (d.diffHours * pixelHour)) ? '' : d.name;
                                return text;
                            } else
                                return '';
                        })
                        .attr("id", function (d, i) { return "int_text" + "_" + i });

                    // Center the top text in the rectangle
                    chart.selectAll("g")
                        .select(".top_text")
                        .attr("x", function (d, i) {
                            var text_element = document.getElementById("int_text" + "_" + i);
                            var text_element_width = text_element.getBoundingClientRect().width;

                            start = parseFloat(d.startHour);
                            if (d.shift == "D") startHourPixel = start - 9;
                            else if (d.shift == "N") {
                                if (d.startHour >= 21) startHourPixel = start - 21;
                                else if (d.startHour < 21) startHourPixel = start + 3;
                            }
                            var rect_start = startHourPixel * pixelHour,
                                rect_width = d.diffHours * pixelHour;
                            return rect_start + rect_width - ((rect_width - text_element_width) / 2) + 10;

                        });

                    //----------------------------------------//
                    //-----------------Strands ---------------//
                    //----------------------------------------//

                    //Select the correct scale
                    var params = this.model.toJSON();
                    if (params.shiftId == 'D') {
                        var scale = d3.scalePoint()
                            .domain(["9AM", "10AM", "11AM", "12PM", "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM"])
                            .range([0, chartWeight]);
                    } else if (params.shiftId == 'N') {
                        var scale = d3.scalePoint()
                            .domain(["9PM", "10PM", "11PM", "12AM", "1AM", "2AM", "3AM", "4AM", "5AM", "6AM", "7AM", "8AM", "9AM"])
                            .range([0, chartWeight]);
                    }
                    // Append x axis
                    var x_axis = d3.axisBottom()
                        .scale(scale);

                    chart.append("g")
                        .attr("class", "axis_label")
                        .attr("transform", "translate(" + 0 + "," + (chartHeight + separationPixels + 4) + ")")
                        .call(x_axis);

                    var array_id = [];
                    chart.selectAll("g")
                        .select(".tick text")
                        .attr("id", function (d, i) {
                            array_id.push(i);
                            return "text_hour" + "_" + i
                        });

                    chart.selectAll("g")
                        .select("#text_hour_" + array_id[1]).attr("x", 10);

                    chart.selectAll("g")
                        .select("#text_hour_" + array_id[13]).attr("x", -10);
                }
            }           


            // Common functions
            , 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.remove();
                this.unbindViewScopedEvents();
                this.unbind();
            }
            , show: function () {
                this.options.state = app.view_states.shown;

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

                this.$el.hide();
                this.unbind();
                this.stopListening();
            }
            , preRender: function () {
                app.models.subnavbar.set('subnavbar', false);
            }
            , reRender: function (viewParams) {
                try {
                    this.refresh();
                } catch (Error) { }
            }


        });

        Screen.Collections.ItemsWarehouseCosts = Backbone.Collection.extend({
            setDataColl: function (data) {
                var newColl,
                    that = this;
                newColl = data;
                that.set(newColl).trigger('fetch', that, data);
            },
        });


        Screen.Collections.ItemsCaster1 = Backbone.Collection.extend({
            setDataColl: function (data) {
                var newColl,
                    that = this;
                newColl = data;
                that.set(newColl).trigger('fetch', that, data);
            },
        });
        Screen.Collections.ItemsCaster2 = Backbone.Collection.extend({
            setDataColl: function (data) {
                var newColl,
                    that = this;
                newColl = data;
                that.set(newColl).trigger('fetch', that, data);
            },
        });
        


        Screen.Models.ItemAllDelay = Backbone.Epoxy.Model.extend({
            parse: function (obj) {
                var result = {
                    CasterNumber: obj.CasterNumber,
                    Code: obj.Code,
                    Start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                    End: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                    Duration: obj.Duration,
                    Color: obj.Color,
                };
                return result;
            },
        });
        Screen.Collections.ItemsAllDelays = Backbone.Collection.extend({
            model: Screen.Models.ItemAllDelay,

            caster1_delays: [],
            caster2_delays: [],

            setDataColl: function (data, shiftId, productionDate) {
                var newColl,
                    that = this;
                that.setDataChart(data, shiftId, productionDate);
                newColl = _.map(data, that.model.prototype.parse);
                that.set(newColl).trigger('fetch', that, data);
            },

            setDataChart: function (delays, shiftId, prodDate) {
                var caster1_delays = [],
                    caster2_delays = [],
                    aux_delay = [];

                var aux_start = null,
                    aux_end = null,
                    shift = 'D',
                    aux_duration = null;

                var START_D = new moment(prodDate + ' ' + '09:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    END_D = new moment(prodDate + ' ' + '21:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    START_N = new moment(prodDate + ' ' + '21:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    END_N = new moment(prodDate + ' ' + '09:00:00', 'MM/DD/YYYY HH:mm:ss').add(1, 'd').format('YYYY-MM-DD HH:mm:ss');

                if (shiftId == '1') shift = 'D';
                else if (shiftId == '2') shift = 'N';

                _.each(delays, function (obj) {
                    var start = new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss");
                    var end = new moment(obj.End).format("YYYY-MM-DD HH:mm:ss");
                    var push = false;
                    if (shift == 'D') {
                        if (moment(START_D).isBefore(end) && moment(start).isBefore(END_D)) {
                            push = true;
                            if (moment(start).isBefore(START_D)) aux_start = START_D;
                            else aux_start = start;
                            if (moment(END_D).isBefore(end)) aux_end = END_D;
                            else aux_end = end;
                        }
                    } else if (shift == 'N') {
                        if (moment(START_N).isBefore(end) && moment(start).isBefore(END_N)) {
                            push = true;
                            if (moment(start).isBefore(START_N)) aux_start = START_N;
                            else aux_start = start;
                            if (moment(END_N).isBefore(end)) aux_end = END_N;
                            else aux_end = end;
                        }
                    };

                    if (push) {
                        var aux_start_diff = moment(new moment(aux_start, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss');
                        var aux_end_diff = moment(new moment(aux_end, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss');
                        var diffHours = aux_end_diff.diff(aux_start_diff, 'hours', true).toFixed(2);
                        var m = parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:SS').format('mm')) / 60;
                        var s = parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:SS').format('ss')) / 3600;
                        var aux = parseFloat(parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:ss').format('HH')) + m + s).toFixed(2);
                        if (obj.CasterNumber == 'Caster 1') {
                            caster1_delays.push({
                                type: 'delay',
                                name: obj.Duration + ' Min',
                                diffHours: diffHours,
                                duration: obj.Duration + ' Min',
                                color: obj.Color,
                                start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                                startHour: aux,
                                end: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                                shift: shift,
                            });
                        } else if (obj.CasterNumber == 'Caster 2') {
                            caster2_delays.push({
                                type: 'delay',
                                name: obj.Duration + ' Min',
                                diffHours: diffHours,
                                duration: obj.Duration + ' Min',
                                color: obj.Color,
                                start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                                startHour: aux,
                                end: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                                shift: shift,
                            });
                        }
                    }


                });
                this.caster1_delays = caster1_delays;
                this.caster2_delays = caster2_delays;
            },
            getDelay_caster1: function () {
                return this.caster1_delays;
            },
            getDelay_caster2: function () {
                return this.caster2_delays;
            },

        });

        Screen.Models.ItemAllHeat = Backbone.Epoxy.Model.extend({
            parse: function (obj) {
                var result = {
                    CasterNumber: obj.CasterNumber,
                    HeatName: obj.HeatName,
                    Start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                    End: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                    PowerOn: obj.PowerOn,

                };
                return result;
            },
        });

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

            caster1_heats: [],
            caster2_heats: [],
            strandSpeeds: [],
            strandSpeedsCaster2: [],
            setDataColl: function (data, shiftId, productionDate, strands, strandsCaster2) {
                var newColl,
                    that = this;
                that.setDataChart(data, shiftId, productionDate, strands, strandsCaster2);
                newColl = _.map(data, that.model.prototype.parse);
                that.set(newColl).trigger('fetch', that, data);
            },

            setDataChart: function (heats, shiftId, prodDate, strands, strandsCaster2) {
                var caster1_heats = [],
                    caster2_heats = [],
                    aux_heats = [];

                var aux_start = null,
                    aux_end = null,
                    shift = 'D',
                    aux_duration = null;

                var START_D = new moment(prodDate + ' ' + '09:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    END_D = new moment(prodDate + ' ' + '21:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    START_N = new moment(prodDate + ' ' + '21:00:00', 'MM/DD/YYYY HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'),
                    END_N = new moment(prodDate + ' ' + '09:00:00', 'MM/DD/YYYY HH:mm:ss').add(1, 'd').format('YYYY-MM-DD HH:mm:ss');

                if (shiftId == '1') shift = 'D';
                else if (shiftId == '2') shift = 'N';

                _.each(heats, function (obj) {
                    var start = new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss");
                    var end = new moment(obj.End).format("YYYY-MM-DD HH:mm:ss");
                    var push = false;
                    if (shift == 'D') {
                        if (moment(START_D).isBefore(end) && moment(start).isBefore(END_D)) {
                            push = true;
                            if (moment(start).isBefore(START_D)) aux_start = START_D;
                            else aux_start = start;
                            if (moment(END_D).isBefore(end)) aux_end = END_D;
                            else aux_end = end;
                        }
                    } else if (shift == 'N') {
                        if (moment(START_N).isBefore(end) && moment(start).isBefore(END_N)) {
                            push = true;
                            if (moment(start).isBefore(START_N)) aux_start = START_N;
                            else aux_start = start;
                            if (moment(END_N).isBefore(end)) aux_end = END_N;
                            else aux_end = end;
                        }
                    };

                    if (push) {
                        var aux_start_diff = moment(new moment(aux_start, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss');
                        var aux_end_diff = moment(new moment(aux_end, 'YYYY-MM-DD HH:mm:ss').format('YYYY-MM-DD HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss');
                        var diffHours = aux_end_diff.diff(aux_start_diff, 'hours', true).toFixed(2);
                        var m = parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:SS').format('mm')) / 60;
                        var s = parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:SS').format('ss')) / 3600;
                        var aux = parseFloat(parseInt(new moment(aux_start, 'YYYY-MM-DD HH:mm:ss').format('HH')) + m + s).toFixed(2);

                        var aux_color = '#3ebf3c';
                        if (parseFloat(obj.Duration) > parseFloat(40) && parseFloat(obj.Duration) <= parseFloat(50)) aux_color = '#f3f317';
                        else if (parseFloat(obj.Duration) > parseFloat(50)) aux_color = '#ff5900';

                        if (obj.CasterNumber == 'Caster 1') {
                            caster1_heats.push({
                                type: 'heat',
                                name: obj.HeatName.substr(obj.HeatName.length - 3),
                                diffHours: diffHours,
                                duration: obj.Duration + ' Min',
                                color: aux_color,
                                start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                                startHour: aux,
                                end: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                                shift: shift,
                                powerOn: obj.PowerOn,
                                enabledS1: obj.EnabledS1,
                                enabledS2: obj.EnabledS2,
                                enabledS3: obj.EnabledS3,
                                enabledS4: obj.EnabledS4,
                                heatName: obj.HeatName,
                            });
                        } else if (obj.CasterNumber == 'Caster 2') {
                            caster2_heats.push({
                                type: 'heat',
                                name: obj.HeatName.substr(obj.HeatName.length - 3),
                                diffHours: diffHours,
                                color: aux_color,
                                duration: obj.Duration + ' Min',
                                start: new moment(obj.Start).format("YYYY-MM-DD HH:mm:ss"),
                                startHour: aux,
                                end: new moment(obj.End).format("YYYY-MM-DD HH:mm:ss"),
                                shift: shift,
                                powerOn: obj.PowerOn,
                                enabledS1: obj.EnabledS1,
                                enabledS2: obj.EnabledS2,
                                enabledS3: obj.EnabledS3,
                                enabledS4: obj.EnabledS4,
                                heatName: obj.HeatName,
                            });
                        }
                    }


                });
                this.caster1_heats = caster1_heats;
                this.caster2_heats = caster2_heats;
                this.strandSpeeds = strands;
                this.strandSpeedsCaster2 = strandsCaster2;
            },
            getHeats_caster1: function () {
                return this.caster1_heats;
            },
            getHeats_caster2: function () {
                return this.caster2_heats;
            },
            getStrandSpeeds: function () {
                return this.strandSpeeds;
            },
            getCaster2StrandSpeeds: function () {
                return this.strandSpeedsCaster2;
            }


        });


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

    });