/// <reference path="http://localhost:65492/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />
//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",

  "modules/modal",

  "backgrid",

  "modules/dateTimeControl",
  "modules/dateControl",

  "moment",

  "backgrid/infinator",
],

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

    function isNull(val1, val2) {
        return (val1) ? val1 : val2;
    }

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

    OEEReport.Models.Main = Backbone.Model.extend({
        defaults: {
            cuberows: null,

            areas: [],
        },
        initialize: function (a, b) {
            this.options = _.extend({}, this.options, b);

            this.attributes.cuberows = new OEEReport.Collections.CubeRows(null, {
                parent: 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.
    OEEReport.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "oee-report";
        } catch (Error) { }
    };

    OEEReport.Models.CubeRow = Backbone.Model.extend({
        defaults: {
            //dimensions
            //year: null,
            //month: null,
            //date: null,
            //shift: null,
            //batch: null,
            //product: null,
            //productionItem: null,
            time: null,
            shift: null,
            product: null,
            machine: null,
            line: null,
            area: null,


            //measures
            oee: null,
            availability: null,
            quality: null,
            performance: null,
            conflicted: null,
        },
    });

    OEEReport.Collections.CubeRows = Backbone.Collection.extend({
        model: OEEReport.Models.CubeRow,

        fixedParameters: {},
        isFetching: false,
        currentPage: 1,
        pageSize: 50,

        initialize: function (a, b, c) {
            this.options = _.extend({}, this.options, b);
            _.bindAll(this);
        },
        fetch: function (params) {
            var that = this;

            var ttimestamp = this.transaction_timestamp = new Date().getTime(),
                options = {
                    params: {},
                    callback: null,
                    refresh: false,
                    set: false,
                    internalAreaText: 'None',
                };

            options = _.extend(options, params);

            this.isFetching = true;

            if (options.refresh) {
                this.resetPagination(true);

                this.fixedParameters = {
                    groupBy: options.groupBy,
                    filterBy: options.filterBy,
                };
            }

            if (!options.refresh && !options.set) {
                fromRow = (this.currentPage - 1) * this.pageSize;
                rowsToFetch = this.pageSize;
            } else {
                fromRow = 0;
                rowsToFetch = this.currentPage * this.pageSize;
            }

            var customPath = "/app/custom-screens/modules/OEE/oee-report/";
            $.ajax(app.foldersRoot + customPath + "cube-api/cube-api.aspx", {
                type: 'POST',
                data: {
                    groupby: JSON.stringify(that.fixedParameters.groupBy),
                    filterby: JSON.stringify(that.fixedParameters.filterBy),
                    rowsStartIndex: fromRow,
                    rowsCount: rowsToFetch,
                },
                dataType: "json",
                success: function (data) {
                    if (data && data.Status != "FAILED") {
                        var items = [];

                        for (var i = 0; i < data.length; i++) {
                            var itemData = data[i];
                            var itemDataN = {};
                            _.each(itemData, function (value, key) {
                                key = key.replace("[Measures].", "").replace(".[MEMBER_CAPTION]", "");
                                key = key.split("[").join("").split("]").join("").split(" ").join("");
                                itemDataN[key] = value;
                            });
                            itemData = itemDataN;

                            var item = {
                                time: (itemData["Time.Year.Year"])
                                            ? moment(itemData["Time.Year.Year"], 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY') :
                                        (itemData["Time.Month.Month"])
                                            ? moment(itemData["Time.Month.Month"], 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM') :
                                        (itemData["Time.Week.Week"])
                                            ? moment(itemData["Time.Week.Week"], 'YYYY-MM-DD HH:mm:ss.SSS').format('YYYY-MM-DD') :
                                        itemData["Time.Date.Date"],
                                area: isNull(
                                    (itemData["ProductionItems.ParentId.Level02"] != '')
                                        ? itemData["ProductionItems.ParentId.Level02"]
                                        : options.internalAreaText,
                                    ''
                                ),
                                line: isNull(itemData["ProductionItems.ParentId.Level03"], ''),
                                machine: isNull(itemData["ProductionItems.ParentId.Level04"], ''),
                                product: isNull(itemData["Products.Id.Id"], ''),
                                shift: isNull(itemData["Shifts.Id.Id"], ''),

                                oee: itemData.OEE,
                                availability: itemData.Availability,
                                performance: itemData.Performance,
                                quality: itemData.Quality,
                                conflicted: (itemData.Conflicted > 0),
                            };


                            items.push(item);
                        }


                        if (ttimestamp == that.transaction_timestamp) {
                            var method = (options.set) ? 'set' : 'add';
                            method = (options.method) ? options.method : method;

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

                            //decreasing page since we couldn't get any data on this page.
                            if (items.length == 0 && method == 'add')
                                that.currentPage--;

                            that.isFetching = false;

                            //if (options && options.callback && _.isFunction(options.callback))
                            //    options.callback.call(that, that, data);
                        }
                    }

                    if (options.callback != null && _.isFunction(options.callback))
                        options.callback.call(this, that, data);
                },
                error: function (e) {
                    if (options && options.callback && _.isFunction(options.callback))
                        options.callback.call(that, that, data);
                    console.log("Failed when trying to get data from cube-api");
                }
            });
        },
        getNextPage: function (options) {
            if (!this.isFetching) {
                this.currentPage++;
                options = (_.isObject(options)) ? options : {};
                this.fetch(options);
            }
        },
        resetPagination: function (force) {
            if (!this.isFetching || force == true) {
                this.currentPage = 1;
            } else {
                _.delay(this.resetPagination, 100);
            }
        },
    });

    OEEReport.Views.Main = Backbone.View.extend({
        template: "oee-report"
        , id: "oee-report"
        , title: "OEEReport"
        //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) {
            }

            var model = new OEEReport.Models.Main(null, {
                parent: this,
            });

            this.options.MYREFERENCES = {
                subviews: {
                }
                , autoRefresh: {
                    enabled: true
                    , toid: null
                }
            };

            this.options.grids = {
                oeeReport_grid: null,
            };

            this.options.firstTime = true;

            this.model = model;

            this.options.MYREFERENCES.subviews.subnavbarControls = new OEEReport.Views.SubnavBarControls({
                parent: this
                , model: new OEEReport.Models.SubnavBarControls()
                , container: app.views.subnavbar.getSectionContainer(1, 12)
                , events: _.extend(OEEReport.Views.SubnavBarControls.prototype.events, {
                    'click .btn-refresh': _.bind(this.refreshResults, this),
                })
                , onExportToExcel: _.bind(this.exportToExcel, this)
            });

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

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

        events: {
        },

        render: function (container) {
            var that = this;
            var thatContainer = (container != null && container != undefined) ? container : this.options.container;
            //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/modules/OEE/oee-report/";

            var percentFormatter = _.extend({}, Backgrid.StringFormatter.prototype, {
                fromRaw: function (rawValue, model) {
                    return (_.isNumber(rawValue)) ? rawValue.toFixed(0) + ' %' : '-';
                }
            });

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

                    //var render_when_null_all = function () {
                    //    Backgrid.StringCell.prototype.render.apply(this, arguments);
                    //    if (!this.model.get(this.column.get('name'))) this.$el.html(app.translate(that, 'all_label'));
                    //    return this;
                    //};


                    var columns = [
                        {
                            name: 'time',
                            label: app.translate(that, 'time_label'),
                            //cubeColumnName: '[Time].[Date].[Date].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'area',
                            label: app.translate(that, 'area_label'),
                            cubeColumnName: '[Production Items].[Parent Id].[Level 02].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'line',
                            label: app.translate(that, 'line_label'),
                            cubeColumnName: '[Production Items].[Parent Id].[Level 03].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'machine',
                            label: app.translate(that, 'machine_label'),
                            cubeColumnName: '[Production Items].[Parent Id].[Level 04].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'product',
                            label: app.translate(that, 'product_label'),
                            cubeColumnName: '[Products].[Id].[Id].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'shift',
                            label: app.translate(that, 'shift_label'),
                            cubeColumnName: '[Shifts].[Id].[Id].[MEMBER_CAPTION]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            })
                        },
                        {
                            name: 'oee',
                            label: app.translate(that, 'oee_label'),
                            cubeColumnName: '[Measures].[OEE]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                                formatter: percentFormatter,
                            })
                        },
                        {
                            name: 'availability',
                            label: app.translate(that, 'availability_label'),
                            cubeColumnName: '[Measures].[Availability]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                                formatter: percentFormatter,
                            })
                        },
                        {
                            name: 'performance',
                            label: app.translate(that, 'performance_label'),
                            cubeColumnName: '[Measures].[Performance]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                                formatter: percentFormatter,
                            })
                        },
                        {
                            name: 'quality',
                            label: app.translate(that, 'quality_label'),
                            cubeColumnName: '[Measures].[Quality]',
                            editable: false,
                            sortable: false,
                            exportable: true,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                                formatter: percentFormatter,
                            })
                        },
                        {
                            name: 'conflicted',
                            label: '',
                            editable: false,
                            sortable: false,
                            exportable: false,
                            cell: Backgrid.Cell.extend({
                                template: _.template(''),
                                initialize: function () {
                                    Backgrid.Cell.prototype.initialize.apply(this, arguments);
                                },
                                render: function () {
                                    var conflictTemplate = _.template('<span title="Item conflicted" style="color:red;"><i class="fa fa-circle" aria-hidden="true"></i></span>')

                                    if (this.model.get('conflicted')) {
                                        this.template = conflictTemplate;
                                    }

                                    this.$el.html(this.template());
                                    this.delegateEvents();
                                    return this;
                                },
                            })
                        },
                    ];

                    // Initialize a new Grid instance
                    var oeeReport_grid;
                    oeeReport_grid = that.options.grids.oeeReport_grid = new Backgrid.Grid({
                        className: 'backgrid table table-hover',
                        columns: columns,
                        collection: that.model.get('cuberows'),
                        footer: Backgrid.Extension.Infinator.extend({
                            scrollToTop: false,
                        }),
                    });

                    that.redrawGrid();

                    that.$el.find('.oee-report-grid-container').append(oeeReport_grid.render().el);

                    that.showLoading(true);
                    that.append(thatContainer, that.$el);
                    //that._startAutoRefresh({});
                    that.refresh();
                }, true, customPath);
            }, customPath, 'main_template');
        }
        , refreshResults: function () {
            this.refresh();
        }
        , _startAutoRefresh: function (opt) {
            try {
                if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                    clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                    this.options.MYREFERENCES.autoRefresh.toid = null;
                }

                this.options.MYREFERENCES.autoRefresh.enabled = true;

                this._autoRefresh(opt);
            } catch (Error) { }
        }
        , _autoRefresh: function (opt) {
            var that = this;
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }

            this.refresh(_.extend({}, opt, {
                callback: function () {
                    if (that.options.MYREFERENCES.autoRefresh.enabled == true) {
                        that.options.MYREFERENCES.autoRefresh.toid = setTimeout(that._autoRefresh, 5000);
                    }
                },
            }));
        }
        , _stopAutoRefresh: function () {
            if (this.options.MYREFERENCES.autoRefresh.toid != null) {
                clearTimeout(this.options.MYREFERENCES.autoRefresh.toid);
                this.options.MYREFERENCES.autoRefresh.toid = null;
            }
            this.options.MYREFERENCES.autoRefresh.enabled = false;
        }
        , refresh: function (opt) {
            try {
                var that = this;

                var snb = that.options.MYREFERENCES.subviews.subnavbarControls.model;
                var snbe = that.options.MYREFERENCES.subviews.subnavbarControls.$el;
                opt = _.extend({}, opt, {
                    groupBy: snb.get("groupBy"),
                    filterBy: {},
                });

                var anyFilters = false;
                snbe.find("[data-cube-filter]").each(function (i, e) {
                    anyFilters = true;
                    var elem = $(e);
                    var type = elem.data("cube-filter").toUpperCase();
                    var name = elem.data("cube-filter-name");
                    var propName = elem.data("cube-filter-prop-name");
                    var query = elem.data("cube-filter-query");

                    var values = [];
                    if (type == "DATE") {
                        var dateMoment = new moment(snb.get(propName), "YYYY-MM-DD HH:mm:ss");
                        values = [dateMoment.format("YYYY-MM-DD")];
                        if (!opt.filterBy[query]) {
                            opt.filterBy[query] = {
                                Type: type,
                                Values: values,
                                Name: "date",
                            };
                        } else {
                            opt.filterBy[query].Values.push(values[0]);
                        }
                    }
                    else {
                        values = [snb.get(propName)];
                        if (values[0] != -1) {
                            opt.filterBy[query] = {
                                Type: (type) ? type : 'DEFAULT',
                                Values: values,
                                Name: name,
                            };
                        }
                    }
                });

                if (anyFilters) {
                    that.showLoading(true);
                    that.redrawGrid();

                    that.model.get("cuberows").fetch(_.extend(opt, {
                        refresh: true,
                        set: true,
                        callback: function (a, b) {
                            that.grayResults(false);
                            if (b.Status == "FAILED") {
                                that.grayResults(true);
                                app.views.topMessages.showMessage(app.translate(that, b.Message + "_MESSAGE"));
                            }
                            that.showLoading(false);
                        },
                        internalAreaText: app.translate(that, "internal_area_text"),
                    }));
                }
            } catch (Error) { }
        }
        , exportToExcel: function (e) {
            try {
                this.options.MYREFERENCES.subviews.subnavbarControls.setExportButtonExporting(true);

                var that = this;
                var grid = this.options.grids.oeeReport_grid;
                var grid_columns = grid.columns;
                var exportableColumns = grid_columns.where({ renderable: true, exportable: true, });
                var customPath = "/app/custom-screens/modules/OEE/oee-report/";
                var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
                    chari = 0,
                    chari2 = 0;


                var snb = that.options.MYREFERENCES.subviews.subnavbarControls.model;
                var snbe = that.options.MYREFERENCES.subviews.subnavbarControls.$el;
                var opt = {
                    groupBy: snb.get("groupBy"),
                    filterBy: {},
                };

                var anyFilters = false;
                snbe.find("[data-cube-filter]").each(function (i, e) {
                    anyFilters = true;
                    var elem = $(e);
                    var type = elem.data("cube-filter").toUpperCase();
                    var name = elem.data("cube-filter-name");
                    var propName = elem.data("cube-filter-prop-name");
                    var query = elem.data("cube-filter-query");

                    var values = [];
                    if (type == "DATE") {
                        var dateMoment = new moment(snb.get(propName), "YYYY-MM-DD HH:mm:ss");
                        values = [dateMoment.format("YYYY-MM-DD")];
                        if (!opt.filterBy[query]) {
                            opt.filterBy[query] = {
                                Type: type,
                                Values: values,
                                Name: "date",
                            };
                        } else {
                            opt.filterBy[query].Values.push(values[0]);
                        }
                    }
                    else {
                        values = [snb.get(propName)];
                        if (values[0] != -1) {
                            opt.filterBy[query] = {
                                Type: (type) ? type : 'DEFAULT',
                                Values: values,
                                Name: name,
                            };
                        }
                    }
                });

                
                $.ajax(
                    app.foldersRoot + customPath + "cube-api/cube-api.aspx",
                    {
                        type: 'POST',
                        data: {
                            action: 'EXPORTEXCEL',

                            groupby: JSON.stringify(opt.groupBy),
                            filterby: JSON.stringify(opt.filterBy),
                            rowsStartIndex: 0,
                            rowsCount: 100000,

                            exportParams: JSON.stringify({
                                Data: [
                                    {
                                        SheetName: 'Data',
                                        RowsData: [{
                                            CellsData: _.map(exportableColumns, function (m) {
                                                return {
                                                    Column: chars[chari++],
                                                    Value: m.get('label'),
                                                };
                                            })
                                        }],
                                        StartRowIndex: 1,
                                    },
                                    {
                                        SheetName: 'Data',
                                        RowsData: [],
                                        StartRowIndex: 2,
                                        DataSourceName: 'data',
                                        DataSourceTableIndex: 0,
                                        CubeCellsData: _.map(exportableColumns, function (m) {
                                            var cubeColName;

                                            if (m.get('name') != 'time') {
                                                cubeColName = m.get('cubeColumnName')
                                            }
                                            else {
                                                if (_.indexOf(opt.groupBy, 'DATE') != -1)
                                                    cubeColName = '[Time].[Date].[Date].[MEMBER_CAPTION]';
                                                else if (_.indexOf(opt.groupBy, 'WEEK') != -1)
                                                    cubeColName = '[Time].[Week].[Week].[MEMBER_CAPTION]';
                                                else if (_.indexOf(opt.groupBy, 'MONTH') != -1)
                                                    cubeColName = '[Time].[Month].[Month].[MEMBER_CAPTION]';
                                                else if (_.indexOf(opt.groupBy, 'YEAR') != -1)
                                                    cubeColName = '[Time].[Year].[Year].[MEMBER_CAPTION]';
                                            }

                                            return { 
                                                ExcelColumnName: chars[chari2++],
                                                CubeDataColumnName: cubeColName, 
                                                DataType: 'String',
                                            };
                                        }),
                                    }
                                ],
                                //ExportMethod: 1,
                                FileName: 'oee-report',
                                TemplateFileFullPath: 'generic.xls',
                            }),
                        },
                        dataType: "json",
                        success: function (resp) {
                            try {
                                if ((resp) && (resp.Success == true) && (resp.Data)) {
                                    location.href = app.foldersRoot + '/excel/' + resp.Data;
                                }
                                else {
                                    if ((resp) && (resp.Message))
                                        console.error(resp.Message);
                                    else
                                        console.error('Server response not valid.');
                                }
                            }
                            catch (Error) { console.error(Error); }
                            that.options.MYREFERENCES.subviews.subnavbarControls.setExportButtonExporting(false);
                        },
                        error: function (resp) {
                            that.options.MYREFERENCES.subviews.subnavbarControls.setExportButtonExporting(false);
                            console.error(resp);
                        },
                    }
                );
            }
            catch (Error) { console.error(Error); }
        }
        , filtersChanged: _.debounce(function () {
            this.anyFilterChanged();
            //this.checkGroupBy();
        }, 300)
        , anyFilterChanged: function () {
            if (this.options.firstTime) {
                this.options.firstTime = false;
                this.refresh();
            } else {
                this.grayResults(true);
            }
        }
        , grayResults: function (v) {
            var grid = this.$el.find(".oee-report-grid-container");
            grid[(v) ? "addClass" : "removeClass"]("grayout");
            grid[(v) ? "removeClass" : "addClass"]("table-hover");
        }
        //, checkGroupBy: function () {
        //    var that = this;
        //    var snb = this.options.MYREFERENCES.subviews.subnavbarControls.model;
        //    var snbe = this.options.MYREFERENCES.subviews.subnavbarControls.$el;

        //    snbe.find("[data-group-by-filter-id]").each(function (i, e) {
        //        var elem = $(e);
        //        var groupByElem = snbe.find("#" + elem.data("group-by-filter-id"));
        //        //var value = parseInt(elem.val(), 10);
        //        var value = elem.val();

        //        var gb = _.clone(snb.get("groupBy"));
        //        if (value != '-1' && _.indexOf(gb, groupByElem.val()) == -1) {
        //            gb.push(groupByElem.val());
        //            snb.set("groupBy", gb);
        //        }
        //    });
        //}
        , groupByChanged: _.debounce(function () {
            var that = this;
            this.anyFilterChanged();
        }, 300)
        , redrawGrid: function () {
            var that = this;
            var gridContainer = that.$el.find(".oee-report-grid-container");
            var oeeReport_grid = that.options.grids.oeeReport_grid;
            var snb = that.options.MYREFERENCES.subviews.subnavbarControls.model;
            var groupBy = snb.get("groupBy");

            var columns = {
                area: function (groupBy) {
                    if (snb.get('areas').length <= 1)
                        return false;
                    else
                        return (_.intersection(groupBy, ['AREA', 'LINE', 'MACHINE']).length > 0);
                },
                date: ['YEAR', 'MONTH', 'DATE'],
                line: ['LINE', 'MACHINE'],
                machine: ['MACHINE'],
                product: ['PRODUCT'],
                shift: ['SHIFT'],
            };


            _.each(columns, function (v, k) {
                var renderable = false;

                if ($.isArray(v) == true) {
                    if (_.intersection(groupBy, v).length > 0) {
                        renderable = true;
                    }
                }
                else if ($.isFunction(v) == true) {
                    renderable = v(groupBy);
                }

                var column = _.first(oeeReport_grid.columns.where({ name: k }));
                if (column) { column.set("renderable", renderable); }
            });
        }
        , showLoading: function (v) {
            var loading = this.$el.find(".loading-poster");
            var grid = this.$el.find(".oee-report-grid-container");

            var class1 = "hide", class2 = "show";
            if (v) {
                class1 = "show";
                class2 = "hide";
            }

            grid.removeClass(class1).addClass(class2);
            loading.removeClass(class2).addClass(class1);
        }
        , 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;
            }
        }
        , 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
            var that = this;

            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:from", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:to", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:areaId", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:lineId", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:machineId", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:shiftId", this.filtersChanged);
            //this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:batchId", this.filtersChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:productId", this.filtersChanged);
            //this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:productionItemId", this.filtersChanged);
            //this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:othersGroupBy", this.groupByChanged);
            //this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:productionItemGroupBy", this.groupByChanged);
            //this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:timestampGroupBy", this.groupByChanged);
            this.listenTo(this.options.MYREFERENCES.subviews.subnavbarControls.model, "change:groupBy", this.groupByChanged);
        }
        , bindViewScopedEvents: function () {
            var that = this;
        }
        , unbindViewScopedEvents: function () {

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

            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        }
        , closeSubviews: function () {
            _.each(this.options.MYREFERENCES.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.MYREFERENCES.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.MYREFERENCES.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 () {
            //this._startAutoRefresh(); 
            this.refresh();
        }
    });

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

            shiftId: -1,
            areaId: -1,
            lineId: -1,
            machineId: -1,
            productId: -1,

            timestampGroupBy: 'DATE',
            productionItemGroupBy: 'MACHINE',
            othersGroupBy: ['PRODUCT', 'SHIFT', ],

            shifts: [],
            products: [],
            areas: [],
            lines: [],
            machines: [],

            showShiftIdSelect: true,
            showAreaIdSelect: true,
            showLineIdSelect: true,
            showMachineIdSelect: true,
            showProductIdSelect: true,
        },
        computeds: {
            groupBy: {
                deps: ['othersGroupBy', 'productionItemGroupBy', 'timestampGroupBy',],
                get: function (othersGroupBy, productionItemGroupBy, timestampGroupBy) {
                    return [].concat(
                        othersGroupBy,
                        [productionItemGroupBy],
                        [timestampGroupBy]
                    );
                },
            },
            lineId$: {
                deps: ['lineId', ],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    var result = { lineId: value, };

                    if ((value != -1) && (this.get('productionItemGroupBy') == 'AREA'))
                        result.productionItemGroupBy = 'LINE';

                    return result;
                }
            },
            linesFiltered: {
                deps: ['lines', 'areaId', ],
                get: function (lines, areaId) {
                    if (areaId != -1)
                        return _.where(lines, { parent: areaId, });
                    else
                        return lines;
                },
            },
            machineId$: {
                deps: ['machineId', ],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    var result = { machineId: value, };

                    if (value != -1)
                        result.productionItemGroupBy = 'MACHINE';

                    return result;
                }
            },
            machinesFiltered: {
                deps: ['machines', 'linesFiltered', 'lineId',],
                get: function (machines, linesFiltered, lineId) {
                    if (lineId != -1) {
                        return _.where(machines, { parent: lineId, });
                    }
                    else {
                        return _.filter(machines, function (obj) {
                            return (_.where(linesFiltered, { value: obj.parent, }).length > 0);
                        });
                    }
                },
            },
            productId$: {
                deps: ['productId', ],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    var result = { productId: value, };

                    if (value != -1) {
                        var groups = _.clone(this.get('othersGroupBy')),
                            groupValue = 'PRODUCT';

                        if (_.indexOf(groups, groupValue) == -1)
                            groups.push(groupValue);

                        result.othersGroupBy = groups;
                    }

                    return result;
                }
            },
            shiftId$: {
                deps: ['shiftId',],
                get: function (value) {
                    return value;
                },
                set: function (value) {
                    var result = { shiftId: value, };

                    if (value != -1) {
                        var groups = _.clone(this.get('othersGroupBy')),
                            groupValue = 'SHIFT';

                        if (_.indexOf(groups, groupValue) == -1)
                            groups.push(groupValue);

                        result.othersGroupBy = groups;
                    }

                    return result;
                }
            },
        },
        initialize: function () {
            var toDate = new moment();
            var fromDate = (new moment(toDate)).subtract(1, 'day');

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

            this.fetchShifts();
            //Load production items on render after load translation.
            //this.fetchProductionItems();
            this.fetchProducts();
        },
        fetchShifts: function () {
            var that = this;
            var customPath = "/app/custom-screens/modules/OEE/oee-report/";
            $.ajax(app.foldersRoot + customPath + "cube-api/cube-api.aspx", {
                type: 'POST',
                data: {
                    action: 'FILTER',
                    name: 'Shifts',
                },
                dataType: "json",
                success: function (data) {
                    if (data) {
                        that.set({
                            shifts: (_.map(data, function (m) {
                                return { value: m["MEMBER_UNIQUE_NAME"], label: m["MEMBER_NAME"] };
                            })),
                        });
                    }
                }
            });
        },
        fetchProductionItems: function (options) {
            var that = this;
            var customPath = "/app/custom-screens/modules/OEE/oee-report/";
            var opt = _.extend(
                {
                    params: {},
                    callback: null,
                    refresh: false,
                    set: false,
                    internalAreaText: 'None',
                },
                options
            );

            $.ajax(app.foldersRoot + customPath + "cube-api/cube-api.aspx", {
                type: 'POST',
                data: {
                    action: 'FILTER',
                    name: 'Production Items',
                },
                dataType: "json",
                success: function (data) {
                    if (data) {
                        //Filter:
                        // + Items duplicated, which contains the text 'DATAMEMBER' on MEMBER_UNIQUE_NAME.
                        // + Unknown member.
                        // + Internal area item.
                        var dataFiltered = _.filter(data, function (m) {
                            return (m["MEMBER_UNIQUE_NAME"].indexOf("DATAMEMBER") == -1)
                                    && (m["MEMBER_NAME"].toUpperCase() != "UNKNOWN")
                                    //&& (parseInt(m["MEMBER_KEY"], 10) > 0)
                            ;
                        });

                        var areas = _.map(
                            _.where(dataFiltered, { LEVEL_UNIQUE_NAME: "[Production Items].[Parent Id].[Level 02]", }),
                            function (m) {
                                return {
                                    value: m["MEMBER_UNIQUE_NAME"],
                                    label: (parseInt(m["MEMBER_KEY"], 10) > 0)
                                                ? m["MEMBER_NAME"]
                                                : opt.internalAreaText,
                                    parent: m["PARENT_UNIQUE_NAME"],
                                };
                            }
                        );

                        var lines = _.map(
                            _.where(dataFiltered, { LEVEL_UNIQUE_NAME: "[Production Items].[Parent Id].[Level 03]", }),
                            function (m) {
                                return { value: m["MEMBER_UNIQUE_NAME"], label: m["MEMBER_NAME"], parent: m["PARENT_UNIQUE_NAME"], };
                            }
                        );

                        var machines = _.map(
                            _.where(dataFiltered, { LEVEL_UNIQUE_NAME: "[Production Items].[Parent Id].[Level 04]", }),
                            function (m) {
                                return { value: m["MEMBER_UNIQUE_NAME"], label: m["MEMBER_NAME"], parent: m["PARENT_UNIQUE_NAME"], };
                            }
                        );

                        ////Items with DATAMEMBER text on is MEMBER_UNIQUE_NAME are the lines.
                        //var lines = _.map(_.filter(data, function (m) { return (m["MEMBER_UNIQUE_NAME"].indexOf("DATAMEMBER") != -1); }), function (m) {
                        //    return { value: m["MEMBER_UNIQUE_NAME"].replace('.DATAMEMBER', ''), label: m["MEMBER_NAME"], valueDataMember: m["MEMBER_UNIQUE_NAME"], };
                        //});
                        ////Machines are the items that do not have DATAMEMBER text on is MEMBER_UNIQUE_NAME.
                        ////But we also need to do some filter because the line items are duplicated: with DATAMEMBER
                        ////and without DATAMEMBER.
                        //var machines = _.map(
                        //    _.filter(data,
                        //        function (m) {
                        //            if (m["MEMBER_UNIQUE_NAME"].indexOf("DATAMEMBER") != -1)
                        //                return false;

                        //            if (_.findWhere(lines, { valueDataMember: m["MEMBER_UNIQUE_NAME"] + '.DATAMEMBER' }))
                        //                return false;

                        //            return true;
                        //        }),
                        //        function (m) {
                        //            return { value: m["MEMBER_UNIQUE_NAME"], label: m["MEMBER_NAME"], parent: m["PARENT_UNIQUE_NAME"], };
                        //        });

                        that.set({
                            areas: areas,
                            lines: lines,
                            machines: machines,
                        });
                    }
                }
            });
        },
        fetchProducts: function () {
            var that = this;
            var customPath = "/app/custom-screens/modules/OEE/oee-report/";
            $.ajax(app.foldersRoot + customPath + "cube-api/cube-api.aspx", {
                type: 'POST',
                data: {
                    action: 'FILTER',
                    name: 'Products',
                },
                dataType: "json",
                success: function (data) {
                    if (data) {
                        that.set({
                            products: (_.map(data, function (m) {
                                return { value: m["MEMBER_UNIQUE_NAME"], label: m["MEMBER_NAME"] };
                            })),
                        });
                    }
                }
            });
        },
    });

    //subview for the subnavbar controls
    OEEReport.Views.SubnavBarControls = Backbone.Epoxy.View.extend({
        id: "oee-report-subnavbar-controls"
        , title: ""
        , template: "oee-report"
        , initialize: function (opt) {
            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: {
            "click .btn-export-to-excel": 'exportToExcel',
        },

        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/modules/OEE/oee-report/";

            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;

                    that.model.fetchProductionItems({
                        internalAreaText: app.translate(that, "internal_area_text"),
                    })

                    //loading the view and appeding it to the views's $el.
                    that.$el.html(tmp());
                    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);
                }, true, customPath);
            }, customPath, "subnavbar_controls");
        }

        , setExportButtonExporting: function (val) {
            var btn_export = this.$el.find('.btn-export-to-excel');
            var export_state = btn_export.find('.excel-export-state');
            var loading_state = btn_export.find('.loading-state');

            if (val) {
                export_state.css('display', 'none', 'important');
                loading_state.removeClass('hide');

                btn_export.attr('disabled', true);
            } else {
                loading_state.addClass('hide');
                export_state.css('display', 'inline-block', 'important');

                btn_export.attr('disabled', false);
            }
        }

        , exportToExcel: function () {
            if (_.isFunction(this.options.onExportToExcel)) {
                this.options.onExportToExcel.call(this);
            }
        }

        , 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 () {
        }
    });

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

});

