(function () {

'use strict';

angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])

.config([
    'mainMenuProvider',
    'gettext',
    function (mainMenuProvider, gettext) {
        mainMenuProvider.register({
            'ui_sref': 'users.user.list',
            'img_class': 'user',
            'title': gettext('Participants'),
            'weight': 500,
            'perm': 'users.can_see_name',
        });
    }
])

.config([
    '$stateProvider',
    function($stateProvider) {
        $stateProvider
        .state('users', {
            url: '/users',
            abstract: true,
            template: "<ui-view/>",
        })
        .state('users.user', {
            abstract: true,
            template: "<ui-view/>",
        })
        .state('users.user.list', {
            resolve: {
                users: function(User) {
                    return User.findAll();
                },
                groups: function(Group) {
                    return Group.findAll();
                }
            }
        })
        .state('users.user.create', {
            resolve: {
                groups: function(Group) {
                    return Group.findAll();
                }
            }
        })
        .state('users.user.detail', {
            resolve: {
                user: function(User, $stateParams) {
                    return User.find($stateParams.id);
                },
                groups: function(Group) {
                    return Group.findAll();
                }
            }
        })
        // Redirects to user detail view and opens user edit form dialog, uses edit url.
        // Used by $state.go(..) from core/site.js only (for edit current slide button).
        // (from users list controller use UserForm factory instead to open dialog in front of
        // current view without redirect)
        .state('users.user.detail.update', {
            onEnter: ['$stateParams', '$state', 'ngDialog', 'User',
                function($stateParams, $state, ngDialog, User) {
                    ngDialog.open({
                        template: 'static/templates/users/user-form.html',
                        controller: 'UserUpdateCtrl',
                        className: 'ngdialog-theme-default wide-form',
                        closeByEscape: false,
                        closeByDocument: false,
                        resolve: {
                            user: function() {return User.find($stateParams.id);}
                        }
                    });
                }
            ]
        })
        .state('users.user.detail.profile', {
            views: {
                '@users.user': {},
            },
            url: '/profile',
            controller: 'UserProfileCtrl',
        })
        .state('users.user.detail.password', {
            views: {
                '@users.user': {},
            },
            url: '/password',
            controller: 'UserPasswordCtrl',
        })
        .state('users.user.import', {
            url: '/import',
            controller: 'UserImportCtrl',
            resolve: {
                groups: function(Group) {
                    return Group.findAll();
                }
            }
        })
        // groups
        .state('users.group', {
            url: '/groups',
            abstract: true,
            template: "<ui-view/>",
        })
        .state('users.group.list', {
            resolve: {
                groups: function(Group) {
                    return Group.findAll();
                }
            }
        })
        .state('users.group.create', {
            resolve: {
                permissions: function(Group) {
                    return Group.getPermissions();
                }
            }
        })
        .state('users.group.detail', {
            resolve: {
                group: function(Group, $stateParams) {
                    return Group.find($stateParams.id);
                },
                permissions: function(Group) {
                    return Group.getPermissions();
                }
            }
        })
        .state('users.group.detail.update', {
            views: {
                '@users.group': {}
            },
            resolve: {
                permissions: function(Group) {
                    return Group.getPermissions();
                }
            }
        })
        .state('login', {
            template: null,
            url: '/login',
            params: { guest_enabled: false },
            onEnter: ['$state', '$stateParams', 'ngDialog', function($state, $stateParams, ngDialog) {
                ngDialog.open({
                    template: 'static/templates/core/login-form.html',
                    controller: 'LoginFormCtrl',
                    showClose: $stateParams.guest_enabled,
                    closeByEscape: $stateParams.guest_enabled,
                    closeByDocument: $stateParams.guest_enabled,
                });
            }]
        });
    }
])

.run([
    'operator',
    '$rootScope',
    '$http',
    '$state',
    'Group',
    function(operator, $rootScope, $http, $state, Group) {
        // Put the operator into the root scope
        $http.get('/users/whoami/').success(function(data) {
            operator.setUser(data.user_id);
            $rootScope.guest_enabled = data.guest_enabled;
            if (data.user_id === null && !data.guest_enabled) {
                // redirect to login dialog if use is not logged in
                $state.go('login', {guest_enabled: data.guest_enabled});
            }
        });
        $rootScope.operator = operator;
        // Load all Groups. They are needed later
        Group.findAll();
    }
])

