/*********************************************
# Name: common.js
# Type: javascript
# Version: 1.1
# Description: main ajax functions
**********************************************/

/* generic global vars */
var DBG = 0;
var debug = 'debug'; // debug frame-id

/* set ajax global vars */
var xmlHttp = null; // xmlHttpRequest instance
var myField = null; // frame-id where ajax response has to write to
/* return response flag. If we find this as a fake field to write to,
we will set a var for calling function instead of writing in field */
var rrFlag = 'setResponseVar';
var returnResponse; // var to set as response. Remember to reset after!

/* generic ajax error messages */
var alertNoXml = 'Browser does not support HTTP Request!';
var alertSrvErr = 'There was an error comunicating to the server!';


/* AJAX FUNCTIONS */

/* sync/async request wrapper: use this call in your js functions */
function rqs (rFld, rUrl, rPar, sync) {
	// debug line
	if (DBG) { htmlReplace(debug, 'writeTo: '+rFld+'<br />url: '+rUrl+'?'+rPar); }
	if (rUrl && rUrl != '') {
		// initialize xml objects
		myField = rFld; // pass field-id to global var
		xmlHttp = GetXmlHttpObject(); // new xml object instance
		if (xmlHttp==null) { alert (alertNoXml); }
		else {
			// sync or async call
			if (sync == 1) { rPost(rUrl, rPar); }
			else { rGet(rUrl, rPar); }
		}
	}
	else if (DBG) { urlUndef('rqs'); }
	return;
}

/* asyncronous request */
function rGet (rUrl, rPar) {
	var url = rUrl + '?' + rPar;
	xmlHttp.onreadystatechange = stateChanged;
	xmlHttp.open('GET', url, true);
	xmlHttp.send(null);
	return;
}

/* syncronous request */
function rPost (rUrl, rPar) {
	xmlHttp.open('POST', rUrl, false);
	stateChanged(); // explicit call to stateChanged
	xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	xmlHttp.setRequestHeader('Content-length', rPar.length);
	xmlHttp.setRequestHeader('Connection', 'close');
	xmlHttp.send(rPar);
	stateChanged(); // explicit call to stateChanged
	return;
}

/* this function is called when a sync/async request state is changed */
function stateChanged() {
	// debug line
	if (DBG) { htmlAdd(debug, ' - St1('+xmlHttp.readyState+')'); }
	if (xmlHttp.readyState==4 || xmlHttp.readyState=='complete') {
		if (xmlHttp.status==200) {
			// debug line
			if (DBG) { htmlAdd(debug, ' - St2('+xmlHttp.status+')'); }
			var parsedTxt = xmlHttp.responseText ? xmlHttp.responseText : ''; // avoid null response error
			if (myField == rrFlag) { returnResponse = parsedTxt; } // here we have to return the response
			else { htmlReplace(myField, parsedTxt); } // standard behaviour
		}
		else { alert (alertSrvErr); }
		xmlHttp = null;
	}
	return;
}

/* new xmlhttp object creation */
function GetXmlHttpObject() {
	var objXMLHttp=null;
	if (window.ActiveXObject) {
		objXMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
		if (!objXMLHttp) { objXMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); }
	}
	else if (window.XMLHttpRequest) { objXMLHttp = new XMLHttpRequest(); }
	return objXMLHttp;
}


/* HTML FUNCTIONS */

/* read and return inner html string */
function htmlGet (rFld) {
	var htmlStr = '';
	if (document.getElementById(rFld)) {
		htmlStr = parent.document.getElementById(rFld).innerHTML
	}
	else if (DBG) { elmUndef(rFld, 'htmlGet'); }
	return htmlStr;
}

/* replace innerHTML with passed string
if string is null, will clean-up field
htmlReplace (fieldID, string); */
function htmlReplace (rFld, htmlStr) {
	if (!htmlStr) { htmlStr = ''; } // avoid null values
	/* standard behaviour */
	if (document.getElementById(rFld)) {
		document.getElementById(rFld).innerHTML = htmlStr;
	}
	/* try parent if standard doc missed */
	else if (parent.document.getElementById(rFld)) {
		parent.document.getElementById(rFld).innerHTML = htmlStr;
	}
	else if (DBG) { elmUndef(rFld, 'htmlReplace'); }
	return;
}

/* add innerHTML with passed string
htmlAdd (fieldID, string); */
function htmlAdd (rFld, htmlStr) {
	if (document.getElementById(rFld)) {
		var doFld = document.getElementById(rFld)
		var oldStr = doFld.innerHTML;
		if (htmlStr && htmlStr != '') {
			doFld.innerHTML = oldStr + htmlStr;
		}
	}
	else if (DBG) { elmUndef(rFld, 'htmlAdd'); }
	return;
}

