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

	module.directive('claSugrePicker', ClaSugrePicker);

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

	function ClaSugrePicker($timeout)
	{
		return {
			restrict: 'E',
			require: '^ngModel',
			//templateUrl: '/intranet/js/angular/cla/sugre_picker/sugre_picker.html',
			templateUrl: template,
			scope: {
				ngModel: '=',
				control: '=',
                multiple: '@',
                options: '='
			},
			link: function(scope, iElement, iAttrs, ctrl)
			{
				scope.id = iAttrs.selectId + '-inner';
				scope.hide_browse = iAttrs.hideBrowse == 1;
				if (scope.multiple === undefined) {
                    scope.multiple = false;
                }

				// Use a directive property for localized value to avoid forcing a dependency on the lmsg directive
				scope.localized_browse = lmsg('common.user_picker.browse');

				var allow_unset = iAttrs.allowUnset == 1;

				iElement.hide();

				// Angular won't have populated the control/browse ids yet so wait until the current event is finished
				$timeout(function(id, text, allow_unset, element) {
					scope.initSelect2(id, text, allow_unset);
					element.show();
				}, 0, true, scope.id, "Select a user / group / role / extranet", allow_unset, iElement);

				ctrl.$viewChangeListeners.push(function() {
					scope.$eval(iAttrs.ngChange);
				});

				scope.initSelect2 = function(id, text, allow_unset)
				{
				    var select = $('#' + id);
				    select.find('option').remove();

                    if (typeof scope.ngModel !== 'object') {
                        scope.ngModel = {
                            selected_options: [],
                        };
                    }

					if (scope.multiple) {
                        if (typeof scope.options === 'object') {
                            for (var offset in scope.options) {
                                select.append($('<option selected value="' + scope.escapeHtml(scope.options[offset].value) + '">' + scope.escapeHtml(scope.options[offset].name) + '</option>'));
                                scope.ngModel.selected_options.push("" + scope.options[offset].value);
                            }
                        }
                        select.on('change', function(){
                            scope.ngModel.selected_options.length = 0;

                            angular.element(this).find('option:selected').each(function(){
                                var sugre_val = angular.element(this).val();
                                var value = {
                                    assigned_value: sugre_val,
                                    assigned_str: sugre_val === '' ? '' : angular.element(this).text()
                                }
                                scope.ngModel.selected_options.push(value);
                            });

                            ctrl.$setViewValue(scope.ngModel);
                        });
                    } else {
                        // Select2 needs a blank entry to go to when no user is selected. It should create this by itself but sometimes doesn't
                        select.append($('<option>').attr('selected', 'selected'));

                        if (scope.ngModel.assigned_value) {
                            // Add an entry for the current user if needed
                            select.append($('<option selected value="' + scope.escapeHtml(scope.ngModel.assigned_value) + '">' +  scope.escapeHtml(scope.ngModel.assigned_str) + '</option>'));
                        }

                        select.on('change', function(){
                            var $el = angular.element(this);
                            var sugre_val = $el.val();
                            scope.ngModel.assigned_value = sugre_val;
                            scope.ngModel.assigned_str = sugre_val === '' ? '' : $el.find('option[value='+sugre_val+']').text();
                            ctrl.$setViewValue(scope.ngModel);
                        });
                    }

                    window.UserPicker_InitSelect2SUGRE(id, '', text, allow_unset);
				};

				scope.browse = function(event)
				{
					event.preventDefault();
					var recwnd = window.open('/intranet/common/common_perms_owners_popup.php?selector_name='+scope.id+'&sugre=1','sugre_popup','width=800,height=590,scrollbars=yes,resizable=yes,hotkeys=no,maximize=no,visible=no');
					recwnd.focus();
				};

				scope.internalControl = scope.control || {};
				scope.internalControl.reset = function()
				{
					scope.initSelect2(scope.id, "Select a user / group / role / extranet", true);
				};

                /**
                 * Sanitize string.
                 * @param {string} text
                 * @returns {string} sanitized string
                 */
                scope.escapeHtml = function (text) {
                    var element = document.createElement('span');
                    element.textContent = text;

                    return element.innerHTML;
                }
			}
		};
	}
});
