//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",
],

function (app, T, Backgrid, Modal) {

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

    Materials.Models.Item = Backbone.Model.extend({
        defaults: {
            id: null,
            name: null,
            price: null,
            density: null,
            physicalYield: null,
            chillFactor: null,
            energyEquivalent: null,
            chemistryC: null, 
            chemistryMn: null, 
            chemistryP: null, 
            chemistryS: null, 
            chemistrySi: null, 
            chemistryCu: null, 
            chemistryV: null, 
            chemistryCb: null, 
            chemistryCr: null, 
            chemistryNi: null, 
            chemistryMo: null, 
            chemistrySn: null, 
            chemistryN: null, 
            chemistryB: null, 
            chemistryAl: null, 
            chemistryTi: null, 
            chemistryCa: null, 
            chemistryPb: null, 
            chemistryAs: null, 
            chemistrySb: null, 
            chemistryZn: null, 
            chemistryCo: null, 
            chemistryZr: null, 
            chemistryW: null, 

            isNew: false,
            isProcessing: false,

            changedAttrs: [],
        }, 
    });

    Materials.Collections.Items = Backbone.Collection.extend({
        model: Materials.Models.Item,
        initialize: function (a, b, c) {
            this.options = _.extend({}, this.options, b); 
            _.bindAll(this);
        },
        comparator: "name", 
        //comparator: function (a, b) {            
        //    if (a.get("inclusiveStart") < b.get("inclusiveStart")) return -1;
        //    else if (a.get("inclusiveStart") > b.get("inclusiveStart")) return 1;
        //    else return 0; 
        //}, 
        fetch: function (opt) {
            var options = {
                method: "set",
                async: true,
                callback: null,
            };

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

            var that = this,
                parentModel = this.options.parent
                QP = new Core.Database.QueryParameters();

            var items = [];

            Core.Json.CallProcedure(app.DatabaseNames.Scrapyard + parentModel.get("getProcedure"), QP, {
                onSuccess: function (data) {
                    if (Core.Object.Eval(data, "Table")) {
                        var data = data.Table;

                        var keys = {};
                        _.each(_.keys((new that.model ()).defaults), function (k) {
                            keys[k.toUpperCase()] = k;
                        });

                        for (var i = 0; i < data.length; i++) {
                            var item = {}; 
                            _.each(data[i], function (value, key) {
                                if (keys[key.toUpperCase()]) {
                                    item[keys[key.toUpperCase()]] = value;
                                }
                            });

                            items.push(item); 
                        }

                        //for (var i = 0; i < data.length; i++) {
                        //    var itemData = data[i];
                        //    var item = {
                        //        id: itemData.Id,
                        //        name: itemData.Name,
                        //        price: itemData.Price,
                        //    };

                        //    items.push(item);
                        //}
                    }

                    var newItems = _.where(that.toJSON(), { isNew: true });
                    var itemsAdded = _.filter(newItems, function (t) {
                        return t["id"] == -1;
                    });
                    var itemsChanged = _.filter(newItems, function (t) {
                        return t["id"] != -1;
                    });

                    items = _.filter(items, function (t) {
                        return !(_.findWhere(itemsChanged, { id: t["id"] }) != null); 
                    }); 

                    [].push.apply(items, newItems);

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

                    if (options.callback != null && _.isFunction(options.callback))
                        options.callback.call(this, that);
                },
                Async: options.async,
                Secured: true,
            }, app.ConnectionStrings.app);

            return this;
        },
        upsertItem: function (id, props, success, error) {
            var that = this;
            var QP = new QueryParameters();

            var parentModel = this.options.parent; 

            QP.Add("Id", "INT", id);

            for (var q in props) {
                QP.Add(props[q].name, props[q].type, props[q].value);
            }

            Core.Json.CallProcedure(app.DatabaseNames.Scrapyard + parentModel.get("upsertProcedure"), QP, {
                onSuccess: function (data) {
                    if (data && data.Table && ((data.Table.length > 0 && data.Table[0].Status != "FAILED") || data.Table.length == 0)) {
                        var data = data.Table;
                        var ids = _.pluck(data, 'Id');

                        if (success != null && _.isFunction(success))
                            success.call(this, that, ids);
                    } else {
                        if (error != null && _.isFunction(error))
                            error.call(this, that, data);
                    }
                },
                onError: function (data) {
                    if (error != null && _.isFunction(error))
                        error.call(this, that, data);
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        validateUpsertRow: function (id, props, success, error) {
            var that = this;
            var QP = new QueryParameters();

            var parentModel = this.options.parent;

            QP.Add("Id", "INT", id);
            QP.Add("IsValidation", "BIT", true); 

            for (var q in props) {
                QP.Add(props[q].name, props[q].type, props[q].value);
            }

            Core.Json.CallProcedure(app.DatabaseNames.Scrapyard + (parentModel.get("validateProcedure") ? parentModel.get("validateProcedure") : parentModel.get("upsertProcedure")), QP, {
                onSuccess: function (data) {
                    if (data && data.Table && data.Table[0] && data.Table[0].Status) {
                        if (success != null && _.isFunction(success))
                            success.call(this, that, data.Table[0]);
                    } else {
                        if (error != null && _.isFunction(error))
                            error.call(this, that, data);
                    }
                },
                onError: function (data) {
                    if (error != null && _.isFunction(error))
                        error.call(this, that, data);
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        }, 
        callRemoveItem: function (id, success, error) {
            var that = this;
            var QP = new QueryParameters();

            var parentModel = this.options.parent;

            QP.Add("@Id", "INT", id);

            Core.Json.CallProcedure(app.DatabaseNames.Scrapyard + parentModel.get("removeProcedure"), QP, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var data = data.Table;
                        var ids = _.pluck(data, 'Id');

                        if (success != null && _.isFunction(success))
                            success.call(this, that, ids);
                    } else {
                        error.call(this, that);
                    }
                },
                Async: true,
                Secured: true,
            }, app.ConnectionStrings.app);
        },
        removeItem: function (id, success, error) {
            var that = this;
            var model = this.get(id);
            if (model) {
                this.callRemoveItem(
                    id
                    , function (ref, ids) {
                        //removing from collection; 
                        that.remove(model);

                        if (success && _.isFunction(success))
                            success.call(this, that, ids);
                    },
                    function (ref) {
                        if (error && _.isFunction(error))
                            error.call(this, that);
                    }
                );
            }
        },
        //insertItem: function (props, success, error) {
        //    this.upsertItem(null, props
        //        , function (ref, ids) {
        //            that.set(
        //        }
        //        , function (ref, ids) {
        //        }
        //    );
        //}, 
    }); 

    Materials.Models.Main = Backbone.Model.extend({
        defaults: {
            items: null,
            getProcedure: null,
            validateProcedure: null, //if null use upsert with isValidation option
            upsertProcedure: null,
            removeProcedure: null,
        },
        initialize: function () {
            this.attributes.items = new Materials.Collections.Items(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.
    Materials.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "materials"; 
        } catch (Error) { }
    }

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

            var procs = {
                type: null, 
                getProcedure: null,
                validateProcedure: null, //if null use upsert with isValidation option
                upsertProcedure: null,
                removeProcedure: null,
            };

            procs.getProcedure = ".SCRAP.GetMaterialsCatalog"
            procs.upsertProcedure = ".SCRAP.UpsertMaterial"; 
            procs.removeProcedure = null; 

            var model = new Materials.Models.Main(_.extend({
            }, procs));

            this.model = model;

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

            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/scrapyard/materials/";

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

                    //that.options.MYREFERENCES.subviews.subnavbarControls = new Materials.Views.SubnavBarControls({
                    //    parent: that
                    //    , container: app.views.subnavbar.getSectionContainer(1, 12)
                    //    , events: {
                    //        "click .add-item": that.addNew,
                    //    }
                    //});

                    //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")

                    var ActionsCell = Backgrid.Cell.extend({
                        template: _.template(that.$el.find("#actions_cell_template").html()),
                        className: "actions-cell", 
                        initialize: function () {
                            Backgrid.Cell.prototype.initialize.apply(this, arguments);
                            this.bindEvents();
                        },
                        events: {
                            "click .btn-cell-action": "cellActionClick"
                        },
                        cellActionClick: function (e) {
                            var target = $(e.target);
                            var actionData = target.closest("[data-cell-action]").data("cell-action");
                            if (actionData) {
                                that.actionOnRow(this.model, actionData);
                            }
                        },
                        render: function () {
                            this.$el.html(this.template());

                            this.$el.find("[data-toggle='tooltip']").tooltip();

                            this.checkMode();
                            this.delegateEvents();
                            return this;
                        },
                        setNewRowMode: function(val){
                            //var btnRemove = this.$el.find(".btn-remove");
                            var btnSave = this.$el.find(".btn-save");
                            var btnDiscard = this.$el.find(".btn-discard");

                            if (val) {
                                //btnRemove.addClass("hide");
                                btnSave.removeClass("hide");
                                btnDiscard.removeClass("hide");
                            } else {
                                //btnRemove.removeClass("hide");
                                btnSave.addClass("hide");
                                btnDiscard.addClass("hide");
                            }
                        },
                        setIsProcessingMode: function (e) {
                            //var btnRemove = this.$el.find(".btn-remove");
                            var btnSave = this.$el.find(".btn-save");
                            var btnDiscard = this.$el.find(".btn-discard");
                            var loading = this.$el.find(".loading-state"); 

                            //btnRemove.addClass("hide");
                            btnSave.addClass("hide");
                            btnDiscard.addClass("hide");

                            loading[e ? "removeClass" : "addClass"]("hide");
                        }, 
                        checkMode: function () {
                            var newRow = this.model.get("isNew");
                            var isProcessing = this.model.get("isProcessing"); 

                            if (isProcessing) {
                                this.setIsProcessingMode(true);
                            } else {
                                this.setIsProcessingMode(false);

                                if (newRow) this.setNewRowMode(true);
                                else this.setNewRowMode(false);
                            }
                        }, 
                        bindEvents: function () {
                            this.listenTo(this.model, "change:isNew", this.checkMode);
                            this.listenTo(this.model, "change:isProcessing", this.checkMode);
                        },
                    });

                    var columns = [
                        {
                            name: "name",
                            label: app.translate(that, "name_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: "string-cell align-center-cell name",
                            })
                        },
                        {
                            name: "price",
                            label: app.translate(that, "price_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        },
                        {
                            name: "density",
                            label: app.translate(that, "density_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        },
                        {
                            name: "physicalYield",
                            label: app.translate(that, "physicalYield_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        },
                        {
                            name: "chillFactor",
                            label: app.translate(that, "chillFactor_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        },
                        {
                            name: "energyEquivalent",
                            label: app.translate(that, "energyEquivalent_label"),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        },
                        //{
                        //    name: "enabled",
                        //    label: app.translate(that, "enabled_label"),
                        //    editable: false,
                        //    sortable: false,
                        //    cell: Backgrid.Cell.extend({
                        //        template: _.template("<input class='enable-checkbox' tabindex='-1' type='checkbox' />"),
                        //        initialize: function () {
                        //            Backgrid.Cell.prototype.initialize.apply(this, arguments);
                        //        },
                        //        events: {
                        //            "change .enable-checkbox": "chkboxChanged",
                        //        },
                        //        chkboxChanged: function (e) {
                        //            this.model.set("enabled", $(e.target).is(":checked"));
                        //        },
                        //        render: function () {
                        //            this.$el.html(this.template());

                        //            if (this.model.get("enabled"))
                        //                this.$el.find(".enable-checkbox").attr("checked", "checked");

                        //            this.delegateEvents();
                        //            return this;
                        //        },
                        //        className: "align-center-cell enabled",
                        //    }),
                        //},
                    ];

                    var chemistries = _.filter(_.keys((new Materials.Models.Item()).defaults), function (v) {
                        return v.indexOf("chemistry") != -1; 
                    });

                    _.each(chemistries, function (c) {
                        columns.push({
                            name: c,
                            label: app.translate(that, c + "_label"),
                            editable: true,
                            sortable: false,
                            cell: Backgrid.NumberCell.extend({
                                orderSeparator: '',
                                className: "number-cell align-center-cell price",
                            })
                        }); 
                    }); 

                    columns.push({
                        name: "actions",
                        label: "",
                        editable: false,
                        sortable: false,
                        cell: ActionsCell
                    }); 

                    var grid = new Backgrid.Grid({
                        className: "backgrid table table-hover",
                        columns: columns,
                        collection: that.model.get("items"),
                    });

                    that.$el.find(".items-grid-container").append(grid.render().el);
                    //that.options.MYREFERENCES.subviews.subnavbarControls.render();

                    //end

                    //appending view to the main container
                    that.append(thatContainer, that.$el); 
                    that._startAutoRefresh(); 
                }, true, customPath);
            }, customPath, "main_template");
        }

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

        , _startAutoRefresh: function () {
            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();
            } catch (Error) { }
        }

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

            this.refresh();

            if (this.options.MYREFERENCES.autoRefresh.enabled == true) {
                this.options.MYREFERENCES.autoRefresh.toid = setTimeout(this._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 () {
            try {
                this.model.get("items").fetch(); 
            } catch (Error) { }
        }

        , collectionChanged: function (m, b, c) {
            var that = this; 
            var fromFetch = (b && b.from == "fetch") ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false; 
            var isNewRow = m.get("isNew");
            var isNewChanged = _.has(m.changed, "isNew"); 

            if (!fromFetch && !isNewRow && !avoidSync && !isNewChanged) {
                m.set("isNew", true); 
            }

            //if (!fromFetch && !isNewRow && !avoidSync) {
            //    m.collection.upsertItem(m.get("id"), [
            //        { name: "Name", type: "VARCHAR", value: m.get("name") }, 
            //        { name: "InclusiveStart", type: "INT", value: m.get("inclusiveStart") },
            //        { name: "ExclusiveEnd", type: "INT", value: m.get("exclusiveEnd") },
            //    ], function (ref, ids) {
            //        //if (m && m.collection && m.collection.sort) m.collection.sort();
            //    }, function (ref, data) {
            //        that.refresh();

            //        if (data && data.Table && data.Table.length > 0 && data.Table[0].Status == "FAILED") {
            //            app.views.topMessages.showMessage(app.translate(that, data.Table[0].Message + "_error_msg"));
            //        }
            //    }); 
            //}
        }

        , collectionTrackChanges: function (m, b, c) {
            var that = this;
            var fromFetch = (b && b.from == "fetch") ? true : false;
            var avoidSync = (b && b.avoidSync) ? b.avoidSync : false;
            var isNewRow = m.get("isNew");
            var isNewChanged = _.has(m.changed, "isNew") && m.changed.length == 1;

            if (!fromFetch && !avoidSync && !isNewChanged) {
                var changed = [];
                for (var i in m.changed) changed.push(i);
                m.set("changedAttrs", _.union(m.get("changedAttrs"), changed), { silent: true });
            }
        }

        , actionOnRow: function (model, action) {
            switch (action.toUpperCase()) {
                case "DELETE":
                    this.removeRow(model); 
                    break;
                case "SAVE":
                    this.saveRow(model); 
                    break;
                case "DISCARD":
                    this.discardRow(model); 
                    break; 
            }
        }

        , removeRow: function (model) {
            var that = this; 
            model.collection.removeItem(
                model.get("id")
                , function (data) {
                    that.refresh(); 
                }
                , function (data) {
                    that.refresh();
                }
            );
        }

        , saveRow: function (m) {
            var that = this;
            var id = (m.get("id") != -1) ? m.get("id") : null;

            var params = [
                //{ name: "Price", type: "FLOAT", value: m.get("price") },
                //{ name: "Enabled", type: "BIT", value: m.get("enabled") },
            ];

            var chemistries = _.filter(_.keys((new Materials.Models.Item()).defaults), function (v) {
                return v.indexOf("chemistry") != -1;
            });

            _.each(chemistries, function (c) {
                params.push({
                    name: c,
                    type: "FLOAT",
                    value: m.get(c), 
                }); 
            });

            m.set("isProcessing", true);
            m.collection.upsertItem(id, params, function (ref, ids) {
                m.set({ id: ids[0], isNew: false, isProcessing: false }, { avoidSync: true });
                m.set({ "changedAttrs": [] }, { silent: true });

                if (m && m.collection && m.collection.sort) m.collection.sort();
                that.refresh();
            }, function (ref, data) {
                m.set("isProcessing", false);
                that.refresh();

                if (data && data.Table && data.Table.length > 0 && data.Table[0].Status == "FAILED") {
                    app.views.topMessages.showMessage(app.translate(that, data.Table[0].Message + "_error_msg"));
                }
            });
        }

        , discardRow: function (m) {
            //to discard just remove the model from the collection.
            if (m.get("id") != -1) {
                m.set("isNew", false);
                m.set({ "changedAttrs": [] }, { silent: true });

                this.refresh();
            } else {
                m.collection.remove(m);
            }
        }

        , addNew: function () {
            this.model.get("items").unshift({
                id: -1,
                isNew: true, 
            }); 
        }

        , bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
            this.listenTo(this.model.get("items"), "change", this.collectionChanged);
            this.listenTo(this.model.get("items"), "change", this.collectionTrackChanges);
            //this.listenTo(this.model.get("items"), "add", this.collectionTrackChanges);
        }

        , bindViewScopedEvents: function () {
        }

        , 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("sections", "12");
            app.models.subnavbar.set("subnavbar", false);
        }

        , reRender: function () {
            this._startAutoRefresh();
        }
    });

    //subview for the subnavbar controls
    Materials.Views.SubnavBarControls = Backbone.Epoxy.View.extend({
        id: "materials-subnavbar-controls"
        , title: ""
        , template: "materials"
        , 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.model = (this.model) ? this.model : new Materials.Models.SubnavBarControls();

            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/scrapyard/materials/";

            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;

                    var ctx = {
                        editable: (($.inArray("AdminUserRole", app.models.user.get("roles")) != -1
                            || $.inArray("SupervisorUserRole", app.models.user.get("roles")) != -1) ? true : false),
                    };

                    //loading the view and appeding it to the views's $el.
                    that.$el.html(tmp(
                        _.extend({}, ctx, (that.model) ? that.model.toJSON() : {})
                    ));

                    that.applyBindings();

                    that.append(thatContainer, that.$el);
                }, 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
        }

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

});