/* replace image src
srcImg : source path of image - note: same width n height! */
function imgReplace (rImg, srcImg) {
	if (document.getElementById(rImg)) {
		document.getElementById(rImg).src = srcImg;
	}
	else if (DBG) { elmUndef(rImg, "imgReplace"); }
	return;
}

/* set visible/invisible function
rSet: 0=invisible, 1=visible, 2=swap
rWidth, rHeight: 0=auto, else pixel width */
function setVisible (rFld, rSet, rWidth, rHeight) {
	if (document.getElementById(rFld)) {
		var doFld = document.getElementById(rFld);	
		if (rSet==1 || (rSet==2 && doFld.style.visibility=="hidden")) {
			rSet = "visible";
			rWidth = (rWidth > 0) ? rWidth : "auto";
			rHeight = (rHeight > 0) ? rHeight : "auto";
		}
		else {
			rSet = "hidden"; rWidth = "0"; rHeight = "0";
		}
		if (rWidth != "auto") { rWidth += "px"; }
		if (rHeight != "auto") { rHeight += "px"; }
		doFld.style.width = rWidth;
		doFld.style.height = rHeight;
		doFld.style.overflow = "hidden";
		doFld.style.visibility = rSet;
	}
	else if (DBG) { elmUndef(rFld, 'setVisible'); }
	return;
}

/* set class of an element
rClass : class of elemet */
function setClass (rFld, rClass) {
	if (document.getElementById(rFld)) {
		document.getElementById(rFld).className = rClass;
	}
	else if (DBG) { elmUndef(rFld, 'setClass'); }
	return;
}


/* FORM FIELDS VALUES FUNCTIONS */

/* get an input field value */
function getInputValue (rFld) {
	if (document.getElementById(rFld)) {
		return document.getElementById(rFld).value;
	}
	else if (DBG) { elmUndef(rFld, 'getInputValue'); }
	return;
}

/* set an input field to given value */
function setInputValue (rFld, sValue) {
	if (document.getElementById(rFld)) {
		if (!sValue) { sValue = ''; } // avoid null values
		document.getElementById(rFld).value = myUnescape(sValue);
	}
	else if (DBG) { elmUndef(rFld, 'setInputValue'); }
	return;
}

/* set the current input field the value */
function setThisValue (rFld, sValue) {
	if (!sValue) { sValue = ''; } // avoid null values
	rFld.value = myUnescape(sValue);
}

/* get the selected value from a drop down menu */
function getSelectValue (rFld) {
	if (document.getElementById(rFld)) {
		var mySelect = document.getElementById(rFld);
		return mySelect.options[mySelect.selectedIndex].value;
	}
	else if (DBG) { elmUndef(rFld, 'getSelectValue'); }
	return;
}

/* set a specific option-value-index into a select drop down menu, passing the option index
sIndex : option value index to set to */
function setSelectIndex (rFld, sIndex) {
	if (document.getElementById(rFld)) {
		var mySelect = document.getElementById(rFld);
		mySelect.selectedIndex = sIndex;
		return;
	}
	else if (DBG) { elmUndef(rFld, 'setSelectIndex'); }
	return;
}

/* get check value of a checkbox */
function getChecked (rFld) {
	if (document.getElementById(rFld)) {
		return document.getElementById(rFld).checked;
	}
	else if (DBG) { elmUndef(rFld, 'getChecked'); }
	return;
}

/* Check/Uncheck all checkboxes of given group name
rForm = id (not name!) of the form
grpName = group name (not id!) of checkboxes */
function checkAll (rForm, grpName, rSet) {
	if (document.getElementById(rForm) && document.getElementById(rForm).elements[grpName]) {
		var myChecks = document.getElementById(rForm).elements[grpName];
		var maxChecks = myChecks.length;
		rSet = (rSet == 1 || rSet == 'checked') ? 'checked' : '';
		var i; for (i=0; i<maxChecks; i++) { myChecks[i].checked = rSet; }
	}
	else if (DBG) { elmUndef(rForm + '.' + grpName, 'checkAll'); }
	return;
}

/* get all checked values of checkboxes of given group name
rForm = id (not name!) of the form
grpName = group name (not id!) of checkboxes
returns Array of values */
function getCheckValues (rForm, grpName) {
	if (document.getElementById(rForm) && document.getElementById(rForm).elements[grpName]) {
		var myChecks = document.getElementById(rForm).elements[grpName];
		var maxChecks = myChecks.length;
		var myValues = new Array();
		var i; for (i=0; i<maxChecks; i++) {
			if (myChecks[i].type == 'checkbox' && myChecks[i].checked == true) {
				myValues.push(myChecks[i].value);
			}
		}
	}
	else if (DBG) { elmUndef(rForm + '.' + grpName, 'getCheckValues'); }
	return myValues;
}