/*
 * Directive to check for permissions
 *
 * This is the Code from angular.js ngIf.
 *
 * TODO: find a way not to copy the code.
*/
.directive('osPerms', [
    '$animate',
    function($animate) {
        return {
            multiElement: true,
            transclude: 'element',
            priority: 600,
            terminal: true,
            restrict: 'A',
            $$tlb: true,
            link: function($scope, $element, $attr, ctrl, $transclude) {
                var block, childScope, previousElements, perms;
                if ($attr.osPerms[0] === '!') {
                    perms = _.trimLeft($attr.osPerms, '!');
                } else {
                    perms = $attr.osPerms;
                }
                $scope.$watch(
                    function (scope) {
                        return scope.operator.hasPerms(perms);
                    },
                    function (value) {
                        if ($attr.osPerms[0] === '!') {
                            value = !value;
                        }
                        if (value) {
                            if (!childScope) {
                                $transclude(function(clone, newScope) {
                                    childScope = newScope;
                                    clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
                                    // Note: We only need the first/last node of the cloned nodes.
                                    // However, we need to keep the reference to the jqlite wrapper as it might be changed later
                                    // by a directive with templateUrl when its template arrives.
                                    block = {
                                        clone: clone
                                    };
                                    $animate.enter(clone, $element.parent(), $element);
                                });
                            }
                        } else {
                            if (previousElements) {
                                previousElements.remove();
                                previousElements = null;
                            }
                            if (childScope) {
                                childScope.$destroy();
                                childScope = null;
                            }
                            if (block) {
                                previousElements = getBlockNodes(block.clone);
                                $animate.leave(previousElements).then(function() {
                                    previousElements = null;
                                });
                                block = null;
                            }
                        }
                    }
                );
            }
        };
    }
])

// Service for generic assignment form (create and update)
.factory('UserForm', [
    '$http',
    'gettextCatalog',
    'Editor',
    'Group',
    'Mediafile',
    function ($http, gettextCatalog, Editor, Group, Mediafile) {
        return {
            // ngDialog for user form
            getDialog: function (user) {
                var resolve;
                if (user) {
                    resolve = {
                        user: function(User) {return User.find(user.id);}
                    };
                }
                return {
                    template: 'static/templates/users/user-form.html',
                    controller: (user) ? 'UserUpdateCtrl' : 'UserCreateCtrl',
                    className: 'ngdialog-theme-default wide-form',
                    closeByEscape: false,
                    closeByDocument: false,
                    resolve: (resolve) ? resolve : null
                };
            },
            // angular-formly fields for user form
            getFormFields: function (hideOnCreateForm) {
                var images = Mediafile.getAllImages();
                return [
                {
                    key: 'username',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Username')
                    },
                    hide: hideOnCreateForm
                },
                {
                    key: 'title',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Title'),
                        description: gettextCatalog.getString('Will be shown before the name.')
                    }
                },
                {
                    key: 'first_name',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('First name')
                    }
                },
                {
                    key: 'last_name',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Last name')
                    }
                },
                {
                    key: 'structure_level',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Structure level'),
                        description: gettextCatalog.getString('Will be shown after the name.')
                    }
                },
                {
                    key: 'groups_id',
                    type: 'select-multiple',
                    templateOptions: {
                        label: gettextCatalog.getString('Groups'),
                        options: Group.getAll(),
                        ngOptions: 'option.id as option.name | translate for option in to.options | ' +
                                   'filter: {id: "!1"} | filter: {id: "!2"}',
                        placeholder: gettextCatalog.getString('Select or search a group ...')
                    }
                },
                {
                    key: 'default_password',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Default password'),
                        description: '',
                        addonRight: { text: 'Reset', class: 'fa fa-undo', onClick:
                            function (options, scope) {
                                $http.post(
                                    '/rest/users/user/' + scope.model.id + '/reset_password/',
                                    {'password': scope.model.default_password})
                                .then(function() {
                                    options.templateOptions.description =
                                        gettextCatalog.getString('Password successfully resetted to:') +
                                        ' ' + scope.model.default_password;
                                });
                            }
                        }
                    }
                },
                {
                    key: 'comment',
                    type: 'input',
                    templateOptions: {
                        label: gettextCatalog.getString('Comment'),
                        description: gettextCatalog.getString('Only for notes.')
                    }
                },
                {
                    key: 'about_me',
                    type: 'editor',
                    templateOptions: {
                        label: gettextCatalog.getString('About me'),
                    },
                    data: {
                        tinymceOption: Editor.getOptions(images)
                    }
                },
                {
                    key: 'is_present',
                    type: 'checkbox',
                    templateOptions: {
                        label: gettextCatalog.getString('Is present'),
                        description: gettextCatalog.getString('Designates whether this user is in the room or not.')
                    },
                    defaultValue: true
                },
                {
                    key: 'is_active',
                    type: 'checkbox',
                    templateOptions: {
                        label: gettextCatalog.getString('Is active'),
                        description: gettextCatalog.getString(
                            'Designates whether this user should be treated as ' +
                            'active. Unselect this instead of deleting the account.')
                    },
                    defaultValue: true
                }];
            }
        };
    }
])

