/******************************************************************************
* Error codes
******************************************************************************/
//Error for when the XMLHttpRequest is unsupported or cannot be created
//this is a fatal error on this script
var ERR_CREATE_REQ = new Number(0);
//Error for when the get request returns no data.  This is not a fatal error,
//it can be caused by a 404 or an unresponsive server
var ERR_RETURN_NULL = new Number(0);

/******************************************************************************
* Ready State codes
*******************************************************************************
*     These are error codes in case there is an error
******************************************************************************/
//Error for when the XMLHttpRequest is unsupported or cannot be created
//this is a fatal error on this script
var RS_UNINITIALIZED = new Number(0);
var RS_LOADING = new Number(1);
var RS_LOADED = new Number(2);
var RS_INTERACTIVE = new Number(3);
var RS_COMPLETED = new Number(4);


function isArray(obj) {
   if (!obj.constructor || obj.constructor.toString().indexOf("Array") == -1)
      return false;
   else
      return true;
}

/******************************************************************************
* AsyncXMLGetRequest - Wrapper class for XMLHttpRequest
*******************************************************************************
*   Properties:
*     xmlRequest - the queue of XMLHttpRequests
*     inRequest - a boolean that marks whether or not the queue is active
*     requestQueue - the queue of URLs to be requested
*     objectQueue - the queue of objects to be used in the "onService" routine
******************************************************************************/
function AsyncXMLGetRequest()
{
	this.xmlRequest = new Array();
	this.inRequest = new Boolean(false);
	this.requestQueue = new Array();
	this.objectQueue = new Array();
	this.postQueue = new Array();
	this.formQueue = new Array();
	this.queueCount = new Number(0);
}
/******************************************************************************
* AsyncXMLGetRequest::setup - setup method for AsyncXMLGetRequest
*******************************************************************************
*     allocates the newest item in the queue its own xml request.
******************************************************************************/
AsyncXMLGetRequest.prototype.setup = function()
{
	if(typeof XMLHttpRequest!='undefined')
	 {
		this.xmlRequest[this.queueCount] = new XMLHttpRequest();
	}
return;
}
/******************************************************************************
* AsyncXMLGetRequest::queueGetRequest - queue method for AsyncXMLGetRequest
*******************************************************************************
*     this method queues a request
******************************************************************************/
AsyncXMLGetRequest.prototype.queuePost = function(myUrl, myPostData, myObject, form_obj)
{
	if(typeof(form_obj) != "undefined" && form_obj != undefined && form_obj != '')
	{
		if(isArray(form_obj))
		{
			for(x=0;x<form_obj.length;x++)
			{
				form_data = form_obj[x];
				for(i=0; i<form_data.elements.length; i++)
				{
					if(form_data.elements[i].id)
					{
					//myPostData = myPostData + "&" + form_data.elements[i].id + "=" + form_data.elements[i].value;
					//window.alert("val" + form_data.elements[i].value);
						form_data.elements[i].id = form_data.elements[i].id.replace(/&/g, "[and]");
						form_data.elements[i].value = form_data.elements[i].value.replace(/&/g, "[and]");

						if(form_data.elements[i].type == "checkbox" || form_data.elements[i].type == "radio")
						{
							if(form_data.elements[i].checked == true)
							{
								myPostData = myPostData + "&" + form_data.elements[i].name + "=" + form_data.elements[i].value;
							}
						}
						else
						{
							myPostData = myPostData + "&" + form_data.elements[i].name + "=" + form_data.elements[i].value;
						}				
					}
				}	
			}
		}
		else
		{
			form_data = form_obj;

			for(i=0; i<form_data.elements.length; i++)
			{
				if(form_data.elements[i].id)
				{
				//myPostData = myPostData + "&" + form_data.elements[i].id + "=" + form_data.elements[i].value;
				//window.alert("val" + form_data.elements[i].value);
					form_data.elements[i].id = form_data.elements[i].id.replace(/&/g, "[and]");
					form_data.elements[i].value = form_data.elements[i].value.replace(/&/g, "[and]");

					if(form_data.elements[i].type == "checkbox" || form_data.elements[i].type == "radio")
					{
						if(form_data.elements[i].checked == true)
						{
							myPostData = myPostData + "&" + form_data.elements[i].name + "=" + form_data.elements[i].value;
						}
					}
					else
					{
						myPostData = myPostData + "&" + form_data.elements[i].name + "=" + form_data.elements[i].value;
					}				
				}
			}
		}
	}

	if(myPostData.indexOf('target') == -1)
	{
			myPostData = myPostData + "&" + "target=" + myObject;
	}
    if(this.inRequest == false)
	{
			this.inRequest = true;

			this.requestQueue[this.queueCount] = myUrl;
			this.objectQueue[this.queueCount] = myObject;
			this.postQueue[this.queueCount] = myPostData;
			this.formQueue[this.queueCount] = form_obj;
			this.setup();
			onRequest(this.objectQueue[this.queueCount]);
			this.queueCount++;

			this.sendPostRequest(myUrl, 0, myPostData);
	}
    else if(this.inRequest == true)
	{
		for(i=0;i<=this.queueCount;i++)
		{
			if(this.requestQueue[i] == myUrl && this.objectQueue[i] == myObject &&  this.postQueue[i] == myPostData &&  this.formQueue[i] == form_obj)
			{
				//window.alert('duplicate');
				// skip complete duplicate request already in queue
				return false;
			}
		}
		
		this.requestQueue[this.queueCount] = myUrl;
        this.objectQueue[this.queueCount] = myObject;
        this.postQueue[this.queueCount] = myPostData;
        this.formQueue[this.queueCount] = form_obj;
        this.setup();
        onRequest(myRequest.objectQueue[this.queueCount], myRequest.requestQueue[this.queueCount], myRequest.postQueue[this.queueCount], myRequest.formQueue[this.queueCount]);
        this.queueCount++;
	}
	
	// for floating div, turn on display for target div and its parent
	if(myObject == 'float_div')
	{
		position_float();
	}	
}

