var module = angular.module('addRepoApiUI', ['localytics.directives']);

module.directive('bsHasError', function() {
	return {
		restrict: "A",
		link: function(scope, element, attrs, ctrl) {
			element.toggleClass('has-feedback', true);
			var input = element.find('input[ng-model], select[ng-model]');
			if (input) {
				scope.$watch(function() {
					if (input.hasClass('ng-invalid')) {
						return 0;
					} else if (input.hasClass('empty')) {
						return 1;
					} else {
						return 2;
					}
				}, function(code) {
					if (code < 0) return;
					
					element.toggleClass('has-error', (code == 0));
					element.toggleClass('has-warning', (code == 1));
					element.toggleClass('has-success', (code == 2));
					
					var feedback = element.find('.form-control-feedback');
					if (feedback) {
						feedback.toggleClass('glyphicon-remove', (code == 0));
						feedback.toggleClass('glyphicon-warning-sign', (code == 1));
						feedback.toggleClass('glyphicon-ok', (code == 2));
					}
				});
			}
		}
	};
});

module.directive('ngSelectRepoField', function($http) {
	return {
		restrict: 'E',
		scope: {
            'label'     : '@',
            'typology'  : '=',
            'selection' : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngSelectRepoField.html',
		link: function(scope, element, attrs, ctrl) {
			scope.repositories = [];
			scope.current = '';
			scope.$watch('typology', function() {
				scope.repositories = [];
				if (scope.typology) {
					showSpinner();
					$http.get('listRepositories.json?type=' + scope.typology).success(function(data) {
						scope.repositories = data;
						hideSpinner();
					}).error(function() {
						show_notification("error", "An error occurred while fetching datasource of type " + scope.typology);
						hideSpinner();
					});
				}
			});
		}
	}
});

module.directive('ngFixedValueField', function() {
	return {
		restrict: 'E',
		scope: {
            'label'  : '@',
            'value'  : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngFixedValueField.html'
	}
});

module.directive('ngApiIdValidation', function() {
	return {
		restrict: 'A',
		scope: {
			'valid' : '='
		},
		require: 'ng-model',
		link: function(scope, element, attrs, ctrl) {
			scope.$watch('valid', function() {
				ctrl.$setValidity('wrongId', scope.valid);
			});
		}
	}
});

module.directive('ngApiIdField', function() {
	return {
		restrict: 'E',
		scope: {
			'label'     : '@',
			'prefix'    : '@',
			'selection' : '=',
			'exclusion' : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngApiIdField.html',
		link: function(scope, element, attrs) {
			scope.suffix = '';
			scope.alert = '';
			scope.valid = false;
			scope.required = true;
			scope.mypattern = new RegExp(scope.regex);

			scope.validate = function(b, newValue, message) {
				scope.valid = b;
				scope.selection = newValue;
				scope.alert = message;
				element.toggleClass('has-error', !b);
				element.toggleClass('has-success', b);
				var feedback = element.find('.form-control-feedback');
				if (feedback) {
					feedback.toggleClass('glyphicon-remove', !b);
					feedback.toggleClass('glyphicon-ok', b);
				}
			}
			
			scope.$watch('suffix', function() {
				var tmpId = scope.prefix + scope.suffix;
				
				if (!scope.suffix) {
					scope.validate(false, '', 'ID is empty');
				} else if (!scope.suffix.match(/^[A-Za-z0-9_]*$/g)) {
					scope.validate(false, '', 'Invalid format, valid chars are: A-Za-z0-9_');
				} else if($.inArray(tmpId, scope.exclusion) > -1) {
					scope.validate(false, '', 'The ID already exists');
				} else {
					scope.selection = tmpId;
					scope.validate(true, tmpId, '');
				}
			});
		}
	}
});

module.directive('ngSelectVocabularyField', function() {
	return {
		restrict: 'E',
		scope: {
            'label'            : '@',
            'vocabulary'       : '=',
            'selection'        : '=',
            'contextualParams' : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngSelectVocabularyField.html',
		link: function(scope, elem, attrs) {
			scope.required = true;
			scope.selectId = 'select_' + scope.label.replace( /\s/g, "_").toLowerCase();
			
			scope.$watch('selection', function() {
				scope.contextualParams = [];
				angular.forEach(scope.vocabulary, function(term){
					if (term.name == scope.selection) {
						scope.contextualParams = term.params;
					} 					
				});				
			});
		}
	}
});

module.filter('vocabularyTerm', function() {
	return function(term) {
		if(term.desc) {
			return term.name + ' (' + term.desc + ')';
	    } else {
	    	return term.name;
	    }
	};
});

module.directive('ngSimpleEditField', function() {
	return {
		restrict: 'E',
		scope: {
            'label'         : '@',
            'regex'         : '@',
            'optional'      : '@',
            'type'          : '@',
            'selection'     : '=',
		},
		templateUrl: '../resources/html/addRepoApi/ngSimpleEditField.html',
		link: function(scope, element, attrs) {
			scope.required = (scope.optional != 'true');
			if      (scope.regex)             { scope.mypattern = new RegExp(scope.regex); }
			else if (scope.type == 'NUMBER')  { scope.mypattern = new RegExp("^[-+]?[0-9]+(\.[0-9]+)?$"); }
			else if (scope.type == 'BOOLEAN') { scope.mypattern = new RegExp("^(true|false)$"); }
			else                              { scope.mypattern = new RegExp(".+"); }
		}
	}
});

module.directive('ngSimpleSelectField', function() {
	return {
		restrict: 'E',
		scope: {
            'label'           : '@',
            'optional'        : '@',
            'refreshFunction' : '&',
            'validValues'     : '=',
            'selection'       : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngSimpleSelectField.html',
		link: function(scope, element, attrs) {
			scope.required = (scope.optional != 'true');
			scope.populateList = function() {
				scope.validValues = scope.functionList();
			}
		}
	}
});


module.directive('ngMultiSelectField', function() {
	return {
		restrict: 'E',
		scope: {
			'label'           : '@',
            'optional'        : '@',
            'refreshFunction' : '&',
            'validValues'     : '=',
            'selection'       : '='
		},
		templateUrl: '../resources/html/addRepoApi/ngMultiSelectField.html',
		link: function(scope, element, attrs) {
			scope.arraySelection = [];
			scope.required = (scope.optional != 'true');
			scope.$watch('arraySelection', function() {
				scope.selection = scope.arraySelection.join();
			});
		}
	}
});


module.controller('addRepoApiCtrl', function ($scope, $http, $sce, $location) {
	
	common_init($scope, $http, $sce, $location)
	
	$scope.values = {
		'compliances'         : getCompliances(),
		'types'               : getTypes(),
		'contentDescriptions' : getContentDescriptions(),
		'protocols'           : getProtocols()
	}
		
	$scope.$watch('repo', function() {
		if ($scope.repo) {
			$scope.apiParams = {};
			$scope.api = {
				'typology'  : $scope.repo.typology,
				'apiParams' : []
			};
		}
	});
	
	$scope.resetForm = function() {
		$scope.currentParams = [];
		$scope.selectedTypology = '';
		$scope.repo = {};
		$scope.api = {};
		$scope.apiParams = {};
		$scope.validValues = [];
	}
	
	$scope.registerApi = function() {
		if (confirm('Add new api to repository \n\n' + $scope.repo.name + '?')) {
			
			$scope.api.apiParams = [];
			angular.forEach($scope.apiParams, function(value, param) {
				$scope.api.apiParams.push({
					'param' : param,
					'value' : value
				});
			});
						
			$scope.showSpinner();
			$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
			$http.post('repoApi.new', $.param({
				'repoId' : $scope.repo.origId,
				'iface'  : JSON.stringify($scope.api)
			})).success(function(res) {
	            	if(res) {
	            		$scope.showNotification('The API has been registered');
	            		$scope.hideSpinner();
	            		$scope.done = 1;
	            		//TODO once we'll get rid of pending/valid repo state, we'll ba able to redirect to the repo detail page
	            		//location.href = 'isManager.do#/profile/' + $scope.repo.id;
	            	} else {
	                	$scope.hideSpinner();
	            		$scope.showError('Registration failed');
	            	}
			}).error(function(err) {
				$scope.hideSpinner();
				$scope.showError('Registration failed: ' + err.message);
			});
		}
	}
	
	$scope.listValidValuesForParam = function(param) {
		if (!param) {
			$scope.showError("Invalid param");
			return;
		}
		
		if (!$scope.api.protocol) {
			$scope.showError("Access Protocol is missing");
			return;	
		}
		if (!$scope.api.baseurl) {
			$scope.showError("BaseUrl is missing");
			return;
		}
		
		var key = $scope.api.baseurl + '@@@' + param;
		$scope.validValues[key] = [];

		$scope.showSpinner();
		$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
		$http.post('listValidValuesForParam.do', $.param({
			'protocol' : $scope.api.protocol,
			'param'    : param,
			'baseUrl'  : $scope.api.baseurl,
		})).success(function(data) {
			$scope.hideSpinner();
			$scope.validValues[key] = data;
		}).error(function(message) {
			$scope.hideSpinner();
			$scope.showError('Error obtaining values: ' + message);
		});
	}
	
	$scope.resetForm();
});