var BallyhooClient = function(pluckServerFQDN) {
	//validate and try to default FQDN
	if (typeof pluckServerFQDN != "string") {
		if (typeof serverUrl == "string") {
			pluckServerFQDN = serverUrl.toLowerCase();
			pluckServerFQDN = pluckServerFQDN.substring( 0, pluckServerFQDN.lastIndexOf("/direct/") );
			this.ballyhooPath = pluckServerFQDN + "/ballyhoo/?recipes=";
		} else {
			throw "BallyhooClient couldn't find the FQDN to the Pluck server. It looks for serverUrl (as used by DAAPI) and the optional constructor parameter.";
			return false;
		}
	} else {
		this.ballyhooPath = "http://" + pluckServerFQDN + "/ver1.0/ballyhoo/?recipes=";
	}
	
	this.recipeIDs = [];	//used internally but it's OK to manipulate externally too
	
	this.addRecipe = function(recipeID) {
		this.recipeIDs.push(recipeID);
	}
	
	this.doAjax = function(fullUrl, callbackFunction) {
		var scriptElem = document.createElement("script");
		ajaxId = "ballyhooClient_" + new Date().valueOf();
		scriptElem.id = ajaxId;
		scriptElem.src = fullUrl + "&uniqueID=" + ajaxId;
		
		//store the callback in a global, as safely as possible
		if (!window.ballyhooClientCallbacks) {
			window.ballyhooClientCallbacks = {};
		}
		window.ballyhooClientCallbacks[ajaxId] = callbackFunction;
		
		document.getElementsByTagName("head")[0].appendChild(scriptElem);
		
		if (scriptElem.readyState != "loaded") {
			scriptElem.onload = scriptElem.onreadystatechange = function() { 
				//TODO: determine the best way to test readyState for all browsers
				//if (!this.readyState || this.readyState == "loaded") { 
				if (this.readyState == "loaded") {
					window.ballyhooClientCallbacks[this.id](this.innerHTML);
				}
			} 
		} else { 
			throw "BallyhooClient encountered an error sending ajax request";
		}
	}
	
	this.callServer = function(callbackFtn) {
		//do some validation
		if (typeof callbackFtn != "function") {
			throw "BallyhooClient's callServer method requires a callback function";
			return false;
		}
		if (this.recipeIDs.length < 1) {
			throw "No recipe IDs were passed to BallyhooClient; stopping execution; use the addRecipe method";
			return false;
		}
		
		//if we get here, we have everything we need to fire the Ajax request
		var ajaxUrl = this.ballyhooPath + this.recipeIDs.join(",");
		this.doAjax( ajaxUrl, this.onballyhoocomplete(callbackFtn) );
		
		//clean up
		this.recipeIDs = [];
	}
	
	this.onballyhoocomplete = function(clientCallback) {
		//curried callback function that handles the info from Pluck 4
		return function(responseObj) {
			//some browsers want to call this twice (an onreadystatechange issue), so disregard these edge cases
			if (typeof responseObj == "object") {
				clientCallback(responseObj.requestedIDs, responseObj.urls);
			}
		}
	}
}
