/******************************************************************************
* Error 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 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);

/******************************************************************************
* AsyncXMLGetRequest - Wrapper class for XMLHttpRequest
*******************************************************************************
*     this class is used as a wrapper class for XMLHttpRequest because browsers
*     are dumb and can't seem to support the same classes.  It also facilitates
*     the request queue, where each request that is made on the object waits
*     in the queue to be filled.
*   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()
{

	// Try for IE native support first
	if(typeof XMLHttpRequest!='undefined')
	 {
		this.xmlRequest[this.queueCount] = new XMLHttpRequest();
		//window.alert('native IE support that also works in Firefox');
	}
	else
	{

		try
		{
			this.xmlRequest[this.queueCount] = new ActiveXObject("Msxml2.XMLHTTP");
			//window.alert('test msxml2');
		}
		catch (e)
		{
			try
			{
				this.xmlRequest[this.queueCount] = new ActiveXObject("Microsoft.XMLHTTP");
				//window.alert('test msxml');
			}

			catch (E)
			{
				xmlhttp = null;
			}
		}
	}

return;
}
/******************************************************************************
* AsyncXMLGetRequest::queueGetRequest - queue method for AsyncXMLGetRequest
*******************************************************************************
*     this method queues a request
******************************************************************************/
AsyncXMLGetRequest.prototype.queuePost = function(myUrl, myPostData, myObject, form_obj)
{

	if(form_obj != undefined && form_obj != '')
	{
		var form_data = form_obj;
		//window.alert(form_id);

		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);
			}
		}
		//window.alert("post " + myPostData);
	}


    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],myUrl);
        this.queueCount++;

		this.sendPostRequest(myUrl, 0, myPostData);
        }
    else if(this.inRequest == true)
        {

		for(i=1;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]);
		this.queueCount++;
       }

	if(myObject == 'float_div')
	{
		if(document.body.scrollHeight > 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 < document.body.scrollHeight)
				{
					var 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++;				

					if((total_height + 2048) >= document.body.scrollHeight)
					{
						this_add = (document.body.scrollHeight - total_height);
						clone.style.height = this_add+"px";
					}

					total_height += 2048;
				}
			}
		}
		else
		{
				document.getElementById('float_bg').style.height = document.body.scrollHeight + "px";
		}
		document.getElementById('float_el').style.height = document.body.scrollHeight + "px";
		document.getElementById('float_el').style.display = "block";
		//window.alert(document.getElementById('float_bg').style.zIndex + " " + document.getElementById('float_div').style.zIndex);
		var float_table = document.getElementById('float_table');
		float_table.style.height=document.body.clientHeight+"px";
		float_table.style.position = 'relative';
		float_table.style.top = document.body.scrollTop + "px";
	}	

    return;
}

/******************************************************************************
* 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
	{
		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);
		//window.alert('test');
		this.xmlRequest[qCount].open("POST", myUrl, true);
		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);
		//window.alert(postData);
		
        //this.xmlRequest[qCount].send("id=" + escape(idTextField.value));
	}

    return;
    }





/******************************************************************************
* 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)
	{
		if(myRequest.xmlRequest[0].responseText == null || myRequest.xmlRequest[0].responseText == '')
		{
	    	onRequestError(myRequest.objectQueue[0], ERR_RETURN_NULL, "Request returned null or no data!");
		}
		else
		{
			var 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);
			//document.getElementById('ajax_status').src='/ext/images/ajax_idle.gif';
		}
		else
		{
			//document.getElementById('ajax_status').src='/ext/images/ajax_loading.gif';
		    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)
{
	if(document.getElementById(requestObj) == undefined || requestObj == '')
	{
		//window.alert(requestObj);
	}
	else if(requestObj.indexOf('float') > -1 && requestURL.indexOf('pop_queue') > -1)
	{
		document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/adding_to_queue.gif' />";	
	}
	else if(requestObj.indexOf('float') > -1)
	{
		document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/new/loading.gif' />";	
	}
	else if(requestObj.indexOf('rating') > -1)
	{
		document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/new/loading.gif' />";		
	}
	else if(requestObj.indexOf('add') > -1)
	{
		document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/new/loading2.gif' />";		
	}
	else if(requestObj.indexOf('autosearch') > -1)
	{
		//document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/new/loading2.gif' />";		
	}
	else
	{
		document.getElementById(requestObj).innerHTML = "<img src='http://images.booksfree.com/images/new/processing.gif' />";
	}
}
/******************************************************************************
* 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)
{
	if(document.getElementById(requestObj) == undefined && requestObj !== '')
	{
		//window.alert(requestObj);
		newObj = document.createElement('div');
		document.body.appendChild(newObj);
		newObj.setAttribute('id',requestObj);
		//document.getElementById(
		//window.alert(requestObj.getAttribute('id'));
	}

	// parse html comments as script commands to evaluate
	var re_dml = new RegExp('<div style="display:none;" id="dml">(.*)</div id="dml">');

	var dml_objects = requestItem.match(re_dml);
	//retrieve DML objects

	// don't display this in any capacity to the client browser
	requestItem = requestItem.replace(re_dml, "");

	// only continue if there is return text
	if(requestItem !== '' && requestObj !== '')
	{
		var object = document.getElementById(requestObj);
			
		// If this is NOT a tip, show the element
		if(requestObj.indexOf('tip') == -1)
		{
			/*
			object.style.visibility = 'hidden';
			object.style.filter = "progid:DXImageTransform.Microsoft.Fade(Duration=1)";
			*/
			
			// set content into new element
			if(requestItem !== '') object.innerHTML = requestItem;
			
			/*

			if (object.filters)
			{
				object.filters[0].apply();
				if(object.style.height == 0) object.style.height = '0px';
				object.style.visibility = 'visible';
				object.filters[0].play();
			}
			else
			{
				object.style.visibility = 'visible';
				object.style.opacity = (0 / 100);
				object.style.MozOpacity = (0 / 100);
				object.style.KhtmlOpacity = (0 / 100);
				opacity(requestObj, 0, 100, 700); // Firefox and others
			}
			*/
			document.getElementById(requestObj).style.display = "block";
		}
		else if(requestObj !== '')
		{
			// set content into new element
			if(requestItem !== '') object.innerHTML = requestItem;
		}

		if(requestObj !== '') document.getElementById(requestObj).setAttribute('url', requestURL);
	}
	
	
	//if(requestObj == 'queue_end') window.alert(dml_objects);

	if(dml_objects != null)
	{
		eval(dml_objects[1]);
	}
	else
	{
		//window.alert('null');
	}



 }
/******************************************************************************
* 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)
    {
    }


//change the opacity for different browsers
function changeOpac(opacity, id) {
    var object = document.getElementById(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
}

function opacity(id, opacStart, opacEnd, millisec) {
    //speed for each frame
    var speed = Math.round(millisec / 100);
    var timer = 0;

    //determine the direction for the blending, if start and end are the same nothing happens
    if(opacStart > opacEnd) {
        for(i = opacStart; i >= opacEnd; i--) {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    } else if(opacStart < opacEnd) {
        for(i = opacStart; i <= opacEnd; i++)
            {
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    }
}