/**
 * ajax.js
 * Ajax caller and callback
 * Work with Yahoo UI and prototype 1.6
 *
 * 2 variables should be setup before using ajaxCaller object:
 *    ajax_tx_signature - String, transaction signature use to verify
 *                        the ajax request is true. Usually, you may use a
 *                        md5 encoded string of client's IP address or
 *                        login name as a tx signature.
 *    ajax_request_timeout - Integer, timeout of Ajax request. unit:ms.
 *                           e.g: 5000 (5sec)
 *
 * Usage :
 * var objCaller = new ajaxCaller(URL[, submitMethod[, debugMode]]);
 * objCaller.responseHandler = doSomething (arrResponse);
 * objCaller.errorHandler = popServerError (arrErrorMsg, intErrorNum, arrResponse);
 * objCaller.failureHandler = popAjaxError ();
 * objCaller.send([formObject|formID|dataObject]);
 *
 * The response should be a JSON object with following elements:
 * {
 *   'ajaxID'    : Integer, purely return the ajaxID sent with the Ajax
 *                 request
 *   'is_error'  : Boolean, indicate that the request is successed or
 *                 failed
 *   'error_num' : Integer. Optional value. Useful when you need to
 *                 determin what kinds of error occured. Default is 0. You
 *                 may set any value you like.
 *   'error_msg' : Array, holding all error message if the request failed
 *   'result'    : Array/Object, the response array or object. You may
 *                 defined them whatever they are.
 * }
 *
 * 
 * 
 **/

/* Ajax Loading Panel */
var oAjaxWaitPanel = new YAHOO.widget.Panel('ajaxWaitPanel',{
	width:"240px",
	fixedcenter:true,
	close:false,
	draggable:false,
	zIndex:999,
	modal:true,
	visible:false
});
oAjaxWaitPanel.setHeader('loading...');
oAjaxWaitPanel.setBody('<img src="core/jslib/images/rel_interstitial_loading.gif" />');

/* Ajax caller class        */
/* For sending Ajax request */
function ajaxCaller (sURL, placeHolder, sMethod, bDebugMode) {
	this.queries = [];
	var sepPos = sURL.indexOf("?");  //check ?
	if (sepPos == -1) {  // ? exist
		this.strURL = sURL;
	} else {
		this.strURL = sURL.substr(0, sURL.indexOf("?"));
		this.queries = this.queries.concat(sURL.substr(sURL.indexOf("?")+1).split("&"));
	}
	if (sMethod == undefined) this.httpMethod = 'POST';
	else this.httpMethod = sMethod;
	if (bDebugMode == undefined) this.debug_mode = false;
	else this.debug_mode = bDebugMode;
	this.debug_win = $('debug_info');
	if (!this.debug_win) this.debug_mode = false;
	this.responseHandler;
	this.errorHandler;
	this.failureHandler;
	oAjaxWaitPanel.render(document.body);
// Change overlay color in here
//	$('ajaxWaitPanel_mask').style.backgroundColor = "#000000";
	this.objCallback = new ajaxCallback(this.debug_mode);
	
	/**
	 * Send Ajax request
	 * argument could be one of the following:
	 *   form object
	 *   data object
	 *   form ID
	 *   form name
	 * argument could be omitted
	 */
	this.send = function (mixArgs) {
		var now = new Date();
		ajaxLoading(placeHolder);
		if (this.debug_mode)
			this.debug_win.value = 'Sending request to '+this.strURL+'...\n';
		// construct post data string
		var mixRequestData = null;
		if (mixArgs !== undefined && mixArgs !== null) {
			if (Object.isString(mixArgs)) {
				// form id or name
				var theObj = ($(mixArgs) || document.forms[mixArgs]);
			} else if (typeof mixArgs == "object") {
				var theObj = mixArgs; // may be a form object
			}
			if (!theObj) {
				alert('Invalid object');
				return;
			}
			if (theObj.tagName && theObj.tagName.toLowerCase()=='form') {
				// form
				if (!theObj['ajaxID']) { // the ajaxID field does not exists
					var aElement = document.createElement('input');
					with (aElement) {
						type = 'hidden';
						name = 'ajaxID';
						value = now.getTime();
					}
					theObj.appendChild(aElement);
				} else { // the ajaxID field already exists
					theObj['ajaxID'].value = now.getTime();
				}
				YAHOO.util.Connect.setForm(theObj);
			} else {
				// argument object
				mixArgs.ajaxID = now.getTime();
				var queryStr = Object.toQueryString(mixArgs);
				if (this.httpMethod=='POST') {
					mixRequestData = queryStr;
				} else if (this.httpMethod=='GET') {
					this.queries = this.queries.concat(queryStr.split("&"));
				}
			}
		} else {
			if (this.httpMethod=='POST') mixRequestData = 'ajaxID='+now.getTime();
			else if (this.httpMethod=='GET') this.queries.push('ajaxID='+now.getTime());
		}
		// construct callback object
		if (this.responseHandler)
			this.objCallback.responseSuccessHandler = this.responseHandler;
		if (this.errorHandler)
			this.objCallback.responseErrorHandler = this.errorHandler;
		if (this.failureHandler)
			this.objCallback.failure = this.failureHandler;
		// send request
		YAHOO.util.Connect.initHeader('X-Signature', ajax_tx_signature);
		if (this.queries.size() > 0) this.strURL += "?"+this.queries.join("&");
		this.cObj = YAHOO.util.Connect.asyncRequest(this.httpMethod, this.strURL, this.objCallback, mixRequestData);
	}
	
	this.isCalling = function () {
		if (this.cObj==undefined || this.cObj==null) return false;
		return YAHOO.util.Connect.isCallInProgress(this.cObj);
	}	
}