.controller('UserListCtrl', [
    '$scope',
    '$state',
    'ngDialog',
    'UserForm',
    'User',
    'Group',
    function($scope, $state, ngDialog, UserForm, User, Group) {
        User.bindAll({}, $scope, 'users');
        Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups');
        $scope.alert = {};
        $scope.groupFilter = undefined;

        // setup table sorting
        $scope.sortColumn = 'first_name'; //TODO: sort by first OR last name
        $scope.filterPresent = '';
        $scope.reverse = false;
        // function to sort by clicked column
        $scope.toggleSort = function ( column ) {
            if ( $scope.sortColumn === column ) {
                $scope.reverse = !$scope.reverse;
            }
            $scope.sortColumn = column;
        };

        // pagination
        $scope.currentPage = 1;
        $scope.itemsPerPage = 100;
        $scope.limitBegin = 0;
        $scope.pageChanged = function() {
            $scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
        };

        // open new/edit dialog
        $scope.openDialog = function (user) {
            ngDialog.open(UserForm.getDialog(user));
        };
        // save changed user
        $scope.save = function (user) {
            User.save(user).then(
                function(success) {
                    //user.quickEdit = false;
                    $scope.alert.show = false;
                },
                function(error){
                    var message = '';
                    for (var e in error.data) {
                        message += e + ': ' + error.data[e] + ' ';
                    }
                    $scope.alert = { type: 'danger', msg: message, show: true };
                });
        };
        // *** select mode functions ***
        $scope.isSelectMode = false;
        // check all checkboxes
        $scope.checkAll = function () {
            angular.forEach($scope.users, function (user) {
                user.selected = $scope.selectedAll;
            });
        };
        // uncheck all checkboxes if isSelectMode is closed
        $scope.uncheckAll = function () {
            if (!$scope.isSelectMode) {
                $scope.selectedAll = false;
                angular.forEach($scope.users, function (user) {
                    user.selected = false;
                });
            }
        };
        // delete all selected users
        $scope.deleteMultiple = function () {
            angular.forEach($scope.users, function (user) {
                if (user.selected) {
                    User.destroy(user.id);
                }
            });
            $scope.isSelectMode = false;
            $scope.uncheckAll();
        };
        // delete single user
        $scope.delete = function (user) {
            User.destroy(user.id);
        };
        // add group for selected users
        $scope.addGroupMultiple = function (group) {
            angular.forEach($scope.users, function (user) {
                if (user.selected) {
                    user.groups_id.push(group);
                    User.save(user);
                }
            });
            $scope.isSelectMode = false;
            $scope.uncheckAll();
        };
        // remove group for selected users
        $scope.removeGroupMultiple = function (group) {
            angular.forEach($scope.users, function (user) {
                if (user.selected) {
                    var groupIndex = user.groups_id.indexOf(parseInt(group));
                    if (groupIndex > -1) {
                        user.groups_id.splice(groupIndex, 1);
                        User.save(user);
                    }
                }
            });
            $scope.isSelectMode = false;
            $scope.uncheckAll();
        };
    }
])

.controller('UserDetailCtrl', [
    '$scope',
    'ngDialog',
    'UserForm',
    'User',
    'user',
    'Group',
    function($scope, ngDialog, UserForm, User, user, Group) {
        User.bindOne(user.id, $scope, 'user');
        Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups');

        // open edit dialog
        $scope.openDialog = function (user) {
            ngDialog.open(UserForm.getDialog(user));
        };
    }
])

