var module = angular.module('oaiExplorerUI', ['ngGrid']);


module.directive('compileTemplate', function($compile, $parse){
	return {
		link: function(scope, element, attr){
			var parsed = $parse(attr.ngBindHtml);
            
			function getStringValue() { return (parsed(scope) || '').toString(); }

			//Recompile if the template changes
			scope.$watch(getStringValue, function() {
                $compile(element, null, -9999)(scope);  //The -9999 makes it skip directives so that we do not recompile ourselves
			});
		}         
	}
});

function oaiExplorerCtrl($scope, $http, $sce) {
	$scope.tmpBaseUrl = getInitialBaseUrl();
	$scope.baseUrl = "";
	$scope.currentAction = "";
	$scope.oaiUrl = "";
	$scope.testAllVerbsData = [];
	$scope.testHarvestingData = [];
	$scope.continueIteration = false;
	
	$scope.identifyData = "";
	
	$scope.isValidUrl = function(url) {
		return (/^http/).test(url);
	}
		
	$scope.verifyBaseUrl = function(url) {
		$scope.baseUrl = "";
		$scope.currentAction = "";
		if ($scope.isValidUrl(url)) {
			$scope.baseUrl = url;
			$scope.identify();
		}
	}
	
	initSpinner();
	$scope.showError        = function(error)   { show_notification("error", error); }
	$scope.showNotification = function(message) { show_notification("info", message); }
	$scope.showSpinner      = function()        { showSpinner(); }
	$scope.hideSpinner      = function()        { hideSpinner(); }

	
	$scope.identify = function() {
		$scope.oaiUrl = $scope.baseUrl + "?verb=Identify";
		
		$scope.callRemoteMethod('Identify', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'Identify' 
        });
	}
	
	$scope.listMetadataFormats = function() {
		$scope.oaiUrl = $scope.baseUrl + "?verb=ListMetadataFormats";
		
		$scope.callRemoteMethod('ListMetadataFormats', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'ListMetadataFormats' 
        });
	}
	
	$scope.listSets = function() {
		$scope.oaiUrl = $scope.baseUrl + "?verb=ListSets";
		
		$scope.callRemoteMethod('ListSets', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'ListSets'
        });
	}

	$scope.listRecords = function(mdf, set) {
		$scope.oaiUrl = $scope.baseUrl + "?verb=ListRecords&metadataPrefix=" + mdf;
		if (set) {
			$scope.oaiUrl += "&set=" + set; 
		}
		
		$scope.callRemoteMethod('ListRecords', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'ListRecords',
			'mdf'     : mdf,
			'set'     : set
        });
	}

	$scope.listIdentifiers = function(mdf, set) {
		$scope.oaiUrl = $scope.baseUrl + "?verb=ListIdentifier&metadataPrefix=" + mdf;
		if (set) {
			$scope.oaiUrl += "&set=" + set; 
		}
		
		$scope.callRemoteMethod('ListIdentifiers', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'ListIdentifiers',
			'mdf'     : mdf,
			'set'     : set
        });
	}

	$scope.getRecord = function(id, mdf) {
		$scope.currentAction = "GetRecord";
		$scope.oaiUrl = $scope.baseUrl + "?verb=GetRecord&metadataPrefix=" + mdf + "&identifier=" + id;
		$scope.callRemoteMethod('GetRecord', {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'GetRecord',
			'mdf'     : mdf,
			'id'      : id
        });
	}
	
	$scope.nextPage = function(token) {
		$scope.oaiUrl = $scope.baseUrl + "?verb=" + $scope.currentAction + "&resumptionToken=" + token;
		$scope.callRemoteMethod($scope.currentAction, {
			'baseUrl': $scope.baseUrl,
			'verb': $scope.currentAction,
			'token' : token
        });
	}

	
	$scope.testAllVerbs = function() {
		$scope.currentAction = "testAllVerbs";
		$scope.oaiDataHTML = "";
		$scope.oaiUrl = $scope.baseUrl + "?verb=Identify";
		$scope.testAllVerbsData = [];
		$scope.testHarvestingData = [];
		$scope.continueIteration = true;		
		
		$scope.time_min = 9999999;
		$scope.time_max = 0;
		$scope.time_total = 0;
		$scope.time_sqrTotal = 0;
		$scope.time_avg = 0;
		$scope.time_stddev = 0;
		
		$scope.testVerb($scope.testAllVerbsData, "test_oai_verb", {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'Identify',
        });
	}
	
	$scope.testHarvesting = function() {
		$scope.currentAction = "testHarvesting";
		$scope.oaiUrl = $scope.baseUrl + "?verb=ListRecords&metadataPrefix=oai_dc";
		$scope.oaiDataHTML = "";
		$scope.testAllVerbsData = [];
		$scope.testHarvestingData = [];
		$scope.continueIteration = false;
		
		$scope.time_min = 9999999;
		$scope.time_max = 0;
		$scope.time_total = 0;
		$scope.time_sqrTotal = 0;
		$scope.time_avg = 0;
		$scope.time_stddev = 0;
	}

	$scope.startTestHarvesting = function() {
		$scope.continueIteration = true;
		$scope.time_min = 9999999;
		$scope.time_max = 0;
		$scope.time_total = 0;
		$scope.time_sqrTotal = 0;
		$scope.time_avg = 0;
		$scope.time_stddev = 0;
		
		$scope.testHarvestingData = [];
		$scope.testVerb($scope.testHarvestingData, "test_harvesting", {
			'baseUrl' : $scope.baseUrl,
			'verb'    : 'ListRecords',
			'mdf'     : 'oai_dc'
        });
	}
	
	$scope.stopTestHarvesting = function() {
		$scope.continueIteration = false;
	}
	
	$scope.testVerb = function(list, method, params) {
		//$scope.showSpinner();
		$http.post(method, params).success(function(data) {
        	list.push(data);
        	
        	if (data.time) {
        		var curr = data.time / 1000;

        		$scope.time_min = Math.min($scope.time_min, curr);
        		$scope.time_max = Math.max($scope.time_max, curr);
        		$scope.time_total += curr;
        		$scope.time_sqrTotal += curr*curr;
        		$scope.time_avg = ($scope.time_total/list.length);
        		$scope.time_stddev = Math.sqrt((list.length * $scope.time_sqrTotal) - ($scope.time_total * $scope.time_total)) / list.length;
        	}
        	
        	location.href="#endPage";
        	//$scope.hideSpinner();
        	if ($scope.continueIteration && data.nextCall && data.nextCall.verb) {
        		$scope.testVerb(list, method, data.nextCall);
        	} else {
        		$scope.continueIteration = false;
        	}
        }).error(
            function() {
            	$scope.showError('Something really bad must have happened to our fellow hamster..');
            	//$scope.hideSpinner();
            }
        );
	}
		
	$scope.callRemoteMethod = function(name, params) {
		$scope.currentAction = name;
		$scope.oaiDataHTML = "";
		$scope.testAllVerbsData = [];
		$scope.testHarvestingData = [];
		
		$scope.showSpinner();

		$http.post('oai_verb', params).success(function(data) {
        	$scope.oaiDataHTML = $sce.trustAsHtml(data);
        	$scope.hideSpinner();
        }).error(
            function() {
            	$scope.showError('Something really bad must have happened to our fellow hamster..');
            	$scope.hideSpinner();
            }
        );
	}
	
	$scope.updateGraph = function(list, field) {
		var i = 1;
		var d = [];
		angular.forEach(list, function(obj) {
			if (obj[field]) {
				d[i] = [i, obj[field]];
			}
			i++;
		});
		jQuery.plot("#harvestingGraph", [ d ]);
	}
	
	
	if ($scope.tmpBaseUrl && $scope.isValidUrl($scope.tmpBaseUrl)) {
		$scope.verifyBaseUrl($scope.tmpBaseUrl);
	}

}