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

	module.directive('claUserPicker', userPicker);

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

	function userPicker($timeout) {
		return {
			link: link,
			restrict: 'E',
			require: '^ngModel',
			templateUrl: template,
			scope: {
				ngModel: '=',
				control: '='
			}
		};

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

			// 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;

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

			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, lmsg('common.picker.select_user'), allow_unset, iElement);

			$('#' + scope.id).append($('<option>').attr('value', '' + ctrl.$modelValue).attr('selected', 'selected').text(scope.user_name));
			window.UserPicker_InitSelect2Single(scope.id, '', lmsg('common.picker.select_user'), allow_unset);

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

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

				// 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'));

				// Add an entry for the current user if needed
				if (scope.ngModel != '' && scope.ngModel != undefined)
					select.append($('<option>').attr('value', '' + scope.ngModel).text(scope.user_name).attr('selected', 'selected'));
                select.on('change', function(){
                    var $el = angular.element(this);
                    var user_id = $el.val();
                    var name = user_id === '' ? '' : $el.find('option[value='+user_id+']').text();
                    scope.change(user_id, name);
                });

				window.UserPicker_InitSelect2Single(scope.id, '', text, allow_unset);
			};

			scope.change = function (user_id, name) {
				if (isNaN(user_id))
					user_id = '';
				else
					scope.user_name = name;

				ctrl.$setViewValue('' + user_id);
				ctrl.$render();

				$timeout(function(user_id) {
					ctrl.$setViewValue('' + user_id);
					ctrl.$render();
				}, 0, true, user_id);
			};

			scope.browse = function (event) {
				event.preventDefault();
				var recwnd = window.open('/intranet/common/user_picker_popup.php?input_dom_id=' + scope.id + '', 'user_picker_wnd', 'width=800,height=450,scrollbars=yes,resizable=yes,hotkeys=no,maximize=no');
				recwnd.focus();
			};

			scope.internalControl = scope.control || {};
			scope.internalControl.reset = function()
			{
				// Rebind the model. This shouldn't be needed but it never gets updated once reset otherwise
				ctrl.$setViewValue(scope.ngModel);

				scope.initSelect2(scope.id, lmsg('common.picker.select_user'), true);
			};
		}
	}
});