.controller('UserCreateCtrl', [
    '$scope',
    '$state',
    'User',
    'UserForm',
    'Group',
    function($scope, $state, User, UserForm, Group) {
        Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups');
        $scope.alert = {};
        // get all form fields
        $scope.formFields = UserForm.getFormFields(true);

        // save user
        $scope.save = function (user) {
            if (!user.groups_id) {
                user.groups_id = [];
            }
            User.create(user).then(
                function(success) {
                    $scope.closeThisDialog();
                },
                function (error) {
                    var message = '';
                    for (var e in error.data) {
                        message += e + ': ' + error.data[e] + ' ';
                    }
                    $scope.alert = {type: 'danger', msg: message, show: true};
                }
            );
        };
    }
])

.controller('UserUpdateCtrl', [
    '$scope',
    '$state',
    '$http',
    'User',
    'UserForm',
    'Group',
    'user',
    function($scope, $state, $http, User, UserForm, Group, user) {
        Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups');
        $scope.alert = {};
        // set initial values for form model by create deep copy of user object
        // so list/detail view is not updated while editing
        $scope.model = angular.copy(user);

        // get all form fields
        $scope.formFields = UserForm.getFormFields();

        // save user
        $scope.save = function (user) {
            if (!user.groups_id) {
                user.groups_id = [];
            }
            // inject the changed user (copy) object back into DS store
            User.inject(user);
            // save change user object on server
            User.save(user).then(
                function (success) {
                    $scope.closeThisDialog();
                },
                function (error) {
                    // save error: revert all changes by restore
                    // (refresh) original user object from server
                    User.refresh(user);
                    var message = '';
                    for (var e in error.data) {
                        message += e + ': ' + error.data[e] + ' ';
                    }
                    $scope.alert = {type: 'danger', msg: message, show: true};
                }
            );
        };
    }
])

.controller('UserProfileCtrl', [
    '$scope',
    '$state',
    'Editor',
    'User',
    'user',
    function($scope, $state, Editor, User, user) {
        $scope.user = user;  // autoupdate is not activated
        $scope.tinymceOption = Editor.getOptions();
        $scope.save = function (user) {
            User.save(user, { method: 'PATCH' }).then(
                function(success) {
                    $state.go('users.user.list');
                },
                function(error) {
                    $scope.formError = error;
                }
            );
        };
    }
])

.controller('UserPasswordCtrl', [
    '$scope',
    '$state',
    '$http',
    'user',
    function($scope, $state, $http, user) {
        $scope.user = user;  // autoupdate is not activated
        $scope.save = function (user) {
            if ($scope.newPassword != $scope.newPassword2) {
                $scope.newPassword = $scope.newPassword2 = '';
                $scope.formError = 'Password confirmation does not match.';
            } else {
                $http.post(
                    '/users/setpassword/',
                    {'old_password': $scope.oldPassword, 'new_password': $scope.newPassword}
                ).then(
                    function (response) {
                        // Success.
                        $state.go('users.user.list');
                    },
                    function (response) {
                        // Error, e. g. wrong old password.
                        $scope.oldPassword = $scope.newPassword = $scope.newPassword2 = '';
                        $scope.formError = response.data.detail;
                    }
                );
            }
        };
    }
])

