/**
 * Constants
*/
var MAX_TIME = 2000;
var regExp = new Object;
	regExp.GENERIC = /^.+$/i;
	regExp.name = /^(\s+)?$/i; //name can't be empty or contain only spaces
	regExp.mail = /^\w[\w_\-\.]*[\w]\@\w[\w_\-\.]*\w\.[\w]{2,4}$/i; //check RFC2822
	regExp.tel = /^[1-9]\d+$/i; //phone and area codes must be numbers, not beginning with 0
	regExp.age = /^\d{1,2}$/i;
var _POPUP_FEATURES = 'location=0,statusbar=0,menubar=0,scrollbars=1';

/**
 * Global variables
*/
var loaded = false;
var imgs = new Array();
var hintStack = new Array();
var timeOutID = 0;
var hbox;
var objXMLHttp = null;
var AJAX_result;

/**
 * Adds an event to the obj given
 * @param obj object whose event is to be defined
 * @param ev name of the event without "on" (e.g. "onclick" changes to "click")
 * @param fun the function callback when event is triggered
*/
function addEvent(obj,ev,fun){
	if(obj.addEventListener) obj.addEventListener(ev,fun,false);
	else obj["on"+ev] = fun;
}

/**
 * Removes an event from the object
 * @see addEvent
*/
function removeEvent(obj,event,fun){
	if(obj.removeEventListener) obj.removeEventListener(event,fun,false);
	else obj["on"+event_name] = null;
}

// Stop an event from bubbling up the event DOM
function stopEvent(evt){
	if(!evt) evt = window.event;
	if (evt.stopPropagation){
		evt.stopPropagation();
		evt.preventDefault();
	}
	evt.cancelBubble = true;
	evt.returnValue = false;
	return false;
}