/******************************************************************************
* AsyncXMLGetRequest::sendPostRequest - sendPostRequest method for AsyncXMLGetRequest
*******************************************************************************
*     this method sends the specified request as POST
******************************************************************************/
AsyncXMLGetRequest.prototype.sendPostRequest = function(myUrl, qCount, postData)
{
    if(this.xmlRequest[qCount] == null)
	{
	    onRequestError(myRequest.objectQueue[0], ERR_CREATE_REQ, "Instance of XMLHttpRequest cannot be created or is null!");
	}
    else
	{
		// automatically get post data if it's remembered
		if( (postData == '' || postData == undefined || postData.indexOf('remember_post') > -1) && document.getElementById(myRequest.objectQueue[qCount]) != undefined  )
		{
			postData = document.getElementById(myRequest.objectQueue[qCount]).getAttribute("post_data");
			//if(postData == undefined) postData = '';
			//window.alert(postData);
		}

		//window.alert(myUrl);
		//window.alert(this.qCount +" " + this.queueCount +" " +postData);

		if(myUrl.substring(0,1) == '/')
		{
			this.xmlRequest[qCount].open("POST", myUrl, true);
		}
		else
		{
			this.xmlRequest[qCount].open("POST", "/"+myUrl, true);
		}
		
		document.body.style.cursor = 'wait';

		this.xmlRequest[qCount].setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.xmlRequest[qCount].setRequestHeader("Content-length", postData.length);
		this.xmlRequest[qCount].setRequestHeader("Connection", "close");
		this.xmlRequest[qCount].onreadystatechange = xmlHTTPStateChangePOST;
		this.xmlRequest[qCount].send(postData + "&ajax=1");

		//window.alert(postData);
	}
}

/******************************************************************************
* xmlHTTPStateChange - callback funciton
*******************************************************************************
*     this function is a callback used by the XMLHttpRequest object when there
*     is a change in the ready state.  If the ready state is 4, that means that
*     the content is loaded.  This function calls the onService routine always
*     with the number zero, because per a queue, the current element serviced
*     is always the first in.  After servicing, the first element in is
*     deleted from the queue, and if there are other requests waiting, the
*     next one in line will be handled, else the request chain is done.
******************************************************************************/
var myRequest = new AsyncXMLGetRequest();
function xmlHTTPStateChangePOST()
{
    //IF the request is uninitialized, before send() is called
    if(myRequest.xmlRequest[0].readyState == RS_UNINITIALIZED)
	{
	}
    //send() has not been called
    else if(myRequest.xmlRequest[0].readyState == RS_LOADING)
	{
	}
    //send() has been called, headers and status are available
    else if(myRequest.xmlRequest[0].readyState == RS_LOADED)
	{
	}
    //data is being downloaded
    else if(myRequest.xmlRequest[0].readyState == RS_INTERACTIVE)
	{
	}
    //the request has completed
    if(myRequest.xmlRequest[0].readyState == RS_COMPLETED)
	{
		this_response = myRequest.xmlRequest[0].responseText;
		
		if(myRequest.xmlRequest[0].status == 500)
		{
	    	this_response = "<div><b class='red'>Server Error</b></div>";
		}
		
		onServicePOST(myRequest.objectQueue[0], myRequest.requestQueue[0], this_response, myRequest.postQueue[0], myRequest.formQueue[0]);

		myRequest.queueCount--;
		myRequest.requestQueue.splice(0, 1);
		myRequest.objectQueue.splice(0, 1);
		myRequest.postQueue.splice(0, 1);
		myRequest.formQueue.splice(0, 1);
		myRequest.xmlRequest.splice(0, 1);

		if(myRequest.queueCount == 0)
		{
			myRequest.inRequest = new Boolean(false);
		}
		else
		{
		    myRequest.sendPostRequest(myRequest.requestQueue[0], 0, myRequest.postQueue[0]);
		}
    }
}

