/*******************************************************************************
 * library: core.ajax.js
 * version: 1.0.0
 * package: Core Scripting
 * globals: none
 * objects: $AJAX, $Lightbox
 * dependencies: jquery-latest.js (1.2.6), core.js (1.0.0)
 * description: This library handles all AJAX queueing functions as well as 
 * request failures and error reporting. It also sets the default varaibles and
 * call back functions for the jQuery AJAX object.
 ******************************************************************************/

/*******************************************************************************
 * $AJAX: AJAX Process and Queue Functions
 * variables: queue.handles, queue.time, queue.go
 * functions: queue.add, queue.stop, queue.active, queue.count, queue.update,
 * queue.abort, failure, report
 ******************************************************************************/
$AJAX = {
	
	// AJAX Queueing Functions
	queue: {
	
		// Active process handles
		handles: [],
		
		// Time before auto-abort
		time: 0,
		
		// Go to URL upon completion
		go: 0,
		
		/**
		* add
		* 
		* Add a new AJAX request to the queue and updates the processes remaining count
		* @param    str		handleID		AJAX Method reference string
		* @return   nil
		*/
		add: function (handleID) {
			
			if (handleID) $AJAX.queue.handles[handleID] = true;
			pCount = $AJAX.queue.count(true);
		    pCountInactive = $AJAX.queue.count(false);
		    
			$("#ProcessRemain").html(
				Locale_Print(
    				"%s of %s Process Remaining...", pCount, 
    				(pCountInactive + pCount)
		    	)
			);
			
			$AJAX.queue.update();
		    
		},
		
		/**
		* stop
		* 
		* Removes a completed AJAX request from the queue
		* @param    str		handleID		AJAX Method reference string
		* @return   nil
		*/
		stop: function (handleID) {
			
			if (handleID) $AJAX.queue.handles[handleID] = false;
			$AJAX.queue.update();
    		
		},
		
		/**
		* active
		* 
		* Checks if there is any active AJAX requests in the queue
		* @param    nil
		* @return   bool
		*/
		active: function () {
			
			for (handleID in $AJAX.queue.handles)
				if ($AJAX.queue.handles[handleID])
					return true;
					
		    return false;
		    
		},
		
		/**
		* count
		* 
		* Returns the amount of active AJAX requests in the queue
		* @param    bool	status		Status to request (active or complete requests)
		* @return   int
		*/
		count: function (status) {
			
			var proCount = 0;
		    for (handleID in $AJAX.queue.handles)
		        if ($AJAX.queue.handles[handleID] == status)
		        	proCount++;
		        	
		    return proCount;
		    
		},
		
		/**
		* update
		* 
		* Updates the Process Waiting screen when an AJAX requests completes
		* @param    nil
		* @return   nil
		*/
		update: function () {
			
			var activeProcess = $AJAX.queue.count(true);
			
			if ($('#ProcessWaitingPerc').length) {
		        // Label
		        if ($("#ProcessRemain").length) {
		        	
		        	var pCount = $AJAX.queue.count(true);
		            $("#ProcessRemain").html(
		            	Locale_Print(
		            		"%s of %s Process Remaining...",
		            		pCount, ($AJAX.queue.count(false) + pCount)
		            	)
		            );
		            
				}
		        
		        // Progress
		        $("#ProcessWaitingPerc").width(
		            (activeProcess / (activeProcess + $AJAX.queue.count(false))) * 400
		        );

		        if (pCount == 0 && $('#Lightbox_Overlay').length) {
		            $('#Lightbox_Overlay').css("display", "none");
		            if ($AJAX.queue.go) document.location = $AJAX.queue.go;
		        }
		        
		    }
		    
		    if (activeProcess) {
		        
		        $("#ajaxProcessing")
		        	.css("display", "block")
		        	.find("div")
		        		.html(activeProcess);
		        
			} else {
				
				$("#ajaxProcessing")
					.css("display", "none");
				
			}
		    
		},
		
		/**
		* abort
		* 
		* Automatically abort all active AJAX requests in the queue
		* @param    nil
		* @return   nil
		*/
		abort: function () {
			
			$AJAX.queue.time = $AJAX.queue.time - 1;
		    if ($AJAX.queue.time <= 0) {
		        
		        // Abort
		        for (handleID in $AJAX.queue.handles)
		            if ($AJAX.queue.handles[handleID] == true)
		            	$AJAX.queue.stop(handleID);
		         
		         $('#ProcessAbort').html("Aborting all processes...");
		         setTimeout(function(){
		            $('#Lightbox_Overlay').css("display","none");
		            if ($AJAX.queue.go) document.location = $AJAX.queue.go;
		         }, 2000);
		         
		    } else {
		    	
		    	// Continue count down
		        if ($('#ProcessAbort').length) {
		            
		            $('#ProcessAbort').html(
		            	Locale_Print(
            				"All process will be automatically aborted in %s seconds...",
            				$AJAX.queue.time
            			)
		            );
		            setTimeout(function(){
		            	$AJAX.queue.abort()
		            }, 1000);
		        }
		    }
		    
		}
	},
	
	/**
	* failure
	* 
	* This function is called when an AJAX request returns a non 200 OK response. It
	* displays a system error screen allowing for users to email the developer to 
	* notify them of the failure.
	* @param    str		method		AJAX Method reference string
	* @return   nil
	*/
	failure: function (xhr) {

	    $Messages.clear();
	    $Lightbox.show('syserror', xhr.data);
	    
	},
	
	/**
	* report
	* 
	* Sends a system error report to the systems developers
	* @param	nil
	* @return	nil
	*/
	report: function () {
		
		// Prepare
	    $Messages.clear();
	    $('#dontSend').css("display","none");
	    $('#doSend').css("display","none");
	    $('#sending').css("display","block");
	    
	    // Process
	    $.ajax({
	    	url: baseDir+"ajax.php",
	    	data: {
	    		"method": "System_SendErrorReport",
	    	    "report": $('#sysErrorReport').val()
	    	},
	    	beforeSend: function () {
	    		
	    		// Override Default
	    		
			},
	    	success: function(data) {
	    		switch (data.result) {
	    		
	    			// Success
	            	case 1:
	            		$('#Lightbox_Frame').html(
            				'<div class="contentBlock"><h2>System Error</h2><div class="inner">'
	                        + '<p style="margin-top: 50px;" class="contentCenter">'
	                        + '<img src="'+styleDir+'images/ajaxSuccess.gif" alt="[SUCCESS]">'
	                        + ' Bug Report email sent successfully.<br><br><br>'
	                        + '<input type="button" class="button cancel" value="Close" onclick="$Lightbox.hide()"></p>'
	                    );
	                    setTimeout(function(){
	                    	$Lightbox.hide();
	                    }, 3000);
	            		break;
	            		
	            	// Failure
	            	default:
	            		alert ("Error :: Failed to send system error report. Please copy the bug report text and manually email the systems developer/administrator.");
	    		}
	    	},
	    	error: function () {
	    		
	    		alert ("Error :: Failed to send system error report. Please copy the bug report text and manually email the systems developer/administrator.");
	    		
			},
	    	complete: function () {
	    		
	    		// Override Default
	    		
			}
	    });
    		
	}
}

