
var obj_hbox;
var arrObjInputBox = new Array(); // the array storing all input boxes that registered as TextBox class 
var gblTimeout1; // time out global variable 1, for showing the warning message
var gblTimeout2; // time out global variable 2, for disappear the message
var highlight_color = "rgb(237,41,57)";
var highlight_border_width = "2px";
var highlight_border_style = "solid";
var pageMoveUpALittleBitWhenFocus = 100; // page move up a little bit when warning and focus occur

// ------------------------------------------------------------
// ------ CLASS Definition start ------
function TextBox(obj) {
	this.id = obj.id;
	this.name = obj.name;
	if (obj.attributes["desc"])
		this.desc = obj.attributes["desc"].value;
	else
		this.desc = "";
	this.htm = obj.outerHTML;
	this.style = obj.style;
	this.offsetHeight = obj.offsetHeight;
	this.type = obj.type;
	// it is abit horrible to calculate the input box position, especially they are nested into table(s),
	// we have to try to detect their parent's position as much as we can
	this.offsetTop = obj.offsetTop; //findPosX(obj);
	this.offsetLeft = obj.offsetLeft; //findPosY(obj);
}
TextBox.prototype.setBorderColor = function (c, bw, bs) {
	this.style.borderColor = c;
	this.style.borderWidth = bw;
	this.style.borderStyle = bs;
}

TextBox.prototype.showDesc = function (obj, d) {
	showDescNow(obj, d);
}
TextBox.prototype.addEvtListener = function (target, type, func, bubbles) {
	if (document.addEventListener) {
		// mozilla
		target.addEventListener(type, func, bubbles);
	} else if (document.attachEvent) {
		// IE
		target.attachEvent("on"+type, func, bubbles);
	} else {	
		target["on"+type] = func;
	}
}
TextBox.prototype.delEvtListener = function (target, type, func, bubbles) {
	if (document.addEventListener) {
		// mozilla
		target.removeEventListener(type, func, bubbles);
	} else if (document.attachEvent) {
		// IE
		target.detachEvent("on"+type, func, bubbles);
	} else {	
		target["on"+type] = null;
	}
}
// ------------- CLASS Definition ended ------------
// ------------------------------------------------------------
function onOut(event) {
	if (event.target) {
		// Mozilla 
		highLightTextBox(this, false);
	} else {
		// IE
		highLightTextBox(event.srcElement, false);
	}
}

