//SCREEN-BOILERPLATE

//this boilerplate builds screens that are gonna be shown in the <div class="content"> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

define([
  // Application variable, always include it to have access to app methods.
  "app",

  //templates-loader: this loads templates async.
  "js/templates-loader",

  "backgrid",

  "modules/modal", 
  "moment",
  "js/dashboard-assets/progressbar/progressbar",

  "modules/dateTimeControl",
    "modules/dateControl",
    'js/d3v4/d3.v4',
    "backgrid/infinator",
],

function (app, T, Backgrid, Modal, moment, ProgressBar, DateTimeControl, DateControl,d3) {

    //replace all "Screen" with your view's name.
    var Screen = { Models: {}, Views: {}, Collections: {} }

    Screen.Models.Main = Backbone.Model.extend({
        defaults: {
            categories: [],
            timeAccounts: null,


            //
        },
        initialize: function () {
            this.attributes.timeAccounts = new Screen.Collections.TimeAccounts(); 
        },

        fetchCategories: function () {
            var that = this;
            Core.Json.CallProcedure(app.DatabaseNames.IHDelays + ".WebApp.GetDelayCategories", null, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var items = data.Table;

                        var categories = [].concat(
                            [
                                { color: '#f84e4e', name: 'NOTDECLARED', description: 'Not Declared', },
                                //{ color: '#008CFF', name: 'MICRODELAY', description: 'Micro Delay', },
                            ],
                            _.map(items, function (m) {
                                return { 
                                    color: m.Color,
                                    description: (m.Description) ? m.Description : m.Name,
                                    name: m.Name, 
                                };
                            })
                        );

                        that.set({ categories: _.sortBy(categories, 'description'), });
                    }
                },
                Async: false,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
    });

    //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.
            return "delays-by-date"; 
        } catch (Error) { }
    }

    Screen.Models.TimeAccount = Backbone.Model.extend({
        defaults: {
            date: null,
            totalDuration: null,
        },
        idAttribute: 'date',
    });

    Screen.Collections.TimeAccounts = Backbone.Collection.extend({
        model: Screen.Models.TimeAccount,
        currentPage: 1,
        fixedParameters: [],
        isFetching: false,
        pageSize: 50,
        transaction_timestamp: null,
        comparator: function (a, b) {
            //Check date
            var valA = new moment(a.get('date'), 'YYYY-MM-DD').toDate(),
                valB = new moment(b.get('date'), 'YYYY-MM-DD').toDate();

            if (valA < valB)
                return -1 * -1;
            else if (valA > valB)
                return 1 * -1;

            //Equals
            return 0;
        },

        initialize: function () {
            this.refreshCount = 0;
            this.totalDuration = 0; 
        },
        //comparator: function (a, b) {            
        //    if (a.get("duration") > b.get("duration") && !a.get("isTotal")) return -1;
        //    else if (a.get("duration") < b.get("duration")) return 1;
        //    else return 0; 
        //}, 
        fetch: function (opt) {
            var that = this; 
            var options = {
                async: true,
                callback: null,
                params: [],
            };
            var qp = new Core.Database.QueryParameters();
            var ttimestamp = this.transaction_timestamp = new Date().getTime();

            options = _.extend(options, (opt) ? opt : {});


            this.isFetching = true;

            if (opt.reset)
                this.resetPagination(true);

            if ((opt.refresh) || (opt.reset)) {
                this.fixedParameters = [];

                _.each(options.params, function (param) {
                    that.fixedParameters.push({ name: param.Name, value: param.Value, type: param.Type, });
                });
            }


            _.each(this.fixedParameters, function (qpParams) {
                qp.Add(qpParams.name, qpParams.type, qpParams.value);
            });

            if (opt.refresh) {
                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', this.currentPage * this.pageSize);
            }
            else if (opt.reset) {
                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', this.pageSize);
            }
            else {
                qp.Add('@fromRow', 'INT', (this.currentPage - 1) * this.pageSize);
                qp.Add('@rowsToFetch', 'INT', this.pageSize);
            }

            qp.Add("Timezone", "CHAR", app.models.user.get("timezoneCode"));

            var newColl = [];

            Core.Json.CallProcedure(
                app.DatabaseNames.IHDelays + ".WebApp.GetDelaysTimeSummaryByDateAndCodeGroup",
                qp,
                {
                    onSuccess: function (data) {
                        try {
                            var timeAccountsData = data.Table;

                            var dates = _.uniq(_.pluck(timeAccountsData, 'Date'));

                            _.each(dates, function (date) {
                                var dateData = {
                                    date: date,
                                    totalDuration: 0,
                                };

                                var dateRecords = _.where(timeAccountsData, { Date: date, });
                                    
                                _.each(dateRecords, function (itemData) {
                                    dateData.totalDuration += itemData.Duration;

                                    itemData.Category in dateData ? dateData[itemData.Category] += itemData.Duration : dateData[itemData.Category] = itemData.Duration;
                                    ;
                                });

                                newColl.push(dateData);
                            });

                            var totalDuration = _.reduce(newColl, function (memo, m) {
                                return memo + m.duration; 
                            }, 0);

                            //timeAccountItems.sort(function (a, b) {
                            //    if (a["duration"] > b["duration"] && !a["isTotal"]) return -1;
                            //    else if (a["duration"] < b["duration"]) return 1;
                            //    else return 0; 
                            //}); 

                            //timeAccountItems.push({
                            //    id: -2,
                            //    code: 'Total',
                            //    category: '',
                            //    description: '',
                            //    color: '',
                            //    duration: totalDuration,
                            //    isTotal: true,
                            //    lastUpdate: ++that.refreshCount,
                            //});

                            //var totalDuration_prev = that.totalDuration;
                            //that.totalDuration = totalDuration;

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

                            that[method](newColl, { from: "fetch" });

                            //if (that.totalDuration != totalDuration_prev)
                            //    that.trigger("totalDurationChanged", this);

                            if (newColl.length == 0 && method == 'add')
                                that.currentPage--;

                            that.isFetching = false;

                            if (options.callback != null && _.isFunction(options.callback))
                                options.callback.call(this, that);
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    },
                    onError: function () {
                        if (options.callback != null && _.isFunction(options.callback))
                            options.callback.call(this, that);
                    }, 
                    Async: options.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        getNextPage: function (options) {
            if (!this.isFetching) {
                this.currentPage++;
                options = (_.isObject(options)) ? options : {};
                this.fetch(options);
            }
        },
        parseResponse: function (resp, opt) {
            if ((resp) && (resp.Table)) {
                var records = resp.Table,
                    newColl;

                newColl = _.map(records, this.model.prototype.parse);

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

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

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

                return true;
            }

            return false;
        },
        resetPagination: function (force) {
            if (!this.isFetching || force == true) {
                this.currentPage = 1;
            } else {
                _.delay(this.resetPagination, 100);
            }
        },
    });

    Screen.Views.Main = Backbone.View.extend({
        template: "delays-by-date"
        , id: "delays-by-date"
        , title: ""
        //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
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            if (this.options.viewParams) {
            }

            this.options.autorefresh = {
                enabled: true
                , toid: null
            }; 

            this.options.delaysTimeSummaryGrid = {
                grid: null,
                model: null, 
            }; 

            var model = new Screen.Models.Main({
            });

            this.model = model;

            this.options.subviews = {}; 

            this.options.subviews.subnavbarControls = new Screen.Views.SubnavBarControls({
                parent: this
                , model: new Screen.Models.SubnavBarControls()
                , container: app.views.subnavbar.getSectionContainer(1, 12)
            });

            this.options.subviews.subnavbarControls.render();

            this.model.fetchCategories();

            this.bindEvents();
            _.bindAll(this);
        },

        events: {
        }, 

        render: function (container) {
            var that = this;
            var thatContainer = (container != null && container != undefined) ? container : this.options.container;
            this.options.MYREFERENCES = {};

            //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/delays/delays-by-date/";

            T.render.call(this, this.template, function (tmp) {
                if (!that.options.i18n) that.options.i18n = {};
                app.getI18NJed(that, that.template, function (i18nJED) {
                    //storing internationalization data
                    that.options.i18n[that.template] = i18nJED;
                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)

                    //end:

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

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

                    //end

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

                    that.drawDelaysTimeSummary(); 

                    that._startAutoRefresh({ showLoading: true, reset: true, });
                }, true, customPath); 
            }, customPath, "main_template");
        }

        , drawDelaysTimeSummary: function () {
            var that = this;

            //var modelTotal = that.model.get("timeAccounts").findWhere({ isTotal: true, });
            //var opt = {
            //    total: (modelTotal) ? modelTotal.get("duration") : that.model.get("timeAccounts").reduce(function (memo, m) {
            //        return ((!m.get("isTotal")) ? m.get("duration") : 0) + memo;
            //    }, 0), 
            //};
            var opt = { total: 0, }; 
            opt.total = that.model.get("timeAccounts").totalDuration;

            //timeAccounts.forEach(function (m) { opt.total += m.get("duration"); });
            //timeAccounts.add({ name: "Staffed Time", duration: opt.total, color: '#ccc' }); 

            var grid = new Backgrid.Grid({
                className: "backgrid table table-hover table-condensed",
                columns: [].concat(
                    [{
                        name: "date",
                        label: app.translate(that, "date_label"),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: "string-cell align-center date",
                        })
                    }],
                    _.map(that.model.get('categories'), function (obj) {
                        return {
                            name: obj.name,
                            label: obj.name,
                            editable: false,
                            sortable: false,
                            cell: Screen.Views.DurationCell,
                        };
                    }),
                    [{
                        name: "totalDuration",
                        label: app.translate(that, "total_duration_label"),
                        editable: false,
                        sortable: false,
                        cell: Screen.Views.DurationCell,
                    },
                    {
                        name: "graph",
                        label: app.translate(that, "graph_label"),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell.extend({
                            template: _.template("<div style='height:20px;width:200px;position:relative;' class='bar-graph-container'></div>"),
                            orderSeparator: '',
                            className: "string-cell",
                            initialize: function () {
                                _.bindAll(this);
                                Backgrid.StringCell.prototype.initialize.apply(this, arguments);

                                this.options.graph = {
                                    pbar: null,
                                };

                                this.bindEvents();
                            },
                            render: function () {
                                //var modelTotal = that.model.get("timeAccounts").findWhere({ isTotal: true, });
                                //opt.total = (modelTotal) ? modelTotal.get("duration") : that.model.get("timeAccounts").reduce(function (memo, m) {
                                //    return ((!m.get("isTotal")) ? m.get("duration") : 0) + memo;
                                //}, 0);

                                opt.total = this.model.get('totalDuration'); 

                                this.$el.html(this.template());
                                var pbar_container = this.$el.find(".bar-graph-container");

                                var that2 = this,
                                    i = 0;

                                this.options.graph.pbar = [];

                                _.each(that.model.get('categories'), function (category) {
                                    var val = that2.model.get(category.name);

                                    if (val) {
                                        var pbar = new ProgressBar.Line(pbar_container.get(0), {
                                            color: category.color,
                                            trailColor: 'transparent',
                                            easing: 'easeInOut',
                                            step: function (state, bar) {
                                            }
                                        });

                                        that2.options.graph.pbar.push(pbar);

                                        var percent = (opt.total != 0) ? (that._getPercent(val, opt) * 100) : 0;

                                        $(pbar_container.find("svg")[i]).css({
                                            height: "20px",
                                            width: percent + "%",
                                            "overflow-y": "hidden",
                                            "float": "left",
                                        });

                                        i++;

                                        setTimeout(function () {
                                            pbar.animate(1);
                                        }, 1000);
                                    }
                                });

                                this.delegateEvents();
                                return this;
                            },
                            refresh: function () {
                                //var modelTotal = that.model.get("timeAccounts").findWhere({ isTotal: true, });
                                //opt.total = (modelTotal) ? modelTotal.get("duration") : that.model.get("timeAccounts").reduce(function (memo, m) {
                                //    return ((!m.get("isTotal")) ? m.get("duration") : 0) + memo;
                                //}, 0);

                                opt.total = this.model.get('totalDuration');

                                
                                var that2 = this,
                                    i = 0;
                                var graphList = this.$el.find(".bar-graph-container").find("svg");

                                _.each(that.model.get('categories'), function (category) {
                                    var val = that2.model.get(category.name);

                                    if (val) {
                                        var percent = (opt.total != 0) ? (that._getPercent(val, opt) * 100) : 0;

                                        $(graphList[i]).css({
                                            width: percent + "%",
                                        });

                                        that2.options.graph.pbar[i].animate(1);

                                        i++;
                                    }
                                });
                            },
                            bindEvents: function () {
                                this.listenTo(this.model, "change", _.debounce(_.bind(this.refresh, this), 500));
                            },
                        })
                    }]
                ),
                collection: this.model.get("timeAccounts"),
                footer: Backgrid.Extension.Infinator.extend({
                    scrollToTop: false,
                }),
            });

            this.options.delaysTimeSummaryGrid.grid = grid;

            this.$el.find(".time-summary-grid-container").append(grid.render().el);
        }

        , _getPercent: function (val, opt) {
            var p = (((val * 100) / opt.total) / 100); 
            var final = Math.floor(p * 100) / 100;

            return (final == 0 && p != 0 && (opt && opt.displayMinimum)) ? 0.01 : final; 
        }

        , 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;
            }
        }
        , refresh: function (opt) {
            try {
                var that = this;

                var lineId = this.options.subviews.subnavbarControls.model.get("lineProductionItemId");
                var machineId = this.options.subviews.subnavbarControls.model.get("machineProductionItemId");
                var productionItemIdFilter = (lineId != -1) ? (machineId != -1) ? machineId : lineId : (machineId != -1) ? machineId : null;

                var from = this.options.subviews.subnavbarControls.model.get("from");
                var to = this.options.subviews.subnavbarControls.model.get("to"); 

                var productId = this.options.subviews.subnavbarControls.model.get("productId");
                productId = (productId != -1) ? productId : null; 

                var shiftId = this.options.subviews.subnavbarControls.model.get("shiftId");
                shiftId = (shiftId != -1) ? shiftId : null; 

                var fromMoment = moment(from);
                var toMoment = moment(to); 
                toMoment.add(1, "d"); 

                this.model.get("timeAccounts").fetch({
                    refresh: opt.refresh,
                    reset: opt.reset,
                    params: [
                        { Name: "From", Type: "DATETIME", Value: fromMoment.format("YYYY-MM-DD HH:mm:ss") },
                        { Name: "To", Type: "DATETIME", Value: toMoment.format("YYYY-MM-DD HH:mm:ss") },
                        { Name: "ProductionItemId", Type: "INT", Value: productionItemIdFilter },
                        { Name: "ProductId", Type: "INT", Value: productId },
                        { Name: "ShiftId", Type: "INT", Value: shiftId },
                    ],
                    callback: function () {
                        if (opt && opt.callback && _.isFunction(opt.callback))
                            opt.callback.call(that, that);
                    },
                });

            } catch (Error) { }
        }
        , _startAutoRefresh: function (opt) {
            try {
                if (this.options.autorefresh.toid != null) {
                    clearTimeout(this.options.autorefresh.toid);
                    this.options.autorefresh.toid = null;
                }

                this.options.autorefresh.enabled = true;

                this._autoRefresh(opt);
            } catch (Error) { }
        }
        , _autoRefresh: function (opt) {
            var that = this;
            var fetched = false;

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

            if (opt && opt.showLoading) {
                setTimeout(function () {
                    if (!fetched) that.showLoading(true);
                }, 1);
            }

            this.refresh(_.extend({}, opt, {
                callback: function () {
                    fetched = true;
                    that.showLoading(false);

                    if (that.options.autorefresh.enabled == true) {
                        that.options.autorefresh.toid = setTimeout(that._autoRefresh, 5000);
                    }

                    if (opt && opt.callback && _.isFunction(opt.callback))
                        opt.callback.call(that, that);
                },
            }));
        }
        , showLoading: function (val) {
            var loadingPoster = this.$el.find(".loading-poster");
            var mainContent = this.$el.find(".main-content");

            if (val) {
                mainContent.addClass("hide");
                loadingPoster.removeClass("hide");
            } else {
                loadingPoster.addClass("hide");
                mainContent.removeClass("hide");
            }
        }
        , _stopAutoRefresh: function () {
            if (this.options.autorefresh.toid != null) {
                clearTimeout(this.options.autorefresh.toid);
                this.options.autorefresh.toid = null;
            }
            this.options.autorefresh.enabled = false;
        }
        , filtersChanged: _.debounce(function (a, b, c) {
            this._autoRefresh({ showLoading: true, reset: true, });
        }, 500)
        , bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:from", this.filtersChanged);
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:to", this.filtersChanged);
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:lineProductionItemId", this.filtersChanged);
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:machineProductionItemId", this.filtersChanged);
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:productId", this.filtersChanged);
            this.listenTo(this.options.subviews.subnavbarControls.model, "change:shiftId", this.filtersChanged);
        }

        , bindViewScopedEvents: function () {
            var that = this;
        }

        , unbindViewScopedEvents: function () {
            this._stopAutoRefresh(); 
        }

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

            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        }

        , closeSubviews: function () {
            _.each(this.options.subviews, function (sview) {
                sview.close();
            });
        }

        , show: function () {
            this.options.state = app.view_states.shown;

            this.showSubviews();
            this.bindEvents();
            this.$el.show();
        }

        , showSubviews: function () {
            _.each(this.options.subviews, function (sview) {
                sview.show();
            });
        }

        , hide: function () {
            this.options.state = app.view_states.hidden;

            this.hideSubviews();
            this._stopAutoRefresh();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        }

        , hideSubviews: function () {
            _.each(this.options.subviews, function (sview) {
                sview.hide();
            });
        }

        , preRender: function () {
            app.models.subnavbar.setAll(false);
            app.models.subnavbar.set("subnavbar", true);
            app.models.subnavbar.set("sections", "12");
        }

        , reRender: function () {
        }
    });

    Screen.Models.SubnavBarControls = Backbone.Epoxy.Model.extend({
        defaults: {
            from: null,
            to: null,

            lineProductionItemId: -1,
            machineProductionItemId: -1,
            productId: -1,
            shiftId: -1, 

            lines: [],
            machinesInternal: [],
            products: [],
            shifts: [], 
        },
        computeds: {
            machines: {
                deps: ["lineProductionItemId"],
                get: function () {
                    var line = this.get("lineProductionItemId");
                    var machines = this.get("machinesInternal");

                    return _.map(_.filter(machines, function (m) {
                        if (line != -1) return m.ParentId == line;
                        else return true;
                    }), function (m) {
                        return { value: m.Id, label: m.Name, };
                    });
                },
            }
        },
        initialize: function () {
            var from = moment();
            var to = moment(from);
            //var to = moment(from).add("d", 1); 

            this.set({
                from: from.format("YYYY-MM-DD"),
                to: to.format("YYYY-MM-DD"),
            }, { silent: true });

            this.fetchLinesMachines();
            this.fetchProducts();
            this.fetchShifts(); 
        },        
        fetchLinesMachines: function () {
            var that = this;
            Core.Json.CallProcedure(app.DatabaseNames.IHDelays + ".WebApp.GetProductionItems", null, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var items = data.Table;

                        that.set({
                            lines: _.map(_.filter(items, function (m) { return m.ProductionItemType.toUpperCase() == "LINE"; }), function (m) {
                                return { value: m.Id, label: m.Name, };
                            }),
                            machinesInternal: _.filter(items, function (m) { return m.ProductionItemType.toUpperCase() == "MACHINE"; }),
                        });
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        fetchProducts: function () {
            var that = this;
            Core.Json.CallProcedure(app.DatabaseNames.IHDelays + ".WebApp.GetProducts", null, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var items = data.Table;

                        that.set({
                            products: _.map(items, function (m) {
                                return { value: m.Id, label: m.Name, };
                            }),
                        });
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        fetchShifts: function () {
            var that = this;
            Core.Json.CallProcedure(app.DatabaseNames.IHDelays + ".WebApp.GetShifts", null, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var items = data.Table;

                        that.set({
                            shifts: _.map(items, function (m) {
                                return { value: m.Id, label: m.Name, };
                            }),
                        });
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
    });

    //subview for the subnavbar controls
    Screen.Views.SubnavBarControls = Backbone.Epoxy.View.extend({
        id: "delays-by-date-subnavbar-controls"
        , title: ""
        , template: "delays-by-date"
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };
            if (this.options.viewParams) {
            }

            this.options.MYREFERENCES = {};

            this.options.viewModels = {
                fromDateControl: new DateControl.Model({
                    date: this.model.get("from"),
                }),
                toDateControl: new DateControl.Model({
                    date: this.model.get("to"),
                }),
            };

            this.bindEvents();
            //_.bindAll(this);
        },

        events: {
        },

        render: function (container, onComplete) {
            var that = this;
            var thatContainer = (container) ? container : (this.options.container) ? this.options.container : null;
            var onViewComplete = (onComplete) ? onComplete : function () { };

            //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/delays/delays-by-date/";

            T.render.call(this, this.template, function (tmp) {
                if (!that.options.i18n) that.options.i18n = {};
                app.getI18NJed(that, that.template, function (i18nJED) {
                    //storing internationalization data
                    that.options.i18n[that.template] = i18nJED;

                    //loading the view and appeding it to the views's $el.
                    that.$el.html(tmp({
                        showProductSelect: false, 
                    }));
                    that.applyBindings();

                    var dc = new DateControl.Views.Main({ model: that.options.viewModels.fromDateControl });
                    dc.render(that.$el.find(".from-date-control-container"));

                    var dc = new DateControl.Views.Main({ model: that.options.viewModels.toDateControl });
                    dc.render(that.$el.find(".to-date-control-container"));

                    that.append(thatContainer, that.$el);
                    that.referencesChart();
                }, true, customPath);
            }, customPath, "subnavbar_controls");
        }

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

        , refresh: function () {
            try {

            } catch (Error) { }
        }

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

            this.listenTo(this.options.viewModels.fromDateControl, "change:date", this.fromToModelChanged);
            this.listenTo(this.options.viewModels.toDateControl, "change:date", this.fromToModelChanged);
        }

        , fromToModelChanged: function (a, b, c) {
            this.model.set({
                from: this.options.viewModels.fromDateControl.get("date"),
                to: this.options.viewModels.toDateControl.get("date"),
            });
        }

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

            this.remove();
            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();
        }

        , reRender: function () {
        }
        , referencesChart: function () {
            var svgCategories = d3.select("#refs-screen-categories").append("svg").attr("width", 670).attr("height", 45)
            var categories = this.options.parent.model.get('categories').sort((a, b) => a.name.localeCompare(b.name));
            var xRect = 2;
            var xText = 0;
            _.each(categories, function (param) {
                if (param.name == 'NOTDECLARED') {
                     param.name = 'N/D'
                }
                svgCategories.append('rect')
                    .attr('x', xRect)
                    .attr('y', 0)
                    .attr('width', 15)
                    .attr('height', 15)
                    .attr('stroke', 'rgb(80, 80, 80)')
                    .attr('fill', param.color);

                svgCategories.append("text")
                    .attr('y', 25)
                    .attr("x", xText)
                    .attr("font-size", 10)
                    .attr("fill", "#505050")
                    .attr("font-family", "Helvetica Neue,Helvetica,Arial,sans-serif")
                    .text(param.name);

                xRect = xRect + 55;
                xText = xText + 55;
            });
            
        },
    });

    Screen.Views.DurationCell = Backgrid.StringCell.extend({
        orderSeparator: '',
        className: "string-cell align-center",
        render: function () {
            var value = this.model.get(this.column.get('name'));
            if (value != undefined) {
                this.$el.html(this.secondsToHHMMSS((value) ? value : 0));
            }
            else {
                this.$el.html("");
            }
            
            this.delegateEvents();
            return this;
            
        },
        secondsToHHMMSS: function (d) {
            d = Number(d);
            var h = Math.floor(d / 3600);
            var m = Math.floor(d % 3600 / 60);
            var s = Math.floor(d % 3600 % 60);
            return ((h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s);
        },
    });

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

});
