// Multiple role picker

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

	module.directive('claRolePicker', rolePicker);

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

	function rolePicker($timeout) {
		return {
			link: link,
			restrict: 'E',
			require: '^ngModel',
			//templateUrl: '/intranet/js/angular/cla/role_picker/role_picker.html',
			templateUrl: template,
			scope: {
				ngModel: '=',
				control: '=',
				roles: '=',
				placeholder: '@'
			}
		};

		function link(scope, iElement, iAttrs, ctrl) {
			scope.id = iAttrs.selectId + '-inner';
			scope.placeholder = scope.placeholder ? scope.placeholder : 'Select a role';

			if (scope.ngModel == 0)
				scope.ngModel = [];

			iElement.hide();

			scope.startSelect2 = function (element_id, query_params, placeholder) {
				var el = angular.element('#' + element_id);
				var page_size = 10;
				el.select2({
					placeholder: placeholder,
					minimumInputLength: 1,
					ajax: {
						url: "/intranet/common/role_picker.php?json=1&multi=1"+query_params,
						dataType: 'json',
						data: function (params) {
							return {
								keywords: params.term.trim(), // search term
								page: params.page,
								page_size: page_size,
								st: (params.page-1) * page_size
							};
						},
						processResults: function (data, params) {
							params.page = params.page || 1;

							return {
								results: data.data,
								pagination: {
									more: ((params.page) * page_size) < data.total
								}
							};
						}
					}
				});
			};

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

			scope.startSelect2(scope.id, '', scope.placeholder);

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

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

				// Add an entry for the current roles if needed
				for (var i = 0; i < scope.ngModel.length; i++)
				{
					select.append(angular.element('<option>').attr('value', '' + scope.ngModel[i]).text(scope.roles[scope.ngModel[i]]).attr('selected', 'selected'));
				}
                select.on('change', function(){
                    scope.ngModel.length = 0;

                    angular.element(this).find('option:selected').each(function(){
                        var role_id = angular.element(this).val();
                        scope.ngModel.push(role_id);
                    });
                    scope.change();
                });

				scope.startSelect2(scope.id, '', text);
			};

			scope.change = function () {
				var roleIds = scope.ngModel;

				scope.roles = {};
				angular.element.each(roleIds, function(key, value)
				{
					scope.roles[value] = angular.element('#' + scope.id + ' [value="' + value + '"]').text();
				});

				ctrl.$setViewValue(roleIds);
				ctrl.$render();

				$timeout(function(roleIds) {
					ctrl.$setViewValue(roleIds);
					ctrl.$render();
				}, 0, true, roleIds);
			};

			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, scope.placeholder, true);
			};
		}
	}
});
