//////////////////////////////////////////////////////////////////////////////////////////////
/********************************************************************************************
AJAX CLASS
version: 0.0.0.11
15/09/09
********************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////

var AJAX = {}

///////////////////////////////////////
/**************************************
LOADING NAMESPACE
**************************************/
///////////////////////////////////////
if (typeof(General) === 'undefined')
{
	var _scriptObj2 = document.createElement('script');
    _scriptObj2.src = 'http://www.girlsense.com/premium/tools/clientScripts/general.js';
    _scriptObj2.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(_scriptObj2);
}

///////////////////////////////////////
/**************************************
ENUMS
**************************************/
///////////////////////////////////////
AJAX.Method = {GET:'GET', POST:'POST'};
AJAX.Type = {ASYNC:true, SYNC:false};


///////////////////////////////////////
/**************************************
AJAX CLASS
**************************************/
///////////////////////////////////////
AJAX.request = function(url, requestMethod, requestType, onSuccessFunction, onFailFunction, onTimeoutFunction)
{
	this.url = url || null;	
	this.requestMethod = (requestMethod.toUpperCase() === AJAX.Method.POST) ? AJAX.Method.POST : AJAX.Method.GET;
	this.requestType = requestType === AJAX.Type.SYNC ? AJAX.Type.SYNC : AJAX.Type.ASYNC;
	
	// url //
	if (this.url === null)
	{
		this.exception = {Error : "No url supported"};
		return this;
	}
	
	// initiating request //
	this.initRequest();
	
	if (typeof(onSuccessFunction) === 'function')
		this.onSuccessFunction = onSuccessFunction;
	if (typeof(onFailFunction) === 'function')
		this.onFailFunction = onFailFunction;
	if (typeof(onTimeoutFunction) === 'function')
		this.onTimeoutFunction = onTimeoutFunction;
	
	return this;
}

///////// VARIABLES 
AJAX.request.prototype.num = 0;
AJAX.request.prototype.url = '';
AJAX.request.prototype.params = '';
AJAX.request.prototype.extra = '';
AJAX.request.prototype.requestMethod = AJAX.Method.GET;
AJAX.request.prototype.xmlhttp = null;
AJAX.request.prototype.exception = null;
AJAX.request.prototype.requestType = AJAX.Type.ASYNC;
AJAX.request.prototype.status = 0;
AJAX.request.prototype.statusText = 0;
AJAX.request.prototype.headers = null;
AJAX.request.prototype.isRunning = false;
AJAX.request.prototype.responseText = '';
AJAX.request.prototype.responseXml = '';
AJAX.request.prototype.onSuccessFunction = null;
AJAX.request.prototype.onFailFunction = null;
AJAX.request.prototype.onTimeoutFunction = null;
AJAX.request.prototype.timeout = 10000;
AJAX.request.prototype.timeoutHandler = null;
AJAX.request.prototype.maxAttempts = 3;
AJAX.request.prototype.currentAttempt = 1;
AJAX.request.prototype.lastSendDate = null;
AJAX.request.prototype.numberOfConnections = 0;
AJAX.request.prototype.averageResponseTime = 0;
AJAX.request.prototype.lastResponseTime = 0;
AJAX.request.prototype.Log = new Array();

///////// METHODS
AJAX.request.prototype.initRequest = function()
{
	var xmlhttp = null;
	try 
	{
		if(General.browser !== 'ie6')
		{
			// Firefox, Konqueror, Safari, Chrome, Opera, IE7, IE8
			xmlhttp = new XMLHttpRequest();
		}
		else
		{
		 	// IE4,5,5.5,6
			xmlhttp = new AJAX.ActiveX("Microsoft.XMLHTTP");
		}
	} 
	catch(ex)
	{
		this.exception = {Error: ex.message,Object: ex}
		this.xmlhttp = xmlhttp;
		this.addToLog("Exception. Couldnt create xmlhttp object.");
		return;
	}
	
	this.xmlhttp = xmlhttp;
	
	// adding a referrence to this object //
	this.xmlhttp.referrence = this;
	
	this.addToLog("xmlhttp object created");
}