/* FORM FIELDS ATTRIBUTES FUNCTIONS */

/* enable/disable input field
use with: input=any, select, textarea
rSet: 0=disable; 1=enable; 2=swap */
function setEnable (rFld, rSet) {
	if (document.getElementById(rFld)) {
		var doFld = document.getElementById(rFld);
		if (!rSet || rSet == 0) { doFld.disabled = true; }
		else if (rSet == 1) { doFld.disabled = false; }
		else if (rSet == 2) { doFld.disabled = (doFld.disabled) ? false : true; }
	}
	else if (DBG) { elmUndef(rFld, 'setEnable'); }
	return;
}

/* sets readonly/writeable input field
use with: input=text, textarea
rSet: 0=readonly; 1=writable; 2=swap */
function setWritable (rFld, rSet) {
	if (document.getElementById(rFld)) {
		var doFld = document.getElementById(rFld);
		if (!rSet || rSet == 0) { doFld.readOnly = true; }
		else if (rSet == 1) { doFld.readOnly = false; }
		else if (rSet == 2) { doFld.readOnly = (doFld.readOnly) ? false : true; }
	}
	else if (DBG) { elmUndef(rFld, 'setWritable'); }
	return;
}


/* FORM SUBMIT FUNCTIONS */

/* form submitting function
NOTE: never put the loader replacing the form or it will not find the form!!!
1) submitted form is retrieved by submit button (passed as this)
2) ajax request script url is retrieved from form action attribute
3) all input fields are retrieved from the passed group name (field name attribute)
4) the querystring to pass is added to passed already parameters */
function formSubmit (rFld, thisButton, grpName, rPar) {
	var myFormId = thisButton.form.id;
	if (myFormId != '') {
		var myForm = document.getElementById(myFormId);
		var myAction = myForm.action;
		if (myAction != '') {
			if (DBG) { htmlReplace('debug', 'form: ' + myFormId + '; action: ' + myAction); }
			// search for group name (fields name)
			if (myForm.elements[grpName]) {
				// we have everything, start processing
				myGrp = myForm.elements[grpName]; // form items group name
				numElm = myGrp.length; // number of items in group
				var myParams = new Array(); // prepare array of field=value
				// iterate all group elements
				var i; for (i=0; i<numElm; i++) {
					// input/password text
					if (myGrp[i].type == 'text' || myGrp[i].type == 'password' || myGrp[i].type == 'textarea') {
						myParams.push( myGrp[i].id + '=' + myEscape(myGrp[i].value) );
					}
					// select drop down fields
					else if (myGrp[i].type == 'select-one') {
						myParams.push(myGrp[i].id + '=' + myEscape(myGrp[i].options[myGrp[i].selectedIndex].value) );
					}
					// check boxes
					else if (myGrp[i].type == 'checkbox' && myGrp[i].checked == true) {
						myParams.push(myGrp[i].id + '=' + myEscape(myGrp[i].value) );
					}
					else if (DBG) { elmUndef('Type of '+myGrp[i].id, 'formSubmit'); }
				}
				if (rPar) { rPar += '&'; } // we still have paremeters before
				rPar += myParams.join('&');
				// here comes the real call!
				rqs(rFld, myAction, rPar, 1);
			}
			else if (DBG) { elmUndef(grpName, 'formSubmit'); }
		}
		else if (DBG) { urlUndef('formSubmit'); }
	}
	else if (DBG) { idUndef('Form', 'formSubmit'); }
	return;
}


/* UTILITY FUNCTIONS */

/* my Escape function */
function myEscape(str) {
	str = escape(str);
	return str.replace(/\+/g, "%2B").replace(/\*/g,"%2A").replace(/\@/g,"%40").replace(/\./g,"%2E").replace(/\//g,"%2F");
}

/* my Unescape function */
function myUnescape(str) {
	str = unescape(str);
	return str.replace(/%2B/g, "+").replace(/%2A/g,"*").replace(/%40/g,"@").replace(/%2E/g,".").replace(/%2F/g,"/");
}


/* ERROR FUNCTIONS */

/* undefined element error */
function elmUndef (myElm, func) {
	htmlReplace(debug, myElm + ' not defined at ' + func);
	return;
}

/* undefined url error */
function urlUndef (func) {
	htmlReplace(debug, 'URL not defined at ' + func);
	return;
}

/* undefined id error */
function idUndef (myElm, func) {
	htmlReplace(debug, myElm + ' ID not defined at ' + func);
	return;
}