/******************************************************************************
* onRequest - callback processing function
*******************************************************************************
*     this is called whenever a request is queued in AsyncXMLGetRequest.  This
*     function is passed the reference variable that was passed into the
*     queue, and can be used to prepare the object for the data.  Usually, this
*     function will take the form of a "loading" or "please wait" prompt, to
*     let the user know that the request has been queued, and you are awaiting
*     data.  The originally requested URL is passed in case it is needed.
******************************************************************************/
function onRequest(requestObj, requestURL)
{
	// skip this if it's a server request with no destination
	if(!requestObj)
	{
		return;
	}
	// loading images
	var proc_img = "processing.gif";
	if(requestObj.indexOf('float') > -1 || requestObj.indexOf('rating') > -1)
	{
		proc_img = "loading.gif"
	}
	else if(requestObj.indexOf('add') > -1 || requestObj.indexOf('autosearch') > -1)
	{
		proc_img = "loading2.gif"
	}
	document.getElementById(requestObj).innerHTML = "<img src='/images/" + proc_img + "' />";
}
/******************************************************************************
* onService - callback processing function
*******************************************************************************
*     this is called whenever a request is serviced (meaning the data requested
*     has been recieved).  It can be used to update the object that requested
*     the data.  The originally requested URL is passed in case it is needed.
*     The data requested is passed as requestItem.
******************************************************************************/
function onServicePOST(requestObj, requestURL, requestItem, post_data, form_obj, js_tab_name)
{
	// if nothing was returned from the request, we don't need to do anything else
	if(requestItem == '')
	{
		return;
	}
	
	obj_name = new String(requestObj);

	// parse html comments as script commands to evaluate
	var re_dml = new RegExp('<div style="display:none;" id="dml">(.*)</div id="dml">');

	//retrieve DML objects
	var dml_objects = requestItem.match(re_dml);

	// don't display this in any capacity to the client browser
	requestItem = requestItem.replace(re_dml, "");
	
	if(requestObj !== '' && typeof(document.getElementById(requestObj)) != 'undefined')
	{
		var object = document.getElementById(requestObj);
		object.innerHTML = requestItem;
		object.style.visibility = 'visible';
	}
	//window.alert(dml_objects);
	if(dml_objects != null)
	{
		eval(dml_objects[1]);
	}

	document.body.style.cursor = 'auto';

	
	// for floating div, turn on display for target div and its parent
	if(requestObj == 'float_div')
	{
		position_float();
	}	
}
/******************************************************************************
* onRequestError - callback processing function
*******************************************************************************
*     this is called whenever there is an error with a request, either a file
*     not found, or trouble initializing the XMLHttpRequest
******************************************************************************/
function onRequestError(requestObj, errorCode, verboseError)
{
	//
}


function position_float()
{
	body_el = document.getElementById('document_body');
	doc_height = body_el.offsetHeight+120;
	
	// this block fixes the IE directx issue for the opaque background
	if(doc_height > 2048)
	{
		if(!document.getElementById('float_bg_1'))
		{
			document.getElementById('float_bg').style.height = "2048px";
			document.getElementById('float_bg').style.zIndex = -1;
			count=1;
			total_height=2048;
			while(total_height < doc_height)
			{
				clone = document.getElementById('float_bg').cloneNode(true);
				clone.id = 'float_bg_'+count;
				clone.style.zIndex = -1;
				//clone.style.backgroundColor='red';
				clone.style.top = (count*2048)+"px";
				document.getElementById('float_el').insertBefore(clone,document.getElementById('float_bg'));
				count++;				

				this_add = 2048;
				if((total_height + this_add) >= doc_height)
				{
					this_add = (doc_height - total_height);
					clone.style.height = this_add+"px";
				}
				total_height += this_add;
			}
		}
	}
	else
	{
			document.getElementById('float_bg').style.height = doc_height + "px";
	}
	
	document.getElementById('float_el').style.display = "block";
	var float_table = document.getElementById('float_container');
	
	arr_scroll = getScrollXY();
	arr_size = getSize();
	
	new_top = arr_scroll[1];
	win_height = arr_size[1];
	
	top_plus = (win_height/2)-((document.getElementById('float_div').offsetHeight+44)/2);
	new_top += top_plus;
	if(new_top < 0) new_top = 0;
	float_table.style.top = new_top + "px";
}

function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}

function getSize() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
return [myWidth,myHeight];
}