/* Ajax Callback class                     */
/* For handling all kinds of Ajax response */
var objAjaxResponse;
function ajaxCallback (bDebugMode, oDebugWin) {
	this.argument;
	this.timeout = ajax_request_timeout; // timeout value come from config.ini
	this.debug_mode = bDebugMode;
	if (oDebugWin != undefined) this.debug_win = oDebugWin;
	
	this.success = function (o) {
		ajaxDone();
		if (o.responseText !== undefined) {
			// convert JSON string to javascipt object
			try {
				objAjaxResponse = eval('('+o.responseText+')');
			} catch (e) {
				//alert("Invalid Ajax response received :\n\n"+o.responseText);
				this.responseErrorHandler([
					"Invalid Ajax response received :",
					o.responseText
				]);
				return;
			}
			// debug info
			if (this.debug_mode) {
				var now = new Date();
				var intDuration = now.getTime() - objAjaxResponse.ajaxID;
				with (this.debug_win)
				{
					value += "Transaction id: "+o.tId+"\n";
					value += "Ajax ID: "+objAjaxResponse.ajaxID+"\n";
					value += "HTTP status: "+o.status+'\n';
					value += "Status code message: "+o.statusText+'\n';
					if (o.argument) value += "Argument object: "+o.argument.toString()+"\n";
					value += "Duration: "+(intDuration/1000)+'sec.\n';
					value += "HTTP headers received:\n--------------------\n"+o.getAllResponseHeaders+'\n';
					//value += "Server Response Text:\n--------------------\n"+o.responseText+'\n\n';
					if (objAjaxResponse.debug_info)
						value += "Debug info:\n--------------------\n"+objAjaxResponse.debug_info+'\n';
				}
			}
			// handle response
			//var arrTrimedResponse = new Array();
			if (objAjaxResponse.is_error) {
				/*
				var arrTrimedErrorMsg = new Array();
				var arrErrorMsg = objAjaxResponse.error_msg;
				for (strKey in arrErrorMsg) {
					if (!isNaN(strKey))
						//arrTrimedErrorMsg[arrTrimedErrorMsg.size()] = arrErrorMsg[strKey];
						arrTrimedErrorMsg.push(arrErrorMsg[strKey]);
				}
				for (strKey in objAjaxResponse.result) {
					if (!isNaN(strKey)) {
						//arrTrimedResponse[arrTrimedResponse.size()] = objAjaxResponse[strKey];
						arrTrimedResponse.push(objAjaxResponse[strKey]);
					}
				}
				this.responseErrorHandler(arrTrimedErrorMsg, arrTrimedResponse);
				*/
				this.responseErrorHandler(
					objAjaxResponse.error_msg,
					objAjaxResponse.error_num,
					objAjaxResponse.result
				);
			} else if (this.responseSuccessHandler) {
				/*
				for (strKey in objAjaxResponse) {
					if (!isNaN(strKey)) {
						//arrTrimedResponse[arrTrimedResponse.size()] = objAjaxResponse[strKey];
						arrTrimedResponse.push(objAjaxResponse[strKey]);
					}
				}
				this.responseSuccessHandler(arrTrimedResponse);
				*/
				this.responseSuccessHandler(objAjaxResponse.result);
			}
		}
	}
	this.responseSuccessHandler;
	this.responseErrorHandler = ajaxErrorResponser;
	
	this.failure = function (o) {
		ajaxDone();
		if (this.debug_mode) {
			with (this.debug_win)
			{
				value += "Transaction id: "+o.tId+'\n';
				value += "HTTP status: "+o.status+'\n';
				value += "Status code message: "+o.statusText+'\n';
			}
		}
		alert(o.statusText);
	}
	
	// this.upload = function (o) {}
}

function ajaxLoading (placeHolder) {
	if ($('msg_area')) $('msg_area').innerHTML = '&nbsp;';
	if ($('msg_box')) $('msg_box').style.visibility = 'hidden';
	if (placeHolder == undefined) {
		oAjaxWaitPanel.show();
	} else {
		$(placeHolder).innerHTML = '<div align="center"><img src="core/jslib/images/47.gif" align="center" /></div>';
	}
	return;
}

function ajaxDone () {
	oAjaxWaitPanel.hide();
	return;
}

function ajaxErrorResponser (arrErrorMsg, intErrorNum, arrResponse) {
	var strResult = '';
	for (var i=0; i<arrErrorMsg.size(); i++) {
		strResult += arrErrorMsg[i]+'\n';
	}
	alert(intErrorNum+" - "+strResult);
}