/*******************************************************************************
 * $Lightbox: LIGHTBOX RELATED FUNCTIONS
 * variables: none
 * functions: getDimension, position, create, show, hide
 ******************************************************************************/
$Lightbox = {
	
	/**
	 * getDimension
	 * 
	 * Helper function to get the innerWidth/Height based on browser specific method
	 * @param   str     axis        'width' || 'height'
	 * @param   str     default     Default return value should all else fail
	 */
	getDimension: function (axis, defaultDim) {
		
		// Determine how we are going to get the Width and Height values
	    if (!window.innerWidth) {
	        if (!document.documentElement.clientWidth) {
	            if (!document.body.clientWidth) return defaultDim;
	            // Provided by many browsers, including Internet Explorer.
	            if (axis == 'width') return document.body.clientWidth;
	            if (axis == 'height') return document.body.clientHeight;
	        } else {
	            // Provided by most DOM browsers, including Internet Explorer.
	            if (axis == 'width') return document.documentElement.clientWidth;
	            if (axis == 'height') return document.documentElement.clientHeight;
	        }
	    } else {
	        // Most Browsers but not IE
	        if (axis == 'width') return window.innerWidth;
	        if (axis == 'height') return window.innerHeight;
	    }
	    
	},
	
	/**
	* position
	* 
	* Repositions the lightbox frame when then document scrollbar is used to ensure
	* that the frame is always visible and centered.
	* @param    nil
	* @return   nil
	*/
	position: function () {
		
		if (!$('#Lightbox_Overlay').length) return true;
	    
	    if ($('#Lightbox_Overlay').css("position") == "absolute")
	    $('#Lightbox_Overlay').css(
	    	"top", (document.documentElement.scrollTop)
	        	? document.documentElement.scrollTop
	        	: document.body.scrollTop
	    );
	        
	},
	
	/**
	* create
	* 
	* Creates the lightbox frame if it doesn't already exist
	* @param    bool	clickClose		Determines if the frame closes when clicked
	* @return   nil
	*/
	create: function (clickClose, page) {
		
		if ($('#Lightbox_Overlay').length) return true;
	    
	    // Create Elements
	    var objBody = document.getElementsByTagName("body").item(0);
	    var objOverlay = document.createElement("div");
	        objOverlay.setAttribute('id','Lightbox_Overlay');
	        if (clickClose)
	            objOverlay.onclick = function () {$Lightbox.hide(); return false;}
	        objOverlay.style.display = 'none';
	        objOverlay.style.position = 'fixed';
	        if (MSIE && MSIE < 7) objOverlay.style.position = 'absolute';
	        objOverlay.style.top = '0';
	        objOverlay.style.left = '0';
	        objOverlay.style.zIndex = '90';
	        objOverlay.style.width = '100%';
	        objOverlay.style.height = '100%';
	    objBody.insertBefore(objOverlay, objBody.firstChild);
	    var objFrame = document.createElement("div");
	        objFrame.setAttribute('id','Lightbox_Frame');
	        objFrame.style.zIndex = '100';
	        objFrame.style.position = "absolute";
	        iWidth = $Lightbox.getDimension("width", 1024);
	        iHeight = $Lightbox.getDimension("height", 768);
	        if (page == "help") {
	        	objFrame.style.left = ((iWidth-700)/2)+"px";
	        	objFrame.style.top = ((iHeight-500)/2)+"px";
			} else {
	        	objFrame.style.left = ((iWidth-500)/2)+"px";
	        	objFrame.style.top = ((iHeight-400)/2)+"px";
			}
	        objOverlay.appendChild(objFrame);
	        
	},
	
	/**
	* show
	* 
	* Makes the lightbox frame visible and executes an AJAX request
	* @param    str		page		AJAX Request Location
	* @param	str		dataPool	AJAX POST Params
	* @return   nil
	*/
	show: function (page, dataPool) {
		
		// Make sure the elements exist
	    $Lightbox.create(false, page);
	    
	    if (page == "help") $("#Lightbox_Frame").addClass("help");
	    
	    // Get the Client Dimensions
	    var innerWidth = $Lightbox.getDimension('width', 1024);
	    var innerHeight = $Lightbox.getDimension('height', 768);
	    
	    // Display the Lightbox Frame
	    $("#Lightbox_Overlay")
	    	.css("display","block");
	    // If we are using IE, set the width and height values
	    // We also need to hide all <select> boxes in IE as they will "pop" through
	    if (MSIE) {
	        $("#Lightbox_Overlay").width(innerWidth);
	        $("#Lightbox_Overlay").height(innerHeight);
	        var SelectElements = document.getElementsByTagName("select");
	        for (var i = 0; i < SelectElements.length; i++) {
	            SelectElements[i].style.visibility = "hidden";
	        }
	        $("#Lightbox_Overlay").focus();
	    }
	    
	    // Display the Loading Frame
	    $('#Lightbox_Overlay')
	    	.css("left",0)
	    	.css("top",0)
	    	.width(innerWidth)
	    	.height(innerHeight);
	    $('#Lightbox_Frame').html(
	    	'<div class="contentBlock"><h2>Please Wait...</h2><div class="inner">'
	    	+ '<p class="first contentCenter">'
	    	+ '<img src="'+styleDir+'/images/ajaxLoading.gif" alt="...">'
	    	+ '</p></div></div>'
	    );
	    
	    // Page Request
	    if (page)
	    {
	        // Process
	        $.ajax({
	        	url: (page == "help") ? baseDir+"help/show.php" : baseDir+"ajax.php",
	        	data: dataPool,
	        	beforeSend: function () {
	        		
	        		// Override Default
	        		
				},
	        	success: function(data) {
	        	
	        		// Override Default

	        	},
	        	error: function (xhr) {
	        		
	        		if (page == "waiting" || page == "help") return;
	        		
	        		if (page != "syserror") $AJAX.failure(xhr);
	                else alert ("XML HTTPRequest Error: Code Failure.");
	                
				},
				complete: function (xhr) {
					
					$('#Lightbox_Frame').html(xhr.responseText);
					if (page == "waiting") {
						$AJAX.queue.update();
						$AJAX.queue.time = 31;
						$AJAX.queue.abort();
					}
					
				}
	        });
	    }
	},
	
	/**
	* hide
	* 
	* Makes the lightbox frame invisible
	* @param    nil
	* @return   nil
	*/
	hide: function () {
		
		// Hide the Lightbox and Config Frames
		$("#Lightbox_Overlay").css("display","none");
		// If we are using IE, un-hide all <select> boxes
		if (MSIE) {
		
			var SelectElements = document.getElementsByTagName("select");
			for (var i = 0; i < SelectElements.length; i++) {
			
			    SelectElements[i].style.visibility = "visible";
			    
			}
		}
	    
	}
}

/**
* Window On Scroll Event
* Bind the lightbox reposition function to the window onscroll event
*/
window.onscroll = function () {
	$Lightbox.position();
	return false;
}

/*******************************************************************************
 * CONFIGURE JQUERY AJAX REQUESTS
 ******************************************************************************/
$.ajaxSetup({
	type: "POST",
	cache: false,
	dataType: "json",
	data: {
		"JSON": true
	},
	beforeSend: function () {
		
		$System.cursor("wait");
		$AJAX.queue.add(this.url+"?"+this.data);
		
	},
	error: function (xhr, error, thrown) {

		$AJAX.failure(this);
		
	},
	complete: function(xhr) {
		
		// Pipe messages
		if (xhr.status != 404 && xhr.responseText) {

			data = eval("(" + xhr.responseText + ")")
			
			$(data.messages).each(function(){
			    $Messages.add($(this)[0], $(this)[1]);
			});
			
			// Do we need to redirect?
			if (data.redirect) $System.go(data.redirect);
		}
		
		// Restore all disabled buttons
		$Forms.enable();
		
		$System.cursor("default");
		$AJAX.queue.stop(this.url+"?"+this.data);
		
	}
});