AJAX.request.prototype.start = function(params, headers)
{
	// checking required properties //
	if (this.xmlhttp === null)
		 this.exception = {Error : "No xml http object was created. check log"};
	if (typeof(this.onSuccessFunction) !== 'function')
		this.exception = {Error : "No on success function supported"};
	else if (typeof(this.onFailFunction) !== 'function')
		this.exception = {Error : "No on fail function supported"};
	else if (typeof(this.onTimeoutFunction) !== 'function')
		this.exception = {Error : "No on timeout function supported"};
	else if (typeof(params) !== 'string' || params === '' )
		this.exception = {Error : "Illegal params supported"};
	else if (this.isRunning)
		this.exception = {Error : "A connection is already running"};
	else	
		this.exception = null;
	
	// checking if there are exceptions //
	if (this.exception !== null)
	{
		this.addToLog("Exception in request.start(). please check object.expection");
		return false;
	}
		
	// starting to run the connection //
	this.isRunning = true;
	
	// saving params //
	this.params = params;
	
	// adding params to url //
	if (this.requestMethod === AJAX.Method.GET)
		this.url += "?" + params;
		
	// openning request //
	this.xmlhttp.open(this.requestMethod, this.url, this.requestType);
	
	// headers //
	headers = headers || null;
	if (headers !== null && headers instanceof Array)
	{
		for (var h in headers)
		{
			this.xmlhttp.setRequestHeader(h,headers[h]);	
		}
		this.headers = headers;
	}
	else
	{
		if (this.requestMethod === AJAX.Method.POST)
			this.xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	}
		
	var br = General.browser;
	if (br === 'ie6' || br === 'ie7' || br === 'ie8')
    {
		this.xmlhttp.onreadystatechange = function()
		{
			switch(this.readyState)
			{
				case 1:
					this.referrence.addToLog("params is packed");
					break;
				case 2:
					this.referrence.addToLog("params were sent");
					break;
				case 3:
					this.referrence.addToLog("params are being sent by server");
					break;
				case 4:
					AJAX.responseHandler(this);
					break;
			}
		}
		if (br === 'ie7' || br === 'ie8')
		{
			this.xmlhttp.onerror = function()
			{
				this.addToLog("request error");
				this.referrence.currentAttempt = 1;
				this.referrence.onFailFunction(this.referrence);
			}
		}
    }
    else
    {
		this.xmlhttp.onload = function()	
		{
			AJAX.responseHandler(this);
		}
		this.xmlhttp.onerror = function()
		{
			this.addToLog("request error");
			this.referrence.currentAttempt = 1;
			this.referrence.onFailFunction(this.referrence);	
		}
		
    }
	    
    var xmlhttp = this.xmlhttp;
    this.timeoutHandler = setTimeout(function(){
	   xmlhttp.abort();
	   xmlhttp.referrence.addToLog("request timed out");
	   xmlhttp.referrence.isRunning = false;
	   xmlhttp.referrence.onTimeoutFunction(xmlhttp.referrence);
    }, this.timeout);
    
    this.addToLog("openning connection");
    this.lastSendDate = new Date();
	if (this.requestMethod === AJAX.Method.POST)
		this.xmlhttp.send(this.params);
    else
    	this.xmlhttp.send();
    	
    return true;
}

AJAX.request.prototype.addToLog = function(text)
{
	if (!text)	return;
	
	var d = new Date();
	var day = d.getDate();
	var month = d.getMonth();
	var year = d.getFullYear();
	var h = d.getHours();
	var m = d.getMinutes();
	var s = d.getSeconds();
	
	if (h < 10)
		h = "0" + h;
		
	if (m < 10)
		m = "0" + m;
		
	if (s < 10)
		s = "0" + s;
		
	var time = day + "/" + month + "/" + year + "   " + h + ":" + m + ":" + s;
		
	this.Log.push(time + "  -  " + text);
}

AJAX.request.prototype.logToHTML = function()
{
	var html = new Array();
	var l = this.Log.length;
	for (var i=0;i<l;++i)
	{
		html.push(this.Log[i] + "<br/>");
	}
	return html.join("");
}

AJAX.request.prototype.logToString = function()
{
	var html = new Array();
	var l = this.Log.length;
	for (var i=0;i<l;++i)
	{
		html.push(this.Log[i] + "\n");
	}
	return html.join("");
}

