define([
  // Application.
  "app",
],

function (app) {

    var MenuManager = { Models: {}, Collections: {}, };

    MenuManager.init = function (ctx, module, app) {
        //app.models.menuManager = new module.Model();
        //app.models.menuManager.start();
    }; 

    MenuManager.Models.Item = Backbone.Model.extend({
        defaults: {
            id: null,
            name: null,
            route: null, 
            href: null,
            navigable: null,
            enabled: false,
            visible: false,
            requiredRole: null,
            group: null, 
        },
    });

    MenuManager.Collections.Items = Backbone.Collection.extend({
        model: MenuManager.Models.Item,
        fetch: function (opt) {
            var options = {
                method: "set",
                async: true,
                callback: null,
            };

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

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

            Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.GetUserSecurityModulesActions", QP, {
                onSuccess: function (response) {
                    if (response && response.Table) {
                        var records = response.Table;
                        var actions = response.Table1;

                        var mdls = [];
                        var actionsMdls = {};

                        for (var i = 0, len = records.length; i < len; i++) {
                            var data = records[i];
                            var obj = _.clone(MenuManager.Models.Module.prototype.defaults);

                            var obj = {
                                id: data.ModuleId,
                                code: data.Code,
                                name: data.Name,
                                value: data.Value,
                            };

                            mdls.push(obj);
                        }

                        for (var i = 0, len = actions.length; i < len; i++) {
                            var data = actions[i];

                            var obj = {
                                id: data.ActionId,
                                code: data.Code,
                                name: data.Name,
                                value: data.Value,
                            };

                            if (!actionsMdls[data.ModuleId]) actionsMdls[data.ModuleId] = [];
                            actionsMdls[data.ModuleId].push(obj);
                        }

                        that[options.method](mdls);
                        that.each(function (t) {
                            var acs = actionsMdls[t.get("id")];
                            t.get("actions").set(acs);
                        });

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

            return this;
        }, 
    }); 

    MenuManager.Model = Backbone.Model.extend({
        defaults: {
            modules: null, 
        },
        toid: null,
        delay: 1000 * 5,
        refreshing: false,
        initialize: function ()
        {
            this.attributes.modules = new MenuManager.Collections.Modules(); 

            _.bindAll(this);
            this.bindEvents(); 
        },
        bindEvents: function () {
        }, 
        fetch: function (opt)
        {
            try
            {
                clearTimeout(this.toid);
                
                this.get('modules').fetch(opt);
            }
            catch (Error) { console.error(Error); }
            finally
            {
                if (this.refreshing)
                    this.toid = setTimeout(this.fetch, this.delay);
            }
        },
        start: function ()
        {
            if (!this.refreshing)
            {
                this.refreshing = true;

                this.fetch({ method: "reset" });
            }

            return this;
        },
        stop: function ()
        {
            clearTimeout(this.toid);

            this.refreshing = false;

            return this;
        },
        getModule: function (code) {
            try {
                var modules = this.get("modules").filter(function (t) {
                    return t.get("code").toUpperCase() == code.toUpperCase();
                });

                return modules.length > 0 ? modules[0] : null; 
            } catch (error) {
                return null; 
            }
        },
        getModuleAction: function (module, actionCode) {
            try{
                var module = (_.isString(module)) ? this.getModule(module) : module;
                if (module) {
                    var actions = module.get("actions").filter(function (t) {
                        return t.get("code").toUpperCase() == actionCode.toUpperCase();
                    });

                    return actions.length > 0 ? actions[0] : null; 
                }
            } catch (error) {
                console.log(error); 
            }

            return null; 
        }, 
        getModuleActionValue: function (moduleCode, actionCode) {
            /// <param name="moduleCode" type="String">module code</param>
            /// <param name="actionCode" type="String">action code</param>
            /// <returns type="Boolean" />
            try {
                var module = this.getModule(moduleCode);
                if (module && module.get("value") == true) {
                    var action = this.getModuleAction(module, actionCode);

                    return (action) ? action.get("value") : false; 
                }
            } catch (error) {
                console.log(error); 
            }

            return false; 
        }, 
    });

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

});