function onOver(event) {
	if (event.target) {
		// Mozilla
		highLightTextBox(this, true);
	} else {
		// IE
		highLightTextBox(event.srcElement, true);
	}
}
function hbox(hboxId) {
	// input box preloader that store all input box & textarea object into "arrObjInputBox" array, 
	// and registered them as instance of Class TextBox
	var arrTextBox;
	var obj = document;
	var a = 0;
	obj_hbox = document.getElementById(hboxId);
	arrTextBox = obj.getElementsByTagName("input");
	for (var i=0;i<arrTextBox.length;i++) {
		if (arrTextBox[i].type!="submit" && arrTextBox[i].type!="button" && arrTextBox[i].type!="hidden") { 
			arrObjInputBox[a] = new TextBox(arrTextBox[i]);
			arrObjInputBox[a].addEvtListener(arrTextBox[i], "blur", onOut, false);
			arrObjInputBox[a].addEvtListener(arrTextBox[i], "focus", onOver, false);
			a++;
		}
	}
	arrTextBox = obj.getElementsByTagName("textarea");
	for (var i=0;i<arrTextBox.length;i++) {
		arrObjInputBox[a] = new TextBox(arrTextBox[i]);
		arrObjInputBox[a].addEvtListener(arrTextBox[i], "blur", onOut, false);
		arrObjInputBox[a].addEvtListener(arrTextBox[i], "focus", onOver, false);
		a++;
	}
	arrTextBox = obj.getElementsByTagName("select");
	for (var i=0;i<arrTextBox.length;i++) {
		arrObjInputBox[a] = new TextBox(arrTextBox[i]);
		arrObjInputBox[a].addEvtListener(arrTextBox[i], "blur", onOut, false);
		arrObjInputBox[a].addEvtListener(arrTextBox[i], "focus", onOver, false);
		a++;
	}
}
function clearTO(i) {
	// clear all timeout
	clearTimeout(gblTimeout1);
	clearTimeout(gblTimeout2);
}
function resetDescBox()
{
	// reset the description box
	clearTO();
	var obj = obj_hbox;
	if (obj) {
		obj.innerHTML = "";
		obj.style.visibility = "hidden";
		obj.style.top = "0px"
		obj.style.left = "0px"
		obj.style.filter = 'alpha(opacity=0)';
		obj.style.MozOpacity = 0;
	}
}
function showDescNow(objBox, str, up) {
	// display a nice sliding box showing the description "str"
	resetDescBox(); // reset the previous box
	var obj = obj_hbox; // obj of the box
	if (obj && str!="") {
		if (objBox) {
			obj.innerHTML = str;
			obj.style.left = objBox.offsetLeft;
			obj.style.top = objBox.offsetTop;
			obj.style.visibility = "visible";
			if (up)
				animateDesc(100, objBox.offsetTop, (objBox.offsetTop-obj.offsetHeight), true); // box rise up
			else
				animateDesc(100, (objBox.offsetTop+objBox.offsetHeight-(obj.offsetHeight/4)), (objBox.offsetTop+objBox.offsetHeight), false); // box drop down
		}
	}
}
function animateDesc(op, topStart, topEnd, up)
{
	// animation to show and then hidden the desc in a period of time
	var newTop
	if (up)
		newTop = parseInt( topStart-(topStart-topEnd)*((100-op)/100) );
	else
		newTop = parseInt( topStart+(topEnd-topStart)*((100-op)/100) );
	var obj = obj_hbox;
	if (obj) {
		obj.style.filter = "alpha(opacity="+parseInt(100-op)+")";
		obj.style.MozOpacity = parseInt(100-op); 
		if (up) {
			// show upward
			if (newTop>topEnd) 
				obj.style.top = newTop+"px";
			else
				obj.style.top = topEnd+"px";
		} else {
			// show downward
			if (newTop<topEnd) 
				obj.style.top = newTop+"px";
			else
				obj.style.top = topEnd+"px";
		}
		if (op>1) {
			op/=2;
			gblTimeout1 = setTimeout("animateDesc("+op+", "+topStart+", "+topEnd+", "+up+")", 50);
		} else {
			clearTO();
			gblTimeout2 = setTimeout("resetDescBox()", 5000);
		}
	}
}
function highLightTextBox(curObj, over) {
	// debug use
	textBox = new TextBox(curObj);
	if (over) {
		textBox.setBorderColor(highlight_color, highlight_border_width, highlight_border_style);
	} else {
		resetDescBox();
		textBox.setBorderColor("", "", "");
	}
}

function hboxAlert(objBox, message, up) {
	// warning the user that some input are invalid or empty with the message given
	if (objBox) {
		if (message==null || message=="" ) {
			if (message==null && objBox.attributes["desc"] && objBox.attributes["desc"].value!="")
				message = objBox.attributes["desc"].value;
			else
				message = "Please insert a value";
		}
		for (var i=0;i<arrObjInputBox.length;i++) {
			// loop through all input boxes to find the correct instance of TextBox
			if (objBox.name == arrObjInputBox[i].name) {
				if (up)
					showDescNow(objBox, message, true);
				else
					showDescNow(objBox, message);
				break;
			}
		}
		objBox.focus();
		moveUpLittleBit();
	} else if (objBox) {
		objBox.focus();
	}
}

function moveUpLittleBit() {
	// page move up a little bit when warning occur
	var theTop;
	if (document.documentElement && document.documentElement.scrollTop)
		theTop = document.documentElement.scrollTop;
	else if (document.body)
		theTop = document.body.scrollTop;
	document.body.scrollTop = parseInt(theTop)-parseInt(pageMoveUpALittleBitWhenFocus);
}