(function(){
GupShup.ajax = {};
GupShup.ajax.send = function(reqType, url, callBack, reqIdentifier){
	
	var callbackWrapper = {
		success: GupShup.ajax.successCallback,
		failure: GupShup.ajax.failureCallback,
		argument: {
			callback: callBack,
			reqIdentifier: reqIdentifier
		}
	};
	
	var conn = {
		method: reqType,
		url: url,
		callBack: callbackWrapper,
		tType: reqIdentifier,
		onAbort: function(){}
	};
	
	var t = GupShup.connectionManager.makeConnection(conn);
	if(t.status)
	{
		if(reqIdentifier != 'READ' && reqIdentifier != 'DYNAMICBAR' && reqIdentifier != 'PENDINGACTION')
			GupShup.html.util.showLoader();
		return t.tObj;
	}
	else
		return null;
};

GupShup.ajax.sendForm = function(reqType, url , callBack, form, isMultiPartData){
	var callbackWrapper = {};
	
	if(isMultiPartData)
		 callbackWrapper = {
			upload : GupShup.ajax.successCallback,
			success: GupShup.ajax.successCallback,
			failure: GupShup.ajax.failureCallback,
			argument: {
				callback: callBack,
				reqIdentifier: 'FORM'
			}
		};
	else
		 callbackWrapper = {
			upload : GupShup.ajax.successCallback,
			success: GupShup.ajax.successCallback,
			failure: GupShup.ajax.failureCallback,
			argument: {
				callback: callBack,
				reqIdentifier: 'FORM'
			}
		};
		
	var conn = {
		method:reqType,
		url:url,
		callBack:callbackWrapper,
		tType:'FORM',
		onAbort: function(){},
		form:form,
		isMultiPartData:isMultiPartData
	};
	var t = GupShup.connectionManager.makeConnection(conn);
	if(t.status)
	{
		GupShup.html.util.showLoader();
		return t.tObj;
	}
	else
		return null;
};

GupShup.ajax.successCallback = function(xhr) {
	var originalCallback = xhr.argument.callback;
	var reqIdentifier = xhr.argument.reqIdentifier;
	xhr.argument = originalCallback.argument;
	originalCallback.success(xhr);
	
	if(reqIdentifier != 'DYNAMICBAR')
		GupShup.util.callUrchinTracker(xhr);
};

GupShup.ajax.failureCallback = function(xhr) {
	var originalCallback = xhr.argument.callback;
	var reqIdentifier = xhr.argument.reqIdentifier;
	xhr.argument = originalCallback.argument;
	originalCallback.failure(xhr);
}

})();

/*
connection = {
	method :  'GET/POST',
	url : 'asdad.adad.adad',
	callback :  {},
	tType:'FORM/PAGINATION/TAB/READ/WRITE'
	form : 'ABCD',(Name or Form Obj)
	isMultiPartData : false
}
GupShup Conn Manager will store All active transactions in an TransactionQ as 
tObj = {obj:transaction , type : 'FORM/PAGINATION/TAB/READ/WRITE', onAbort: function()}
*/
(function(){
GupShup.connectionManager = {};
GupShup.connectionManager.transactionQ = new Array();
GupShup.connectionManager.makeConnection = function(connection){
	if(typeof connection.form == 'string')
	{
		YAHOO.util.Connect.setForm(document.forms[connection.form], connection.isMultiPartData);
	}
	else if(typeof connection.form == 'object')
	{
		YAHOO.util.Connect.setForm(connection.form, connection.isMultiPartData);
	}
	
	if(!GupShup.connectionManager.isNextTransactionPermitted())
	{
		return {status:false};
	}
	var tObj = YAHOO.util.Connect.asyncRequest(connection.method, connection.url, connection.callBack);
	GupShup.connectionManager.addTransaction({obj:tObj,type:connection.tType, onAbort:connection.onAbort});
	return {status:true,tObj:tObj};
}

GupShup.connectionManager.addTransaction = function(tObj){
	if(!GupShup.connectionManager.isNextTransactionPermitted())
	{
		GupShup.connectionManager.abortTransaction(tObj);
	}
	if(GupShup.connectionManager.isTransactionAlive(tObj))
	{
		GupShup.connectionManager.abortLPTransactions(tObj.type); // Remove earlier similar requests
		GupShup.connectionManager.transactionQ.push(tObj);	// Add new req to transactionQ
	}
}

GupShup.connectionManager.isTransactionAlive = function(tObj){
	if(tObj == null || typeof tObj == 'undefined')
		return false;
	else
		return YAHOO.util.Connect.isCallInProgress(tObj.obj);
}

GupShup.connectionManager.isNextTransactionPermitted = function(){
	var allowed = true;
	var tQ  = GupShup.connectionManager.transactionQ;
	for(var i = 0 ; i < tQ.length ; i++)
	{
			if(!GupShup.connectionManager.isTransactionAlive(tQ[i]))
				tQ[i] = null;
			else
			{
				if(GupShup.connectionManager.isAbortable(tQ[i]))
					continue;
				else
				{
					allowed = false;
					break;
				}
			}
	}
	
	return allowed;
}
GupShup.connectionManager.isAbortable = function(tObj){
	switch(tObj.type)
	{
		case 'FORM' :
		case 'WRITE' :	return false;
		case 'READ' :	// making read as abortable so that any other req can go in parallel with read
		case 'DYNAMICBAR':
		case 'PAGINATION': 
		case 'PENDINGACTION' :
		case 'USER_INTIATED_READ' :
		case 'TABSWITCH': return true;
	}
}
//Lower priority value indicates highly intensive
GupShup.connectionManager.getPriority = function(type){
	switch(type)
	{
		case 'FORM' :
		case 'WRITE' :	return 1;
		case 'TABSWITCH': return 2;
		case 'DYNAMICBAR': return 3;
		case 'PAGINATION': return 4;
		case 'PENDINGACTION': return 5;
		case 'USER_INTIATED_READ': return 6;
		default : return 7; 
	}
}

GupShup.connectionManager.abortLPTransactions = function(type){
	var tQ  = GupShup.connectionManager.transactionQ;
	var tempQ = new Array();
	var pReq = GupShup.connectionManager.getPriority(type);
	var len = tQ.length;
	for(var i = 0 ; i < len ; i++)
	{
		var transObj = tQ.pop();
		if(GupShup.connectionManager.isTransactionAlive(transObj))
		{
			if(transObj.type != 'READ') // Do not abort any read request if any other high priority req comes Its hack:(
			{
				var pAvialable = GupShup.connectionManager.getPriority(transObj.type);
				if((transObj.type == type) || (pReq < pAvialable))
				{
					GupShup.connectionManager.abortTransaction(transObj);
				}
				else
				{
					tempQ.push(transObj);	
				}
			}
		}
	}
	GupShup.connectionManager.transactionQ = tempQ;
}

GupShup.connectionManager.abortTransaction = function(tObj){
	if(GupShup.connectionManager.isAbortable(tObj))
	{
		YAHOO.util.Connect.abort(tObj.obj); //Abort running transaction
		if(typeof tObj.onAbort == 'function')
			tObj.onAbort();	//Execute onAbort function if any
	}
}
})();
