
/*********** OBJECT factory ***********************************/

	/* GLOBAL FIELDS:*/
	var userInavailabilityCounter = 0;
	var emailInavailabilityCounter = 0;
	var termsInavailabilityCounter = 0;
	var userTimer = {timer:null};
	var emailTimer = {timer:null};
	var pass1Timer = {timer:null};
	var pass2Timer = {timer:null};
	var blogurlTimer = {timer:null};
	var openidTimer = {timer:null};


	function getFieldIndication(fieldName) {
		return document.getElementById(fieldName+'_vld');	
	}
	function getFieldErrorLabel(fieldName) {
		return document.getElementById(fieldName+'_err');
	}
	
	function getFieldMessageLabel(fieldName) {
		return document.getElementById(fieldName+'_msg');
	}


	function setUnavailable(fieldName) {
		if (fieldName == 'terms') {
			termsInavailabilityCounter = 1;
		}
		if (fieldName == 'username') {
			userInavailabilityCounter = 1;
		}
		if (fieldName == 'email') {
			emailInavailabilityCounter = 1;
		}
		disableSubmit();
		
	}
	function setAvailable(fieldName) {
		if (fieldName == 'terms') {
			termsInavailabilityCounter = 0;
		}	
		if (fieldName == 'username') {
			userInavailabilityCounter = 0;
		}
		if (fieldName == 'email') {
			emailInavailabilityCounter = 0;
		}
		if (emailInavailabilityCounter==0 && userInavailabilityCounter == 0 && termsInavailabilityCounter == 0 ) { 
			enableSubmit();
		}	
	}
	
	function getTimerByFieldName(fieldName) {
		switch(fieldName){
			case 'username': return userTimer; break;
			case 'email': return emailTimer; break;
			case 'password': return pass1Timer; break;
			case 'password2': return pass2Timer; break;
			case 'blogurl': return blogurlTimer; break;
			case 'openid_url': return openidTimer; break;
		}
		
	}
	
	
	

/************************OPENID**************************************/

	function makeOpenId() {
		addUrlParam("openid","true");
		
	}
	function unmakeOpenId(){
		addUrlParam("openid","false");

	}


/************************************************************/

	function disableSubmit() {
		changeSubmit(true);
	}
	function enableSubmit() {
		changeSubmit(false);
	}
	
	function changeSubmit(disabled) {
		var gos = document.getElementsByName('go');
		if (gos != null && gos.length > 0 ) {
			gos[0].disabled = disabled;
		}	
	}


