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

  "js/jqBootstrapValidation/jqBootstrapValidation",

],

function (app, T, Modal, Backgrid) {

    var procsDB = app.DatabaseNames.System;
    var procsConnectionString = app.ConnectionStrings.app; 

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

    Users.Model.UsersListItem = Backbone.Model.extend({
        defaults: {
            userId: null,
            name: "",
            username: "",
            role: "", 
            selected: false
        }
    });

    Users.Collections.UsersList = Backbone.Collection.extend({
        model: Users.Model.UsersListItem
    }); 

    Users.Model.UsersList = Backbone.Model.extend({
        initialize: function () {
            this.set("selected", new Users.Collections.UsersList());

            this.listenTo(this.get("selected"), "change add remove reset", function () {
                this.trigger("change:selected"); 
            });

            this.set("list", new Users.Collections.UsersList());

            this.listenTo(this.get("list"), "change add remove reset", function () {
                this.trigger("change:list");
            });
        }
        , fetch: function (e) {
            //@overriding fetch method to fit our needs.
            var obj = {};

            var userslist_collection = new Users.Collections.UsersList(); 
            var existing_userslist_collection = this.attributes.list;
            var existing_selected_collection = this.attributes.selected; 

            var usersListModels_array = [];
            Core.Json.CallProcedure(procsDB + ".FrontEnd.GetAccountUsers", null, {
                onSuccess: function (data) {
                    if (Core.Object.Eval(data, "Table")) {
                        var data = data.Table;
                        data.sort((a, b) => {
                            const nameA = a.Name.toUpperCase();
                            const nameB = b.Name.toUpperCase();
                            if (nameA < nameB) {
                                return -1;
                            }
                            if (nameA > nameB) {
                                return 1;
                            }
                            return 0;
                        });
                        
                        for (var i = 0; i < data.length; i++) {

                            var idata = data[i];

                            var attrs = {
                                userId: idata.UserID,
                                id: idata.UserID,  
                                name: idata.Name,
                                username: idata.Username,
                                role: idata.Role,
                            }; 

                            var existingModel = existing_userslist_collection.findWhere({ userId: attrs.userId });
                            if (existingModel) existingModel = existingModel.clone()

                            var newModel = null; 
                            if (existingModel) {
                                newModel = existingModel;
                                newModel.set(attrs, { silent: true });
                            } else {
                                newModel = new Users.Model.UsersListItem(attrs);
                            }

                            usersListModels_array.push(newModel);
                        }
                    }
                },
                Async: false,
                Secured: true,
                //Language: app.language,
            }, procsConnectionString);
            
            existing_userslist_collection.set(usersListModels_array);
            
            var selectedmodels = []; 
            _.each(existing_userslist_collection.where({selected:true}), function(model){
                selectedmodels.push(new Users.Model.UsersListItem({ userId: model.get("userId"), id: model.get("userId") })); 
            }); 
            existing_selected_collection.set(selectedmodels); 
        }
        , defaults: {
            selected: null,
            list:null, 
        }
    });

    Users.Views.UsersList = Backbone.View.extend({
        template: "users"
        , id: "users"
        , title: "Users"
        //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 Users.Model.UsersList({
            });

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

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

            this.model = model; 

            this.options.MYREFERENCES.subviews = {};

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

        events: {
            "click .users-table tbody tr": "rowClick",
            "click .chkbox-select-all": "selectAllRows",
            "change .users-table tbody input:checkbox": "checkboxChange",
        },

        render: function (container, viewParams) {
            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/IHConfiguration/users/";

            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
                    if (!that.options.i18n[that.template])
                        that.options.i18n[that.template] = i18nJED;

                    var ctx = {
                        write: app.models.securityManager.getModuleActionValue("ihconfiguration_users", "write"),
                    }; 

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    if (!that.options.MYREFERENCES.subviews.subnavbarControls) {
                        that.options.MYREFERENCES.subviews.subnavbarControls = new Users.Views.SubnavBarControls({
                            parent: that
                            , container: app.views.subnavbar.getSectionContainer(3)
                            , events: _.extend((Users.Views.SubnavBarControls.prototype.events) ? Users.Views.SubnavBarControls.prototype.events : {},
                                {
                                "click .delete-user-btn": that.removeUser
                                }
                            )
                        });

                        that.options.MYREFERENCES.subviews.subnavbarControls.render();
                    }

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

                    that.$el.html(tmp(_.extend(that.model.toJSON(), ctx)));

                    that.drawUsersGrid();

                    //

                    that._startAutoRefresh();

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

                    //end:

                }, true, customPath);
            }, customPath, 'users_list');
        }

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

                var columns = [
                    {
                        name: 'name',
                        label: 'Name',
                        editable: false,
                        sortable: true,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: 'string-cell align-center-cell',
                        }),
                    },
                    {
                        name: 'username',
                        label: 'Users',
                        editable: false,
                        sortable: true,
                        cell: Backgrid.StringCell.extend({
                            orderSeparator: '',
                            className: 'string-cell align-center-cell',
                        })
                    },
                ];

                var customRow = Backgrid.Row.extend({
                    events: {
                        "click": "onClick"
                    },
                    className: "clickeable-row",
                    initialize: function () {
                        Backgrid.Row.prototype.initialize.apply(this, arguments);
                        this.bindEvents();
                    },
                    render: function () {
                        Backgrid.Row.prototype.render.apply(this, arguments);
                        return this;
                    },
                    onClick: function (e) {
                        try {
                            that.model.set({ selectedUserId: this.model.get('userId') });
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    },
                    bindEvents: function () {
                    },
                });

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

                this.options.grids.users = grid;
                var grid_el = grid.render().el;
                that.$el.find(".usersTableContainer").append(grid_el);

            } catch (error) { console.error(error); }

        }

        , removeUser: function () {
            try {

                var userids = [];
                var usernames = [];

                _.each(this.model.get("list").where({ selected: true }), function (model) {
                    userids.push(model.get("userId").toString());
                    usernames.push(model.get("username").toString());
                }); 

                var modal = new Modal.Views.Main({
                    id: "remove-user-confirmation-modal"
                    , title: this.options.i18n[this.template].translate("remove_users_confirmation_title")
                                                                .ifPlural(usernames.length, "remove_users_confirmation_title_plural_")
                                                                .fetch()
                    , message: this.options.i18n[this.template].translate("remove_users_confirmation_body")
                                                                .ifPlural(usernames.length, "remove_users_confirmation_body_plural_")
                                                                .fetch(usernames.join(", "))
                    , allowCancel: true
                    , buttons_type: "CONTINUE-CANCEL"
                });

                modal.on("continue", _.bind(function () { 

                    var qps = {
                        UserID: { val: userids.join(','), type: "VARCHAR" },
                    };

                    var QP = new QueryParameters();
                    for (var i in qps)
                        QP.Add(i, qps[i].type, qps[i].val);

                    Core.Json.CallProcedure(procsDB + ".FrontEnd.RemoveAccountUsers", QP, {
                        onSuccess: function (data) {
                            if (Core.Object.Eval(data, "Table")) {
                            }
                        },
                        Async: false,
                        Secured: true
                    }, procsConnectionString);

                    this.refresh(); 

                }, this));

                modal.show();

            } catch (Error) { }
        }

        , _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.options.MYREFERENCES.autoRefresh.toid = setTimeout(this._autoRefresh, 1);
            } catch (Error) { }
        }

        , _autoRefresh: function () {
            //console.log("autorefresh: " + new Date().toString()); 
            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 (viewParams) {
            try {
                this.model.fetch(); 
            } catch (Error) { }
        }

        , rowClick: function () {
            try {
                var that = this;
                var userid = that.model.get('selectedUserId');

                app.router.navigate(app.router.currentRoute + "/user/" + userid, { trigger: true });
               
            } catch (Error) {
            }
        }

        , selectAllRows: function (e) {
            try {
                var that = this; 
                var target = $(e.target);
                var isChecked = target.prop("checked"); 

                this.$el.find(".users-table tbody td input:checkbox").prop("checked", target.prop("checked"));

                selected = this.model.get("selected");

                this.model.get("list").each(function (item) {
                    item.set({ selected: false }, { silent: true }); 
                }); 

                if (isChecked) {
                    selected.reset([], { silent: true }); 
                    this.$el.find(".users-table tbody tr").each(function (index, elem) {
                        var userid = $(elem).data("userid"); 

                        var listItem = that.model.get("list").findWhere({ userId: userid });
                        if (listItem) listItem.set({ selected: target.prop("checked") }, { silent: true });

                        selected.add(new Users.Model.UsersListItem({ userId: $(elem).data("userid"), id: $(elem).data("userid") }));
                    });
                } else {
                    selected.reset(); 
                }

            } catch (Error) {
            }
        }

        , checkboxChange: function (e) {
            var target = $(e.target);
            var tr = target.parent("td").parent("tr");
            var userid = tr.data("userid");

            var selected = this.model.get("selected"); 

            var listItem = this.model.get("list").findWhere({ userId: userid });
            if (listItem) listItem.set({ selected: target.prop("checked") }, { silent: true }); 

            if (target.prop("checked")) {
                selected.add(new Users.Model.UsersListItem({ userId: userid, id: userid })); 
            } else {
                var item = selected.findWhere({ userId: userid }); 
                if (item) selected.remove(item); 
            }

            this.$el.find(".chkbox-select-all").prop("checked", false);
        }

        , checkToolbar: function () {
            var selected = this.model.get("selected");
            var toolbar = this.options.MYREFERENCES.subviews.subnavbarControls; 

            if (selected.length > 0) {
                toolbar.toolbarDelete(true); 
            } else {
                toolbar.toolbarDelete(false);
            }
        }

        , checkList: function (e) {
            e; 
        }

        , 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("selected"), "add", this.checkToolbar);
            //this.listenTo(this.model.get("selected"), "remove", this.checkToolbar);
            //this.listenTo(this.model.get("selected"), "reset", this.checkToolbar);
            this.listenTo(this.model, "change:selected", this.checkToolbar);
            this.listenTo(this.model, "change:list", _.debounce(this.render, 500));
        }

        , bindViewScopedEvents: function () {

        }

        , unbindViewScopedEvents: function () {

        }

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

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

        , closeSubviews: function () {
            _.each(this.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._stopAutoRefresh(); 
            this.hideSubviews();

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

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

        , preRender: function () {
            this.config_subnavbar(); 
        }
        , config_subnavbar: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("dateTimeScopeControl", false);
            app.models.subnavbar.set("sections", "4-4-4");

            var subnavbar = app.models.securityManager.getModuleActionValue("ihconfiguration_users", "write");
            app.models.subnavbar.set("subnavbar", subnavbar);
        }
        , reRender: function () {
            this.config_subnavbar(); 
            this.refresh();
        }
    });

    Users.Model.ProfileMembership = Backbone.Model.extend({
        defaults: {
            id: null,
            name: null,
            member: false, 
        }, 
        initialize: function () {
        }, 
    }); 

    Users.Collections.ProfileMemberships = Backbone.Collection.extend({
        model: Users.Model.ProfileMembership,
        fetch: function (options) {
            var QP = new QueryParameters();

            var pms = []; 
            Core.Json.CallProcedure(procsDB + ".FrontEnd.GetAccountProfiles", QP, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var profiles = data.Table;

                        _.each(profiles, function (t) {
                            pms.push({
                                id: t.Id,
                                name: t.Name,
                                member: false,
                            }); 
                        });
                    }
                },
                Async: false,
                Secured: false
            }, procsConnectionString);

            this.set(pms);
        }, 
    }); 

    Users.Model.UserPanel = Backbone.Model.extend({
        defaults: {
            userId: null,
            name: "",
            lastname: "",
            role: null,
            autologin: false, 
            username: null,
            nextId: null,
            previousId: null,
            changingPassword: false,
            password: null,
            timezone: null, 
            departmentId: -1,
            departments: null,
            screenmode: "EDIT",

            profileMemberships: null,
        }, 
        initialize: function () {
            if (!this.attributes.profileMemberships) this.attributes.profileMemberships = new Users.Collections.ProfileMemberships(); 
        }, 
        lastFetchAttributes: {},
        fetch: function (options) {
            //@overriding fetch method to fit our needs.
            var attrs = {};
            var pms = [];
            var departments = [];

            var QP = new QueryParameters();
            if (options.data) {
                if (options.data.id) QP.Add("UserID", "INT", options.data.id); 
            }

            Core.Json.CallProcedure(procsDB + ".FrontEnd.GetAccountUserInfo", QP, {
                onSuccess: function (data) {
                    if (Core.Object.Eval(data, "Table.0")) {
                        var userdata = data.Table[0];
                        var profileMemberships = data.Table1; 
                        var departmentsTable = data.Table2;

                        attrs = {
                            userId: userdata.UserID,
                            name: userdata.Name,
                            lastname: userdata.LastName,
                            role: userdata.Role,
                            username: userdata.Username,
                            autologin: userdata.Autologin, 
                            timezone: userdata.Timezone,
                            departmentId: userdata.DepartmentId
                        };
                       
                        _.each(profileMemberships, function (t) {
                            pms.push({
                                id: t.Id,
                                name: t.Name,
                                member: t.Member
                            }); 
                        }); 
                        _.each(departmentsTable, function (t) {
                            departments.push({
                                id: t.DepartmentId,
                                name: t.Name,
                            }); 
                        });
                    }
                },
                Async: false,
                Secured: true
            }, procsConnectionString);

            this.lastFetchAttributes = _.clone(attrs);

            this.get("profileMemberships").set(pms);
            this.set("departments", departments);
            this.set(this.parse(attrs), {});
       }
    });

    Users.Views.UserPanel = Backbone.View.extend({
        template: "users"
        , id: "users"
        , title: "Users"
        //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 () { };

            var userid = -1;

            if (this.options.viewParams) {
                userid = (this.options.viewParams.sectionParam2 != null && this.options.viewParams.sectionParam2 != undefined) 
                    ? this.options.viewParams.sectionParam2 : -1; 
            }

            var model = new Users.Model.UserPanel({
            });

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

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

            this.model = model;

            this.options.MYREFERENCES.subviews = {};
            

            this.model.fetch({ data: { id: userid } });

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

        events: {
            "click .btn-save-changes": "saveChanges",
            "click .btn-cancel-changes": "cancelChanges",
            "click .btn-back": "goBack",
            "click .btn-change-password": "changePassword", 
            "click .delete-user-btn" : "removeUser",
        },

        render: function (container, viewParams) {
            var that = this;
            var thatContainer = 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/IHConfiguration/users/";

            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
                    if (!that.options.i18n[that.template])
                        that.options.i18n[that.template] = i18nJED;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    var ctx = {
                        timezones: []
                    };
                    
                    var automatic_timezone_label = that.options.i18n[that.template].translate("timezone_automatic_label").fetch(); 
                    ctx.timezones.push({ Id: "AUTO", Name: automatic_timezone_label }); 

                    Core.Json.CallProcedure(procsDB + ".FrontEnd.GetTimezones", null, {
                        onSuccess: function (data) {
                            if (data.Table != null && data.Table != undefined) {
                                for (var i in data.Table) {
                                    var rowdata = data.Table[i];
                                    ctx.timezones.push({ Id: rowdata.Id, Name: rowdata.Name });
                                }
                            }
                        }
                        , Async: false
                    }, procsConnectionString);

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

                    that.checkBindings(); 
                    that.addValidations(); 

                    that.drawProfilesGrid(); 

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

                    //end:

                }, true, customPath);
            }, customPath, "user_panel");
        }
        , drawProfilesGrid: function () {
            try {
                var that = this;
                var writePermission = app.models.securityManager.getModuleActionValue("ihconfiguration_users", "write");

                var columns = [
                    {
                        label: app.translate(that, "profile_name_label"),
                        name: 'name',
                        editable: false, 
                        sortable: true,
                        cell: Backgrid.StringCell, 
                    }, 
                    {
                        name: "member",
                        label: app.translate(that, "profile_member_label"),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.Cell.extend({
                            template: _.template("<input class='grid-checkbox' tabindex='-1' type='checkbox' />"),
                            initialize: function () {
                                Backgrid.Cell.prototype.initialize.apply(this, arguments);
                            },
                            events: {
                                "change .grid-checkbox": "chkboxChanged",
                            },
                            chkboxChanged: function (e) {
                                this.model.set(this.column.get("name"), $(e.target).is(":checked"));
                            },
                            render: function () {
                                this.$el.html(this.template());
                                if (this.model.get(this.column.get("name"))) this.$el.find(".grid-checkbox").attr("checked", "checked");

                                if (!writePermission) this.$el.find(".grid-checkbox").attr("disabled", "disabled");

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

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

                this.options.grids.profileMemberships = grid;
                var grid_el = grid.render().el;
                that.$el.find(".user-profiles-grid-container").append(grid_el);
            } catch (error) {
                console.log(error); 
            }
        }
        , 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;
            }
        }

        , addValidations: function () {
            try {
                this.$el.find(".form-user-data input").jqBootstrapValidation({
                    filter: function () {
                        return $(this).is(":visible"); 
                    }
                });
            } catch (Error) { }
        }

        , saveChanges: function () {
            try {
                var that = this; 
                var submitted = false;

                $(".form-user-data").submit(function (e) {
                    e.preventDefault();
                    submitted = true;
                });
                $(".form-user-data").submit();

                if (submitted == false) {
                    return; 
                }

                var profileIds = _.map(this.model.get("profileMemberships").where({ member: true }), function (t) {
                    return t.get("id"); 
                });
                var profileIdsstr = profileIds.join(','); 



                var qps = {
                    UserID: { val: this.model.get("userId"), type: "INT" },
                    Name: { val: (this.model.lastFetchAttributes["name"] != this.model.get("name")) ? this.model.get("name") : null, type: "VARCHAR" },
                    LastName: { val: (this.model.lastFetchAttributes["lastname"] != this.model.get("lastname")) ? this.model.get("lastname") : null, type: "VARCHAR" },
                    Role: { val: (this.model.lastFetchAttributes["role"] != this.model.get("role")) ? this.model.get("role") : null, type: "VARCHAR" },
                    Timezone: { val: (this.model.lastFetchAttributes["timezone"] != this.model.get("timezone")) ? this.model.get("timezone") : null, type: "VARCHAR" },
                    Username: { val: (this.model.lastFetchAttributes["username"] != this.model.get("username")) ? this.model.get("username") : null, type: "VARCHAR" },
                    Password: { val: (this.model.get("changingPassword") == true) ? this.model.get("password") : null, type: "VARCHAR" },
                    ProfileIds: { val: profileIdsstr, type: "VARCHAR" },
                    DepartmentId: { val: document.getElementsByClassName("departmentSelect")[0].value, type: "INT" }
                };

                var QP = new QueryParameters();
                for (var i in qps)
                    QP.Add(i, qps[i].type, qps[i].val);

                Core.Json.CallProcedure(procsDB + ".FrontEnd.UpdateAccountUser", QP, {
                    onSuccess: function (data) {
                        if (Core.Object.Eval(data, "Table.0")) {
                            data = data.Table[0];
                            if (data.Status == 1) {
                                if (that.model.get("changingPassword") && app.models.user.get("userId") == that.model.get("userId")) {
                                    var password_changed = new Modal.Views.Main({
                                        id: "users-save-changes-success-modal"
                                        , title: that.options.i18n[that.template].translate("change_password_modal_success_security_measure_title").fetch()
                                        , message: that.options.i18n[that.template].translate("change_password_modal_success_security_measure").fetch()
                                        , allowCancel: false
                                        , buttons_type: "OK"
                                    });

                                    password_changed.on("continue", function () {
                                        app.router.logout();
                                    });

                                    password_changed.show();
                                } else {
                                    app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });
                                }
                            } else {
                                new Modal.Views.Main({
                                    id: "users-save-changes-error-modal"
                                    , title: "Error"
                                    , message: "Hubo un error al intentar guardar los cambios. "
                                    , allowCancel: false
                                    , buttons_type: "OK"
                                }).show();
                            }
                        }
                    },
                    Async: false,
                    Secured: true
                }, procsConnectionString);

            } catch (Error) {
            }
        }

        , cancelChanges: function () {
            try {
                app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });
            } catch (Error) {
            }
        }

        , goBack: function () {
            try {
                app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });
            } catch (Error) {
            }
        }

        , changePassword: function () {
            try {
                //if (this.model.get("userId") != app.models.user.get("userId")) {
                this.$el.find(".btn-change-password").attr("disabled", "disabled");
                this.$el.find(".password-section").removeClass("hide").addClass("show");
                this.model.set({ changingPassword: true }, { silent: true });
                //}
            } catch (Error) {
            }
        }
        , removeUser: function () {
            var that = this;
            try {
               

                //var userids = [];
                //var usernames = [];

                
                //userids.push(that.model.get("userId").toString());
                //usernames.push(that.model.get("username").toString());

                

                var modal = new Modal.Views.Main({
                    id: "remove-user-confirmation-modal"
                    , title: this.options.i18n[this.template].translate("remove_users_confirmation_title")
                        .fetch()
                    , message: this.options.i18n[this.template].translate("remove_users_confirmation_body")
                        //.ifPlural(usernames.length, "remove_users_confirmation_body_plural_")
                        .fetch(that.model.get('username'))
                    , allowCancel: true
                    , buttons_type: "CONTINUE-CANCEL"
                });

                this.listenToOnce(modal, "continue", function (modal) {
                    try {
                        var qps = {
                        UserID: { val: that.model.get('userId'), type: "VARCHAR" },
                        }; 
                        var QP = new QueryParameters();
                        QP.Add('@UserId', 'INT', that.model.get('userId'));
                        Core.Json.CallProcedure(procsDB + ".FrontEnd.RemoveAccountUser", QP, {
                        onSuccess: function (data) {
                                if (Core.Object.Eval(data, "Table")) {
                                    app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });
                                    app.views.topMessages.showMessage('User: ' + that.model.get('username') + ' deleted succesfully.', { stay: 2000, });
                                }
                                else {
                                    app.views.topMessages.showMessage(data.Message, { stay: 2000, });
                                }
                            },
                            onFailure: function (data) {
                                app.views.topMessages.showMessage(data.Message, { stay: 2000, });
                            },
                        Async: false,
                        Secured: true
                        }, procsConnectionString);

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

                modal.show();

                //modal.on("continue", _.bind(function () {

                //    var qps = {
                //        UserID: { val: userids.join(','), type: "VARCHAR" },
                //    };

                //    var QP = new QueryParameters();
                //    for (var i in qps)
                //        QP.Add(i, qps[i].type, qps[i].val);

                //    Core.Json.CallProcedure(procsDB + ".FrontEnd.RemoveAccountUsers", QP, {
                //        onSuccess: function (data) {
                //            if (Core.Object.Eval(data, "Table")) {
                //            }
                //        },
                //        Async: false,
                //        Secured: true
                //    }, procsConnectionString);

                //    this.refresh();

                //}, this));

                //modal.show();

            } catch (Error) { }
        }

        , checkBindings: function () {
            var that = this;
            var bindingelems = this.$el.find("[data-bindingtype]");

            bindingelems.each(function (i, elem) {
                $(elem).change(function (e) {
                    var elem = $(e.target);
                    var prop = elem.data("bindingprop");
                    var val = elem.val();

                    if (elem.is(":checkbox")) val = elem.is(":checked");

                    var attrs = {};
                    if (prop != null && prop != undefined && prop != "") {
                        attrs[prop] = val;
                        that.model.set(attrs, { silent: true });
                    }
                });
            });
        }

        , reRender: function (viewParams) {
            this.config_subnavbar(); 
            try {
                var userid = -1;

                if (viewParams) {
                    userid = (viewParams.sectionParam2 != null && viewParams.sectionParam2 != undefined)
                        ? viewParams.sectionParam2 : -1;
                }

                this.model.fetch({ data: { id: userid } });
            } catch (error) {
                console.error(error); 
            }
        }

        , refresh: function (viewParams) {
           
        }

        , 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, "change", this.render); 
        }

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

        , resetModel: function () {
            var defs = _.extend({}, _.omit(this.model.defaults, 'profileMemberships'));

            this.model.set(
                defs
            );

            this.model.get("profileMemberships").reset();

            //this.model.initialize();
        }

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

            this.resetModel(); 
            this.hideSubviews();

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

        , hideSubviews: function () {
            _.each(this.options.MYREFERENCES.subviews, function (sview) {
                sview.hide();
            });
        }
        , config_subnavbar: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("dateTimeScopeControl", false);
            app.models.subnavbar.set("sections", "4-4-4");
            app.models.subnavbar.set("subnavbar", false);
        }
        , preRender: function () {
            this.config_subnavbar(); 
        }
    });

    Users.Model.CreateUserPanel = Backbone.Model.extend({
        defaults: {
           userId: null,
           name: "",
           lastname: "",
           role: "BASICUSER",
           autologin: false,
           username: null,
           password: null,
           timezone: null, 
           screenmode: "CREATE",
           departments: null,
           departmentId: null,
           profileMemberships: null,
        }, 
        initialize: function () {
            if (!this.attributes.profileMemberships) this.attributes.profileMemberships = new Users.Collections.ProfileMemberships(); 
        }, 
    });

    Users.Views.CreateUserPanel = Backbone.View.extend({
        template: "users"
        , id: "users"
        , title: "Create User"
        //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 () { };

            var model = new Users.Model.CreateUserPanel({
            });
            model.get("profileMemberships").fetch(); 

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

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

            this.model = model;

            this.options.MYREFERENCES.subviews = {};

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

        events: {
            "click .btn-create-user": "createUser",
            "click .btn-cancel-create-user": "cancelCreateUser",
            "change .name-input, .lastname-input": "suggestUsername",
            //"change .username-input": "checkDomainUserInfo",
            "change .active-directory-input": "activeDirectoryChanged", 
        },

        render: function (container, viewParams) {
            var that = this;
            var thatContainer = 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/IHConfiguration/users/";

            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
                    if (!that.options.i18n[that.template])
                        that.options.i18n[that.template] = i18nJED;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    var ctx = {
                        timezones: [], 
                    };

                    var automatic_timezone_label = that.options.i18n[that.template].translate("timezone_automatic_label").fetch();
                    ctx.timezones.push({ Id: "AUTO", Name: automatic_timezone_label });

                    Core.Json.CallProcedure(procsDB + ".FrontEnd.GetTimezones", null, {
                        onSuccess: function (data) {
                            if (data.Table != null && data.Table != undefined) {
                                for (var i in data.Table) {
                                    var rowdata = data.Table[i];
                                    ctx.timezones.push({ Id: rowdata.Id, Name: rowdata.Name });
                                }
                            }
                        }
                       , Async: false
                    }, procsConnectionString);

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

                    that.checkBindings(); 
                    that.addValidations(); 

                    that.drawProfilesGrid(); 

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

                    //end:
                }, true, customPath);
            }, customPath, "user_panel");
        }

        , drawProfilesGrid: function () {
            try {
                var that = this;
                var writePermission =  app.models.securityManager.getModuleActionValue("ihconfiguration_users", "write"); 

                var columns = [
                    {
                        label: app.translate(that, "profile_name_label"),
                        name: 'name',
                        editable: false,
                        sortable: false,
                        cell: Backgrid.StringCell,
                    },
                    {
                        name: "member",
                        label: app.translate(that, "profile_member_label"),
                        editable: false,
                        sortable: false,
                        cell: Backgrid.Cell.extend({
                            template: _.template("<input class='grid-checkbox' tabindex='-1' type='checkbox' />"),
                            initialize: function () {
                                Backgrid.Cell.prototype.initialize.apply(this, arguments);
                            },
                            events: {
                                "change .grid-checkbox": "chkboxChanged",
                            },
                            chkboxChanged: function (e) {
                                this.model.set(this.column.get("name"), $(e.target).is(":checked"));
                            },
                            render: function () {
                                this.$el.html(this.template());
                                if (this.model.get(this.column.get("name"))) this.$el.find(".grid-checkbox").attr("checked", "checked");

                                if (!writePermission) this.$el.find(".grid-checkbox").attr("disabled", "disabled"); 

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

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

                this.options.grids.profileMemberships = grid;
                var grid_el = grid.render().el;
                that.$el.find(".user-profiles-grid-container").append(grid_el);
            } catch (error) {
                console.log(error);
            }
        }

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

        , checkBindings: function () {
            var that = this; 
            var bindingelems = this.$el.find("[data-bindingtype]");

            bindingelems.each(function (i, elem) {
                $(elem).change(function (e) {
                    var elem = $(e.target);
                    var prop = elem.data("bindingprop"); 
                    var val = elem.val(); 
                    
                    if (elem.is(":checkbox")) val = elem.is(":checked"); 

                    var attrs = {};
                    if (prop != null && prop != undefined && prop != "") {
                        attrs[prop] = val;
                        that.model.set(attrs, { silent: true });
                    }
                }); 
            }); 
        }

        , addValidations: function () {
            try {
                this.$el.find(".form-user-data input").jqBootstrapValidation("destroy");
                this.$el.find(".form-user-data input").jqBootstrapValidation({
                    filter: function () {
                        return $(this).is(":visible");
                    }
                });
            } catch (Error) { }
        }

        , createUser: function () {
            try {

                var submitted = false; 
                $(".form-user-data").submit(function (e) { e.preventDefault(); submitted = true; });
                $(".form-user-data").submit(); 

                if (!submitted) {
                    return;
                }

                //if (this.$el.find(".form-user-data").jqBootstrapValidation("hasErrors")) {
                //    return; 
                //}
                
                var profileIds = _.map(this.model.get("profileMemberships").where({ member: true }), function (t) {
                    return t.get("id");
                });
                var profileIdsstr = profileIds.join(',');

                var qps = {
                    Name: { val: this.model.get("name"), type: "VARCHAR" }, 
                    LastName: { val: this.model.get("lastname"), type: "VARCHAR" }, 
                    Role: { val: this.model.get("role"), type: "VARCHAR" },
                    Timezone: { val: this.model.get("timezone"), type: "VARCHAR" },
                    Username: { val: this.model.get("username"), type: "VARCHAR" }, 
                    Password: { val: this.model.get("password") != null ? this.model.get("password") : "", type: "VARCHAR" },
                    Autologin: { val: this.model.get("autologin"), type: "BIT" },
                    ProfileIds: { val: profileIdsstr, type: "VARCHAR" },
                };

                var QP = new QueryParameters();
                for (var i in qps)
                    QP.Add(i, qps[i].type, qps[i].val);

                Core.Json.CallProcedure(procsDB + ".FrontEnd.CreateAccountUser", QP, {
                    onSuccess: function (data) {
                        if (Core.Object.Eval(data, "Table")) {
                            
                            data = data.Table[0];
                            if (data.Status == 1) {
                              //  app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });

                                app.views.topMessages.showMessage('The user was successfully created', { stay: 5000, });                                    
                            } else {
                                new Modal.Views.Main({
                                    id: "users-create-error-modal"
                                    , title: "Error"
                                    , message: "There was an error while creating the user. "
                                    , allowCancel: false
                                    , buttons_type: "OK"
                                }).show();
                                
                            }
                            app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });

                           
                        }
                    },
                    Async: false,
                    Secured: true
                }, procsConnectionString);

            } catch (Error) { }
        }

        , cancelCreateUser: function () {
            try{
                app.router.navigate(app.router.resolveURL(app.router.currentModule, { section: "users" }, false), { trigger: true });
            } catch (Error) { }
        }

        , suggestUsername: function (e) {
            var name = this.model.get("name");
            var lastname = this.model.get("lastname");
            var autologin = this.model.get("autologin");
            var username = ""; 

            if (!autologin) {
                if (lastname != null && lastname != undefined && $.trim(lastname) != "") {
                    if (name.length > 0) username += name.substring(0, 1);
                    username += lastname;
                } else {
                    username += name;
                }

                username = username.replace(/\s/g, "").toLowerCase();

                this.model.set({ "username": username }, { silent: true });
                this.$el.find(".username-input").val(username);
            }
        }

        , activeDirectoryChanged: function (e) {
            var target = $(e.target);
            var checked = (target.is(":checkbox")) ? target.is(":checked") : false;

            this.checkActiveDirectoryMode(checked); 
        }

        , checkActiveDirectoryMode: function (val) {
            var usr = this.$el.find(".username-input");
            if (!val) { this.suggestUsername(); } else { usr.val(""); }
            this.$el.find(".password-section").find("input").val("");

            if (val) {
                usr.data("validation-regex-regex", "^[a-zA-Z][a-zA-Z0-9_\\-\\.]{1,61}[a-zA-Z]\\\\[a-zA-Z0-9_\\-\\.]{2,}$");
                usr.data("validation-regex-message", app.translate(this, app.translate(this, "autologin_regex_helper")));

                usr.attr("placeholder", app.translate(this, "placeholder_username_domain"));

                this.$el.find(".password-section").addClass("hide");
            } else {
                usr.removeData("validation-regex-regex");
                usr.removeData("validation-regex-message");

                usr.attr("placeholder", app.translate(this, "placeholder_username"));
                
                this.$el.find(".password-section").removeClass("hide");
            }

            this.addValidations(); 
        }

        , checkDomainUserInfo: function () {
            var autologin = this.model.get("autologin"); 
            var domainUser = this.$el.find('.domain-user-spans');
            var usernameInput = this.$el.find(".username-input"); 
            
            if (autologin) {
                var userValue = (_.isString(usernameInput.val())) ? usernameInput.val().split("\\") : []; 
                var domain = userValue.length > 0 ? userValue[0] : "";
                var user = userValue.length > 1 ? userValue[1] : "";

                domainUser.find(".domain-span").text(domain);
                domainUser.find(".domain-user-span").text(user);

                domainUser.removeClass("hide"); 
            } else {
                domainUser.addClass("hide");
            }
        }

        , reRender: function (viewParams) {
            try {
                this.model.get("profileMemberships").fetch(); 
            } catch (Error) { }
        }

        , refresh: function (viewParams) {
        }

        , 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, "change", this.render);
        }

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

        , resetModel: function () {
            var defs = _.extend({}, _.omit(this.model.defaults, 'profileMemberships'));

            this.model.set(
                defs
            );

            this.model.get("profileMemberships").reset(); 

            //this.model.initialize();
        }

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

            this.resetModel();
            this.hideSubviews();

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

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

        , preRender: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("dateTimeScopeControl", false);
            app.models.subnavbar.set("sections", "4-4-4");
            app.models.subnavbar.set("subnavbar", true);
        }
    });

    Users.Model.Main = Backbone.Model.extend({
        defaults: {
            procedure: '',
            screenModules: {
                "userslist": Users.Views.UsersList,
                "userpanel": Users.Views.UserPanel,
                "createuserpanel": Users.Views.CreateUserPanel, 
            }, 
        }
    });

    //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.
    Users.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "users"; 
        } catch (Error) { }
    }

    Users.Views.Main = Backbone.View.extend({
        template: "users"
        , id: "users"
        , title: "Users"
        //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 Users.Model.Main({
                procedure: "dbo.procedureName"
            });

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

            this.model = model;

            this.options.MYREFERENCES.subviews = {};

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

        events: {
            'keyup #searchUsersInput': 'filterUsersList',
        }, 

        render: function (container, viewParams) {
            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/IHConfiguration/users/";

            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;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)

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

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

                    that.refresh(viewParams);

                    //end:

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

        , refresh: function (viewParams) {
            try {

                for (var view in this.options.MYREFERENCES.subviews) {
                    this.options.MYREFERENCES.subviews[view].hide();
                }

                //default action
                var action = "userslist"; 

                //parsing uri params
                var params = {
                    "user": "userpanel",
                    "new": "createuserpanel", 
                }; 

                if (viewParams && viewParams.sectionParam1) {
                    if (params[viewParams.sectionParam1])
                        action = params[viewParams.sectionParam1]; 
                }

                if (!this.options.MYREFERENCES.subviews[action]) {
                    var module = this.model.get("screenModules")[action];
                    if (module != null && module != undefined) {
                        this.options.MYREFERENCES.subviews[action] = new module({
                            parent: this,
                            container: this.$el.find("#users_screen_container"),
                            viewParams: viewParams
                        });

                        this.options.MYREFERENCES.subviews[action].preRender(viewParams); 
                        this.options.MYREFERENCES.subviews[action].render(null, viewParams);
                    }
                } else {
                    var screen = this.options.MYREFERENCES.subviews[action];

                    screen.show();
                    screen.reRender(viewParams);
                }

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

        , 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.$el.hide();
            this.unbind();
            this.stopListening();
        }

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

        , preRender: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("dateTimeScopeControl", false);

            app.models.subnavbar.set("sections", "4-4-4"); 
            app.models.subnavbar.set("subnavbar", true);
        }

        , reRender: function (viewParams) {
            this.refresh(viewParams); 
        }

        , filterUsersList: function () {
            var input, filter, ul, liList, i, txtValue;
            input = document.getElementById("searchUsersInput");
            filter = input.value.toUpperCase();
            ul = document.getElementsByClassName('users-table')[0];
            tr = ul.getElementsByTagName("tr");

            for (i = 0; i < tr.length; i++) {
                tdName = tr[i].getElementsByTagName("td")[0];
                tdUsername = tr[i].getElementsByTagName("td")[1]
                if (tdName || tdUsername) {
                    txtNameValue = tdName.textContent || tdName.innerText;
                    txtUsernameValue = tdUsername.textContent || tdUsername.innerText;
                    if (txtNameValue.toUpperCase().indexOf(filter) > -1 || txtUsernameValue.toUpperCase().indexOf(filter) > -1) {
                        tr[i].style.display = "";
                    } else {
                        tr[i].style.display = "none";
                    }
                }
            }

        }
    });

    //subview for the subnavbar controls
    Users.Views.SubnavBarControls = Backbone.View.extend({
        id: "users-subnavbar-controls"
        , title: ""
        , template: "users"
        , 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.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/IHConfiguration/users/";

            T.render.call(this, this.template, function (tmp) {

                var ctx = {
                    currentRoute: app.router.currentRoute
                };

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

                that.append(thatContainer, that.$el); 

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

        , toolbarDelete: function (status) {
            var toolbardelete = this.$el.find(".btn-toolbar-remove-user");
            if (status == true) toolbardelete.removeClass("hide");
            else toolbardelete.addClass("hide");
        }

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

});