.controller('UserImportCtrl', [
    '$scope',
    'gettext',
    'User',
    'Group',
    function($scope, gettext, User, Group) {
        // import from textarea
        $scope.importByLine = function () {
            $scope.usernames = $scope.userlist[0].split("\n");
            $scope.importcounter = 0;
            $scope.usernames.forEach(function(name) {
                // Split each full name in first and last name.
                // The last word is set as last name, rest is the first name(s).
                // (e.g.: "Max Martin Mustermann" -> last_name = "Mustermann")
                var names = name.split(" ");
                var last_name = names.slice(-1)[0];
                var first_name = names.slice(0, -1).join(" ");
                var user = {
                    first_name: first_name,
                    last_name: last_name,
                    groups_id: []
                };
                User.create(user).then(
                    function(success) {
                        $scope.importcounter++;
                    }
                );
            });
        };

        // *** csv import ***
        // set initial data for csv import
        $scope.users = [];
        $scope.separator = ',';
        $scope.encoding = 'UTF-8';
        $scope.encodingOptions = ['UTF-8', 'ISO-8859-1'];
        $scope.csv = {
            content: null,
            header: true,
            headerVisible: false,
            separator: $scope.separator,
            separatorVisible: false,
            encoding: $scope.encoding,
            encodingVisible: false,
            result: null
        };
        // set csv file encoding
        $scope.setEncoding = function () {
            $scope.csv.encoding = $scope.encoding;
        };
        // set csv file encoding
        $scope.setSeparator = function () {
            $scope.csv.separator = $scope.separator;
        };
        // pagination
        $scope.currentPage = 1;
        $scope.itemsPerPage = 100;
        $scope.limitBegin = 0;
        $scope.pageChanged = function() {
            $scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
        };
        // detect if csv file is loaded
        $scope.$watch('csv.result', function () {
            $scope.users = [];
            var quotionRe = /^"(.*)"$/;
            angular.forEach($scope.csv.result, function (user) {
                // title
                if (user.title) {
                    user.title = user.title.replace(quotionRe, '$1');
                }
                // first name
                if (user.first_name) {
                    user.first_name = user.first_name.replace(quotionRe, '$1');
                }
                // last name
                if (user.last_name) {
                    user.last_name = user.last_name.replace(quotionRe, '$1');
                }
                if (!user.first_name && !user.last_name) {
                    user.importerror = true;
                    user.name_error = gettext('Error: First or last name is required.');
                }
                // structure level
                if (user.structure_level) {
                    user.structure_level = user.structure_level.replace(quotionRe, '$1');
                }
                // groups
                if (user.groups) {
                    var csvGroups = user.groups.replace(quotionRe, '$1').split(",");
                    user.groups_id = [];
                    user.groupnames = [];
                    if (csvGroups !== '') {
                        // All group objects are already loaded via the resolve statement from ui-router.
                        var allGroups = Group.getAll();
                        csvGroups.forEach(function(csvGroup) {
                            allGroups.forEach(function (allGroup) {
                                if (csvGroup == allGroup.id) {
                                    user.groups_id.push(allGroup.id);
                                    user.groupnames.push(allGroup.name);
                                }
                            });
                        });
                    }
                } else {
                    user.groups_id = [];
                }
                // comment
                if (user.comment) {
                    user.comment = user.comment.replace(quotionRe, '$1');
                }
                // is active
                if (user.is_active) {
                    user.is_active = user.is_active.replace(quotionRe, '$1');
                    if (user.is_active == '1') {
                        user.is_active = true;
                    } else {
                        user.is_active = false;
                    }
                } else {
                    user.is_active = false;
                }
                $scope.users.push(user);
            });
        });

        // import from csv file
        $scope.import = function () {
            $scope.csvImporting = true;
            angular.forEach($scope.users, function (user) {
                if (!user.importerror) {
                    User.create(user).then(
                        function(success) {
                            user.imported = true;
                        }
                    );
                }
            });
            $scope.csvimported = true;
        };
        $scope.clear = function () {
            $scope.csv.result = null;
        };
        // download CSV example file
        $scope.downloadCSVExample = function () {
            var element = document.getElementById('downloadLink');
            var csvRows = [
                // column header line
                ['title', 'first_name', 'last_name', 'structure_level', 'groups', 'comment', 'is_active'],
                // example entries
                ['Dr.', 'Max', 'Mustermann', 'Berlin', '"3,4"', 'xyz', '1'],
                ['', 'John', 'Doe', 'Washington', '3', 'abc', '1'],
                ['', 'Fred', 'Bloggs', 'London', '', '', ''],

            ];
            var csvString = csvRows.join("%0A");
            element.href = 'data:text/csv;charset=utf-8,' + csvString;
            element.download = 'users-example.csv';
            element.target = '_blank';
        };
    }
])

.controller('GroupListCtrl', [
    '$scope',
    'Group',
    function($scope, Group) {
        Group.bindAll({}, $scope, 'groups');

        // delete selected group
        $scope.delete = function (group) {
            Group.destroy(group.id);
        };
    }
])

.controller('GroupCreateCtrl', [
    '$scope',
    '$state',
    'Group',
    'permissions',
    function($scope, $state, Group, permissions) {
        // get all permissions
        $scope.permissions = permissions;
        $scope.group = {};
        $scope.save = function (group) {
            if (!group.permissions) {
                group.permissions = [];
            }
            Group.create(group).then(
                function(success) {
                    $state.go('users.group.list');
                }
            );
        };
    }
])