/*************************************************************/


	
	/*  check user availability (uses AJAX check), and update indication
		takes the OBJECT to check, and the id of the msg label to update with the result*/  
   	function indicateAvailability(obj, actionUrl) {

		var xmlHttp = getNewAjaxObject();
		var fieldName_ = obj.name;
		if (obj.value == null || obj.value.trim() == '') {
			return;
		}	
		xmlHttp.onreadystatechange=function() {
			if(xmlHttp.readyState==4) {  // request complete
  				// Get the data from the server's response		
  				if (xmlHttp.status==200) { // only if OK			
				  	if (xmlHttp.responseText.match('true')) { 
				  		/* if the ajax reponse was simply 'true' i.e available*/
						setAvailable(fieldName_);					  		
					}
					else { /* the reasult was 'false' meaning that it's not available */
						set_field_message(fieldName_,"already taken");
					 	setUnavailable(fieldName_);						
						if (getFieldIndication(fieldName_).className!='field_bad') {
							set_error_indication_bad(fieldName_);
						}
					} 
				}
				else {	// no response?
					if (xmlHttp.status == 0) {
						return; // IGNORE the abort that might occur if the user presses register while the call is being sent
					}	
					set_field_message(fieldName_,"Unable to check "+ fieldName_ + " availability");
					if (getFieldIndication(fieldName_).className!='field_bad') {
						set_error_indication_bad(fieldName_);
					}
				}
  			}
		}
		xmlHttp.open("GET",actionUrl + obj.value,true);
  		xmlHttp.send(null);
   	}
	

	/* checks a STRING for alphanumeric validity. if it contains any character
		other than english letters or numbers, it returns false. true otherwise. */ 
	function alphanumeric_validation(str) {
		var result_ok = true;
		var alphaa;
		var hh;
		
		for(var j=0; j<str.length; j++)
		{
			alphaa = str.charAt(j);
			hh = alphaa.charCodeAt(0);
			if(!((hh > 47 && hh<59) || (hh > 64 && hh<91) || (hh > 96 && hh<123))) {
				result_ok = false;
		  	 }
		}
		return result_ok;
	}
	
	 function numeric_validation(str) {
    var result_ok = !(isNaN(str));
    return result_ok;
  }
  
	/* uses REGEX to validate an email string */
	function validateEmailStr(str) {
		emailpat = /^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/; 
		if (!emailpat.test( str )) {
			return false; // doesn't match
		}
		else {
			return true; // matches
		}
	}
	
	/* checks an email field for validity. takes the field OBJECT and a 
		visual indicator object - which it updates accordingly. returns the result
		as string.  */
	function validateEmail ( emailField ) {
		var result;
		fieldName = emailField.name;
		
		if(emailField.value.length==0) {
			clear_error_indication(fieldName);
			clear_field_error(fieldName);
			clear_field_message(fieldName);
			result = 'empty';
		}
		
		else if ( !validateEmailStr(emailField.value) ) { // email is invalid
			
			set_error_indication_bad(fieldName);
			set_field_message(fieldName,"invalid email");
		  	result='bad';
		 }
		 else {
		 	 if (getFieldIndication(fieldName).className != 'field_bad') {
		 	 
				 set_error_indication_ok(fieldName);
				 clear_field_error(fieldName);
				 result='good';
			}
			else {
				// leave it as it is, if it was already bad
			}	 
		 }
		return result;
	}
	
	// checks for URL validity using REGEX.. returns false if bad, true if good;
	function validateURL(str) {
	 var urlPattern = /((https?):\/\/([\-\w]+\.)+\w{2,4}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i
	 if (!urlPattern.test(str)) {
		return false;
	 }
	 return true;

}
	

/** ********************** GENERIC *************** */

	/* takes A STRING and returns true if it's empty and false if it's not */
	function validate_required(str)
	{
		var result = false;
			if (str == null || str == ""){
				result = true;
			}
			else{
				result = false;
			}
		return result;
	}
	
	function validate_length(str,min,max) {
		var result;
		if (str) {
			if (validate_maxlength(str,max) && validate_minlength(str,min)) {
				result = true;
			}
			else {
				result=false;
			}
		}
		return result;
	}
	
	function validate_maxlength(str,max) {
		var result=false;
		if (str && max) {
			if (str.length > max) {
				result=false;
			}
			else {
				result=true;
			}
		}
		return result;
	}
	
	function validate_minlength(str,min) {
		var result=false;
		if (str && min) {
			if (str.length < min) {
				result=false;
			}
			else {
				result=true;
			}
		}
		return result;
	}
	
/*************************************************/	
	
	


	/* compares two fields - obj and cmpobj, on the fly. Only if they match,
	   is it possible to get the "ok" (depends on the alphanumeric validity 
	   of the fields themselves */
	   
	/* IMPORTANT - NOTE: the function assumes the first field is the confirmation field*/
	function hotmatch(obj,cmpobj){
		var x = obj.value; /* confirmation field value*/
		var fieldName = obj.name;
		var w = cmpobj.value; /* regular field value*/
		var result;
		
		
		if (x==w) {
			hotvalid(cmpobj);
			result = hotvalid(obj);
			
			
		}
		else {
			if (x.length != 0) {
				set_error_indication_bad(fieldName);
				clear_field_error(fieldName);	
				set_field_message(fieldName, "passwords must match");
			}	
			else {
				/* do nothing, let user touch the confirmation field first!*/
			}
			result = 'nomatch';
		}
		
		return result; 
	}
		

	
	/* takes a field OBJECT and validates it - checks for emptiness and alphanumeric
		validity. returns a string with the appropriate result. */
	function validate_field_total(fieldobj) {
		var x = fieldobj.value;
		var result;
		
		if(validate_required(x)) {
			result = 'empty';
		}
		else if (alphanumeric_validation(x) &&  validate_length(x,3,64)) {
			
			result = 'good';
		}	
		else {
			result = 'bad';
		}
		
		 return result;
		
	}
	
	/* takes a url field OBJECT and validates it - checks for emptiness and URL
	validity. returns a string with the appropriate result. */
	function validate_url_total(fieldobj) {
		var x = fieldobj.value;
		var result;
		
		if(validate_required(x)) {
			result = 'empty';
		}
		else if (validateURL(x)) {
			
			result = 'good';
		}	
		else {
			result = 'bad';
		}
		
		 return result;
	}
	
	
	
	// the function calls hotvalid with timer
	function hotTimerValid(obj) {
		fieldName=obj.name;
		var timer = getTimerByFieldName(fieldName);
		if (timer.timer!=null) {
			clearTimeout(timer.timer);
		}	
		timer.timer=setTimeout(function(){hotvalid(obj)},850);
	}
	
	function hotTimerMatch(obj, cmpobj) {
		fieldName=obj.name;
		var timer = getTimerByFieldName(fieldName);
		if (timer.timer!=null) {
			clearTimeout(timer.timer);
		}	
		timer.timer=setTimeout(function(){hotmatch(obj,cmpobj);},850);
	}

	
	function hotTimerUsernameValid(obj,url) {
		fieldName=obj.name;
		var timer = getTimerByFieldName(fieldName);
		if (timer.timer!=null) {
			clearTimeout(timer.timer);
		}	
		timer.timer=setTimeout(function(){hotvalid(obj); indicateAvailability(obj,url)},850);
	
	}
	
	function hotTimerEmailValid(obj, url) {
		fieldName=obj.name;
		var timer = getTimerByFieldName(fieldName);
		if (timer.timer!=null) {
			clearTimeout(timer.timer);
		}	
		timer.timer=setTimeout(function(){validateEmail(obj);indicateAvailability(obj,url)},1000);
	}
	
	function hotTimerUrlValid(obj) {
		fieldName=obj.name;
		var timer = getTimerByFieldName(fieldName);
		if (timer.timer!=null) {
			clearTimeout(timer.timer);
		}	
		timer.timer=setTimeout(function(){hotvalidURL(obj);},1000);
	}
	
	
	/* validates a single field "on the fly". takes a field OBJECT,
	   an object for error label (errobj) and the visual indication object (vldobj).
	   updates the indication accordingly and resets the textual error.  
	   returns a text string with the appropriate result */
	function hotvalid(obj){
		var result;
		var fieldName = obj.name;
		switch (validate_field_total(obj)) {
			case 'good':
				if (getFieldIndication(fieldName).className=='field_bad' && fieldName == 'username') {
					// it was bad before we left
				}
				else {
					set_error_indication_ok(fieldName);
					result = 'good';						 
				}	
				clear_field_error(fieldName);
				break;
			case 'empty' :
				clear_error_indication(fieldName);
				clear_field_error(fieldName);
				clear_field_message(fieldName);
				result = 'empty';	
				break;
			default:
			case 'bad':
				set_error_indication_bad(fieldName);
				set_field_message(fieldName,"must be 3-64 letters &amp; digits");
				clear_field_error(fieldName);
				result = 'bad';
				break;
		} 
		
		return result;
	}
	

	
	
	
	// same as the regular hotvalid but for URLs
	function hotvalidURL(obj){
		var result;
		var fieldName = obj.name;

			
		switch (validate_url_total(obj)) {
			case 'good':
				set_error_indication_ok(fieldName);
				clear_field_error(fieldName);
				result = 'good';						 
				break;
			case 'empty' :
				clear_error_indication(fieldName);
				clear_field_error(fieldName);
				result = 'empty';	
				break;
			default:
			case 'bad':
				set_error_indication_bad(fieldName);
				set_field_message(fieldName,"invalid URL");
				clear_field_error(fieldName);		 
				result = 'bad';
				break;
		} 
		
		return result;
	}
	
	
	
	
	/* marks a field as errenous by changing the vld indication object to a different class*/
	/*function set_error_indication(errvldId) {
		document.getElementById(errvldId).className='field_bad'
	}*/
	
	function set_error_indication_bad(fieldName) {
		obj = getFieldIndication(fieldName);
		if (obj!=null) {
			obj.className='field_bad';
		}	
		
	}
	function set_error_indication_ok(fieldName) {
		obj = getFieldIndication(fieldName);
		if (obj!=null) {
			obj.className='field_ok';
		}	
		clear_field_message(fieldName);
		clear_field_error(fieldName);
		
	}
	
	function set_field_error(fieldName,errormsg) {
		var timer = getTimerByFieldName(fieldName);
		if (timer!=null && timer.timer!=null) {
			clearTimeout(timer.timer);
		}
		var obj = getFieldErrorLabel(fieldName);
		if (obj!=null) {
			obj.innerHTML=errormsg;
		}	
		clear_field_message(fieldName);
	}
	
	function set_field_message(fieldName,errormsg) {
		obj = getFieldMessageLabel(fieldName);
		if (obj!=null) {
			obj.innerHTML=errormsg;
		}	
		clear_field_error(fieldName);
	}	
	
	
	
	/* clears the error label of a field*/
	function clear_field_error(fieldName) {
		obj = getFieldErrorLabel(fieldName);
		if (obj!=null) {
			obj.innerHTML='';
		}	
	}
	/* clear the message of a field*/
	function clear_field_message(fieldName) {
		obj = getFieldMessageLabel(fieldName);
		if (obj!=null) {
			obj.innerHTML='';
		}	
	}	
	
	function clear_error_indication(fieldName) {
		getFieldIndication(fieldName).className = 'field_blank';
	} 
	
	function clear_all(fieldName) {
		clear_error_indication(fieldName);
		clear_field_error(fieldName);
		clear_field_message(fieldName);
	}
	
	function clearFieldErrors(field) {
		clear_all(field.name); 
		var timer = getTimerByFieldName(field.name);
		if (timer!=null && timer.timer!=null) {
			clearTimeout(timer.timer);
		}
	}
	
	
	function validate_form( thisform ){
		var result = true;
		with (thisform)
			{	
				/* if the URL is good, add "HTTP://" if necessary */				
				if (document.getElementById('blogurl_field')!=null) {
					switch(validate_url_total(blogurl)) {
						case 'good': 
							fixURLField(blogurl); 
							break;
						case 'empty':
							set_field_error(blogurl.name,"blog URL required");
							blogurl.focus;
							result=false;
							break;
						case 'bad':
							set_field_error(blogurl.name,"URL invalid");
							blogurl.focus;
							result=false;
							break;
					}
				} 
				
				
				switch (validateEmail(email)) {
					case 'empty':
						
						
						set_field_error(email.name,"email required");
						email.focus;
						result=false; 
						break;
					case 'bad':
						
						
						set_field_error(email.name,"invalid email");
						
						email.focus;
						result=false; 
						break;
				}
			
				
				switch (validate_field_total(username)) {
					case 'empty':
						
						
						set_field_error(username.name,"username required");
						
						username.focus;
						result = false; 
						break;
					case 'bad' :
						
						
						set_field_error(username.name,"must be 3-64 letters &amp; digits");
						
						username.focus;
						result = false;
						break;
				}				


				
				switch (validate_field_total(password)) {
					case 'empty':
						
						set_field_error(password.name,"password required");
						
						password.focus;
						result = false; 
						break;
					case 'bad' :
						
						set_field_error(password.name,"must be 3-64 letters &amp; digits");
						
						password.focus;
						result = false;
						break;
				}				


				switch (hotmatch(password2,password)) {
					case 'empty':
						
						set_field_error(password2.name,"password confirmation required");
						
						password2.focus;
						result = false; 
						break;
					case 'bad' :
						
						
						set_field_error(password2.name,"must be 3-64 letters &amp; digits");
					
						password2.focus;
						result = false;
						break;
					case 'nomatch':
						
						set_field_error(password2.name,"passwords don\'t match");
						
						password2.focus;
						result = false;
						break;						
						
				}			
				

					
			}
			
		return result;

	}	