/**
 * Initiates an asynchronous AJAX request
 *
 * @param url url of request to execute
 * @param fun function to execute when response is ready
*/
function AJAX_init(url,fun){
	if (window.XMLHttpRequest) objXMLHttp = new XMLHttpRequest();
	else if (window.ActiveXObject){
		try { objXMLHttp = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch(e) { objXMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
	}
	objXMLHttp.onreadystatechange = function (){
		if (objXMLHttp.readyState==4 || objXMLHttp.readyState=="complete"){
			AJAX_result = objXMLHttp.responseText;
			fun();
		}
	}
	objXMLHttp.open("GET",url,true);
	objXMLHttp.send(null);
}

/**
 * Calculates the absolute left offset of object obj 
 * without the need to use absolute positioning in CSS.
 * 
 * @param obj id of the object whose offset is to be calculated
*/
function offsetLeft(obj){
	var total = 0;
	var parentEle = document.getElementById(obj);
	while (parentEle != null){
		total += parentEle.offsetLeft;
		parentEle = parentEle.offsetParent;
	}
	return total;
}

/**
 * Calculates the absolute top offset of object obj 
 * without the need to use absolute positioning in CSS.
 *
 * @param obj id of the object whose offset is to be calculated
*/
function offsetTop(obj){
	var total = 0;
	var parentEle = document.getElementById(obj);
	while (parentEle != null){
		total += parentEle.offsetTop;
		parentEle = parentEle.offsetParent;
	}
	return total;
}

/**
 * Hides the "hintbox" div.
*/
function unHint(){
      hbox.style.visibility = "hidden";
      hbox.style.left = "-500px";
}

/**
 * Displays the "hintbox" div with an appropriate hint message.
 * @param e triggered event
*/
function hint(e){
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	var tip_name = targ.id.split("_",2);
	AJAX_init('/tip.php?name='+tip_name[1],updateHint);
	hbox.style.top = offsetTop(targ.id)+targ.offsetHeight/2+"px";
	hbox.style.left = offsetLeft(targ.id)+targ.offsetWidth/2+"px";
	clearTimeout(timeOutID);
	timeOutID = 0;
	hbox.style.visibility = "visible";
}

function updateHint(){
	hbox.innerHTML = AJAX_result;
	var wide = ((AJAX_result.replace(/<[^>]+>/ig,"")).replace(/&[\w]+;/,"")).length/5;
	if(wide <= 25) hbox.style.width = "150px";
	else if(wide > 50) hbox.style.width = "300px";
	else hbox.style.width = (150 + (wide-25)*6) + "px";
}

/**
 * Prepares a div called "hintbox" to present the hint. Also declares events for 
 * various elements
*/
function init(e1){
	if(loaded) return true;
	hbox = document.createElement("div");
	hbox.setAttribute("id","hintbox");
	addEvent(hbox,'mouseover',function(e2){ clearTimeout(timeOutID); timeOutID = 0; });
	addEvent(hbox,'mouseout',function(e2){ timeOutID = setTimeout('unHint()',MAX_TIME); });
	document.body.appendChild(hbox);

	links = document.getElementsByTagName("a");
	for(var i=0; i<links.length; i++){
		if(links[i].className == "popup"){
			addEvent(links[i],'click',function(e2){
				var theWindow = window.open(this.getAttribute('href'),'blank',_POPUP_FEATURES);
				theWindow.focus();
				stopEvent(e2);
			});
		}
		else if(links[i].className == "external"){
			addEvent(links[i],'click',function(e2){
				var theWindow = window.open(this.getAttribute('href'),'blank',_POPUP_FEATURES+',width=800,height=600');
				theWindow.focus();
				stopEvent(e2);
			});
		}
		else if(links[i].className == "help"){
			addEvent(links[i],'click',function(e2){
				var theWindow = window.open(this.getAttribute('href'),'blank',_POPUP_FEATURES+',width=300,height=550');
				theWindow.focus();
				stopEvent(e2);
			});
		}
	}

	imgs = document.getElementsByTagName("img");
	for(var i=0; i<imgs.length; i++){
		if(imgs[i].className == "warn"){
			var tip_name = imgs[i].id.split("_",2);
			var tip = tip_name[1];
			var input = document.getElementById(tip);

/**
 * For each mandatory input text element, declare an 'onchange' event 
 * to check the validity of the input's contents according to the 
 * regular expressions
 * 
 * @internal substituting 'onchange' with 'onkeyup', etc., can cause response lags, 
 * as well as accessibility breakage
*/
			if(input.type == "text"){
				switch(tip){
					case "mail":
						addEvent(document.getElementById(input.id),'change',function(){
							var img = document.getElementById("warn_"+this.id);
							img.style.visibility = regExp.mail.test(this.value)?"hidden":"visible";
						});
						break;
					case "tel":
						addEvent(document.getElementById(input.id),'change',function(){
							var img = document.getElementById("warn_"+this.id);
							var lada = document.getElementById("lada");
							img.style.visibility = (regExp.tel.test(this.value)&&regExp.tel.test(lada.value))?"hidden":"visible";
						});
						break;
					case "age":
						addEvent(document.getElementById(input.id),'change',function(){
							var img = document.getElementById("warn_"+this.id);
							img.style.visibility = regExp.age.test(this.value)?"hidden":"visible";
						});
						break;
					case "name":
						addEvent(document.getElementById(input.id),'change',function(){
							var img = document.getElementById("warn_"+this.id);
							img.style.visibility = !regExp.name.test(this.value)?"hidden":"visible";
						});
						break;
					default:
						addEvent(document.getElementById(input.id),'change',function(){
							var img = document.getElementById("warn_"+this.id);
							img.style.visibility = regExp.GENERIC.test(this.value)?"hidden":"visible";
						});
						break;
				}
			}
			addEvent(document.getElementById(imgs[i].id),'mouseover',hint);
			addEvent(document.getElementById(imgs[i].id),'mouseout',function(e2){ timeOutID = setTimeout('unHint()',MAX_TIME); });
		}
	}
	var forms = document.getElementsByTagName("form");
	for(var f = 0;f<forms.length;f++){
		addEvent(forms[f],'submit',function (e2){
			imgs = document.getElementsByTagName("img");
			for(var i=0;i<imgs.length;i++){
				if(imgs[i].className == "warn"){
					var tip_name = imgs[i].id.split("_",2);
					var tip = tip_name[1];
					var input = document.getElementById(tip);
					switch(tip){
						case "mail":
							if(!regExp.mail.test(input.value)){
								var go = document.getElementById('go');
								AJAX_init('/tip.php?name=err',updateHint);
								hbox.style.top = offsetTop(go.id)+go.offsetHeight/2+"px";
								hbox.style.left = offsetLeft(go.id)+go.offsetWidth/2+"px";
								clearTimeout(timeOutID);
								timeOutID = 0;
								hbox.style.visibility = "visible";
								timeOutID = setTimeout('unHint()',MAX_TIME);
								stopEvent(e2);
							}
							break;
						case "tel":
							if(!regExp.tel.test(input.value)){
								var go = document.getElementById('go');
								AJAX_init('/tip.php?name=err',updateHint);
								hbox.style.top = offsetTop(go.id)+go.offsetHeight/2+"px";
								hbox.style.left = offsetLeft(go.id)+go.offsetWidth/2+"px";
								clearTimeout(timeOutID);
								timeOutID = 0;
								hbox.style.visibility = "visible";
								timeOutID = setTimeout('unHint()',MAX_TIME);
								stopEvent(e2);
							}
							break;
						case "name":
							if(regExp.name.test(input.value)){
								var go = document.getElementById('go');
								AJAX_init('/tip.php?name=err',updateHint);
								hbox.style.top = offsetTop(go.id)+go.offsetHeight/2+"px";
								hbox.style.left = offsetLeft(go.id)+go.offsetWidth/2+"px";
								clearTimeout(timeOutID);
								timeOutID = 0;
								hbox.style.visibility = "visible";
								timeOutID = setTimeout('unHint()',MAX_TIME);
								stopEvent(e2);
							}
							break;
						default:
							if(!regExp.GENERIC.test(input.value)){
								var go = document.getElementById('go');
								AJAX_init('/tip.php?name=err',updateHint);
								hbox.style.top = offsetTop(go.id)+go.offsetHeight/2+"px";
								hbox.style.left = offsetLeft(go.id)+go.offsetWidth/2+"px";
								clearTimeout(timeOutID);
								timeOutID = 0;
								hbox.style.visibility = "visible";
								timeOutID = setTimeout('unHint()',MAX_TIME);
								stopEvent(e2);
							}
							break;
					}
				}
			}
			return true;
		});
	}
	loaded = true;
	return true;
}

if(document.addEventListener) addEvent(document,'DOMContentLoaded',init);
if(!window.ActiveXObject) addEvent(window,'load',init);

/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
document.getElementById("__ie_onload").onreadystatechange = function() {
    if (this.readyState == "complete") init();
};
/*@end @*/