.controller('GroupUpdateCtrl', [
    '$scope',
    '$state',
    'Group',
    'permissions',
    'group',
    function($scope, $state, Group, permissions, group) {
        // get all permissions
        $scope.permissions = permissions;
        $scope.group = group;  // autoupdate is not activated
        $scope.save = function (group) {
            Group.save(group).then(
                function(success) {
                    $state.go('users.group.list');
                }
            );
        };
    }
])

.controller('GroupDetailCtrl', [
    '$scope',
    'Group',
    'group',
    'permissions',
    function($scope, Group, group, permissions) {
        Group.bindOne(group.id, $scope, 'group');
        $scope.groupPermissionNames = [];
        // get display names of group permissions
        // from an object array with all available permissions [{display_name, value}]
        angular.forEach(group.permissions, function(permValue) {
            angular.forEach(permissions, function(p) {
                if (p.value == permValue) {
                    $scope.groupPermissionNames.push(p.display_name);
                }
            });
        });
    }
])

.controller('userMenu', [
    '$scope',
    '$http',
    'DS',
    'User',
    'operator',
    'ngDialog',
    function($scope, $http, DS, User, operator, ngDialog) {
        $scope.logout = function () {
            $http.post('/users/logout/').then(function (response) {
                operator.setUser(null);
                window.location.reload();
            });
        };
    }
])

.controller('LoginFormCtrl', [
    '$rootScope',
    '$scope',
    '$http',
    '$stateParams',
    'operator',
    function ($rootScope, $scope, $http, $stateParams, operator ) {
        $scope.alerts = [];

        // get login info-text from server
        $http.get('/users/login/').success(function(data) {
            if(data.info_text) {
                $scope.alerts.push({
                    type: 'success',
                    msg: data.info_text
                });
            }
        });
        // close alert function
        $scope.closeAlert = function(index) {
            $scope.alerts.splice(index, 1);
        };
        // check if guest login is allowed
        $scope.guestAllowed = $rootScope.guest_enabled;
        // login
        $scope.login = function () {
            $scope.alerts = [];
            $http.post(
                '/users/login/',
                {'username': $scope.username, 'password': $scope.password}
            ).then(
                function (response) {
                    // Success: User logged in.
                    operator.setUser(response.data.user_id);
                    $scope.closeThisDialog();
                    setTimeout(function(){
                        window.location.replace('/');
                    }, 1000);
                },
                function (response) {
                    // Error: Username or password is not correct.
                    $scope.alerts.push({
                        type: 'danger',
                        msg: response.data.detail
                    });
                }
            );
        };
        // guest login
        $scope.guestLogin = function () {
            $scope.closeThisDialog();
        };
    }
])

// Mark all permission strings for translation in JavaScript.
// (see models.py of each Django app)
.config([
    'gettext',
    function (gettext) {
        // agenda
        gettext('Can see agenda');
        gettext('Can manage agenda');
        gettext('Can see hidden items and time scheduling of agenda');
        gettext('Can put oneself on the list of speakers');
        // assignments
        gettext('Can see elections');
        gettext('Can nominate another participant');
        gettext('Can nominate oneself');
        gettext('Can manage elections');
        // core
        gettext('Can see the projector');
        gettext('Can manage the projector');
        gettext('Can see the front page');
        gettext('Can manage tags');
        gettext('Can manage configuration');
        gettext('Can use the chat');
        // mediafiles
        gettext('Can see the list of files');
        gettext('Can upload files');
        gettext('Can manage files');
        // motions
        gettext('Can see motions');
        gettext('Can create motions');
        gettext('Can support motions');
        gettext('Can manage motions');
        // users
        gettext('Can see names of users');
        gettext('Can see extra data of users (e.g. present and comment)');
        gettext('Can manage users');
    }
]);


// this is code from angular.js. Find a way to call this function from this file
function getBlockNodes(nodes) {
  // TODO(perf): just check if all items in `nodes` are siblings and if they are return the original
  //             collection, otherwise update the original collection.
  var node = nodes[0];
  var endNode = nodes[nodes.length - 1];
  var blockNodes = [node];

  do {
    node = node.nextSibling;
    if (!node) break;
    blockNodes.push(node);
  } while (node !== endNode);

  return $(blockNodes);
}

}());