///////////////////////////////////////////////////////////////////////////
///////// STATIC requestMethodS
///////////////////////////////////////////////////////////////////////////
AJAX.responseHandler = function(xmlhttp)
{
	// calculating average response time //
	var now = new Date();
	xmlhttp.referrence.lastResponseTime = now-xmlhttp.referrence.lastSendDate;
	var totalTime = (xmlhttp.referrence.averageResponseTime * xmlhttp.referrence.numberOfConnections++);
	xmlhttp.referrence.averageResponseTime = (totalTime + xmlhttp.referrence.lastResponseTime) / xmlhttp.referrence.numberOfConnections;
	
	// canceling timeout //
	clearTimeout(xmlhttp.referrence.timeoutHandler);
	xmlhttp.referrence.timeoutHandler = null;
	
	// clearing running flag //
	xmlhttp.referrence.isRunning = false;
	
	// trying to get status //
	var status = -1;
	try
	{
		status = xmlhttp.status;	
	}			
	catch(e){}
	
	// log //
	xmlhttp.referrence.addToLog("response receieved, status: " + status);
	
	// saving response texts //
	xmlhttp.referrence.responseText = xmlhttp.responseText;
	xmlhttp.referrence.responseXml = xmlhttp.responseXml;
	xmlhttp.referrence.status = status;
	xmlhttp.referrence.statusText = xmlhttp.statusText;
	
	
	if (status === 200)
	{
		xmlhttp.referrence.currentAttempt = 1;
		xmlhttp.referrence.onSuccessFunction(xmlhttp.referrence);
	}
	else if (status === 400 || status === 404 || status === 500)
	{
		xmlhttp.referrence.currentAttempt = 1;
		xmlhttp.referrence.onFailFunction(xmlhttp.referrence);
	}
	else if (status === 503)
	{
		if (xmlhttp.referrence.currentAttempt++ <= xmlhttp.referrence.maxAttempts)
		{
			xmlhttp.referrence.addToLog("trying again");
			setTimeout(function(){xmlhttp.referrence.start(xmlhttp.referrence.params)},200);
		}
		else
		{
			xmlhttp.referrence.addToLog("max tries reached");
			xmlhttp.referrence.currentAttempt = 1;
			xmlhttp.referrence.onFailFunction(xmlhttp.referrence);
		}
	}
}

///////////////////////////////////////////////////////////////////////////
///////// IE6 ACTIVEX OBJECT IMPROVED
///////////////////////////////////////////////////////////////////////////
AJAX.ActiveX = function(progid)
{
	var ax = new ActiveXObject(progid);
	var object = null;
	if (progid == "Microsoft.XMLHTTP")
	{
		// properties //
		object = 
		{
			_ax: ax,
	      	responseText: "",
	      	responseXml: null,
	      	readyState: 0,
	      	status: 0,
	      	statusText: 0,
	      	onreadystatechange: null,
	      	referrence : null
		}
		
		// methods //
		object._onreadystatechange = function()
		{
			var self = object;
			self.readyState = self._ax.readyState;
			if (self.readyState === 4)
			{
				self.responseText = self._ax.responseText;
				self.responseXml  = self._ax.responseXml;
				self.status       = self._ax.status;
				self.statusText   = self._ax.statusText;
				self.abort();
			}
			if (typeof(self.onreadystatechange) === 'function')
				self.onreadystatechange();
		}
		object.open = function(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword)
		{
			varAsync = (varAsync !== false);
			this._ax.onreadystatechange = this._onreadystatechange
			this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
		};
		object.send = function(varBody)
		{
			varBody = varBody || null;
			this._ax.send(varBody);
		};
		object.setRequestHeader = function(param, value)
		{
			if (!param || !value) return;
			
			this._ax.setRequestHeader(param, value);	
		}
		object.abort = function()
		{
			this._ax.abort();
		}
	}
	else
	{
		object = ax;	
	}
	
	return object;
}

/**************** [PROTOTYPED VERSION] *****************/
/*
AJAX.ActiveX = function(progid)
{
	this._ax = new ActiveXObject(progid);
	if (progid === "Microsoft.XMLHTTP")
	{
		return this;
	}
	else
	{
		return _ax;	
	}
}

///////// VARIABLES 
AJAX.ActiveX.prototype._ax = null;
AJAX.ActiveX.prototype.responseText = '';
AJAX.ActiveX.prototype.responseXml = null;
AJAX.ActiveX.prototype.readyState = 0;
AJAX.ActiveX.prototype.status = 0;
AJAX.ActiveX.prototype.statusText = '';
AJAX.ActiveX.prototype.onreadystatechange = null;
AJAX.ActiveX.prototype.referrence = null;


///////// METHODS 
AJAX.ActiveX.prototype._onreadystatechange = function()
{
	alert( this instanceof ActiveXObject);
	alert(this._ax);
	return;
	
	this.readyState = this._ax.readyState;
	if (this.readyState === 4)
	{
		this.responseText = this._ax.responseText;
		this.responseXml  = this._ax.responseXml;
		this.status       = this._ax.status;
		this.statusText   = this._ax.statusText;
	}
	if (typeof(this.onreadystatechange) === 'function')
		this.onreadystatechange();
}

AJAX.ActiveX.prototype.open = function(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword)
{
	varAsync = (varAsync !== false);
	this._ax.onreadystatechange = this._onreadystatechange;
	this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
};
AJAX.ActiveX.prototype.send = function(varBody)
{
	varBody = varBody || null;
	this._ax.send(varBody);
};
AJAX.ActiveX.prototype.setRequestHeader = function(param, value)
{
	if (!param || !value) return;
	
	this._ax.setRequestHeader(param, value);	
}
AJAX.ActiveX.prototype.abort = function()
{
	this._ax.abort();
}
*/





