define(['cla_angular', './permissions_picker.html', 'autocomplete'], function (angular, template) {
	var moduleName = 'cla.core.permissions_picker';
	try {
		var module = angular.module(moduleName);
	} catch(err) {
		// named module does not exist, so create one
		var module = angular.module(moduleName, []);
	}

	module.directive('claPermissionsPicker', permissionsPicker);

	permissionsPicker.$inject = ['$timeout'];

	function permissionsPicker($timeout) {
		controller.$inject = ['$scope'];

		return {
			link: link,
			controller: controller,
			controllerAs: 'perms',
			bindToController: true,
			restrict: 'E',
			require: '^ngModel',
			templateUrl: template,
			scope: {
				ngModel: '=',
				permClass: '=',
				control: '='
			}
		};

		function controller($scope)
		{
			var ctrl = this;

            this.$onInit = function() {
                ctrl.autocompleteObj = null;
                ctrl.searchBox = null;
                ctrl.search = '';
                ctrl.model = {owners: []};
                ctrl.selectedOwner = [];
                ctrl.public_id= '6_0';
                ctrl.all_perms = {};
                ctrl.control = $scope.control || {};

                for (var key in ctrl.model.owners)
                {
                    ctrl.all_perms[ctrl.model.owners[key].value] = [ctrl.model.owners[key].name, 1];
                }
                ctrl.onames = {1: "User", 2: "Role", 3: "Group", 4: "All registered", 5: "Extranet area", 6: "Public", 9: "Owner", 10: "Group[+]"};

                // When the object with permissions changes, ctrl.all_perms needs to be updated with the new values
                ctrl.control.populate = function()
                {
                    // Remove old data
                    for (var key in ctrl.all_perms)
                    {
                        delete ctrl.all_perms[key];
                    }

                    ctrl.model.owners.length = 0;

                    // Copy new data
                    for (i = 0; i < ctrl.ngModel.owners.length; i++)
                    {
                        ctrl.model.owners.push(ctrl.ngModel.owners[i]);
                    }

                    for (var i = 0; i < ctrl.model.owners.length; i++)
                    {
                        var owner = ctrl.model.owners[i];
                        ctrl.all_perms[owner.value] = [owner.name, 1];
                    }
                };

                // Parent directive needs to get the updated data
                ctrl.control.sync = function()
                {
                    ctrl.ngModel.owners.length = 0;

                    for (var i = 0; i < ctrl.model.owners.length; i++)
                    {
                        ctrl.ngModel.owners.push(ctrl.model.owners[i]);
                    }
                };
            };

			ctrl.addOwner = function(oclass, id, name) {
				if (typeof ctrl.all_perms[oclass + '_' + id] === 'undefined') {
					ctrl.all_perms[oclass + '_' + id] = [name, 1];
					ctrl.model.owners.push({
						name: (id != 0 ? (ctrl.onames[oclass] + ': ') : '') + name,
						value: oclass + '_' + id
					});
					return true;
				}
				return false;
			};

			ctrl.formatAutocompleteResult = function(value, data, currentValue) {
				currentValue = currentValue.replace(/^\w{0,10}(\+?|\[\+\]):\s*/, '');
				if (currentValue.length === 0)
					return value;

				var span = document.createElement('span');
				span.innerText = value;
				value = span.innerHTML;

				var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '<', '>', '\\'].join('|\\') + ')', 'g');
				var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
				return value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
			};

			ctrl.addOwnerFromAutocomplete = function(value, data) {
				if (data[0] != 0)
					ctrl.addOwner(data[0], data[1], data[2]);
				else
					ctrl.addOwner(data[1], 0, data[2]);
				ctrl.search = '';
				$scope.$digest();

				// jquery.autocomplete doesn't sync automatically if we change the value so force it too manually
				ctrl.autocompleteObj.onValueChange();

				return false;
			};

			ctrl.deleteSelectedOwner = function() {
				for (var i = 0; i < ctrl.selectedOwner.length; i++)
				{
					sel = ctrl.selectedOwner[i];

					for (var key in ctrl.all_perms)
					{
						if (key === sel)
							delete ctrl.all_perms[key];
					}

					for (var key in ctrl.model.owners)
					{
						if (ctrl.model.owners[key].value === sel)
							ctrl.model.owners.splice(key, 1);
					}
				}

				ctrl.selectedOwner = [];
			};

			ctrl.unsetArrayElement = function(input_array, key_to_unset) {
				var output_array = {};
				for (var key in input_array) {
					if (key != key_to_unset) output_array[key] = input_array[key];
				}
				return output_array;
			};

			ctrl.openEffectivePermissionsWindow = function(event)
			{
				event.preventDefault();

				var perms = [];
				for (var key in ctrl.all_perms)
				{
					perms.push(key + '_1');
				}
				perms = perms.join(',');

				var perm_values = '1_Member';

				window.open("/intranet/common/common_perms_effective.php?perms="+perms+"&perm_values="+perm_values,
					"effective_popup", "width=1040,height=550,scrollbars=yes,resizable=yes,hotkeys=no,maximize=no");
			};
		}

		function link(scope, iElement, iAttrs, ctrl) {
			scope.id = iAttrs.selectId + '-inner';
			scope.user_name = iAttrs.userName;

			if (scope.ngModel == 0)
				scope.ngModel = '';

			// Angular won't have populated the control/browse ids yet so wait until the current event is finished
			$timeout(function(id, text, element) {
				var input = angular.element(element).find ('.js-owner_search');
				scope.perms.searchBox = input;
				scope.perms.autocompleteObj = input.autocomplete({
					serviceUrl: "/intranet/common/common_perms_owners_popup.php",
					params: {'pp': 0, 'pc': scope.perms.permClass, sho: 1, json: 1},
					deferRequestBy: 100,
					width: 'auto',
					fnFormatResult: scope.perms.formatAutocompleteResult,
					onSelect: scope.perms.addOwnerFromAutocomplete
				});
			}, 0, true, scope.id, lmsg('common.picker.select_user'), iElement);
		}
	}
});
