/*******************************************************************************
 * library: core.js
 * version: 1.0.0
 * package: Core Scripting
 * globals: MSIE
 * objects: $Helper, $System, $Window, $Cookie, $Nav, $Messages, $Forms,
 			$Workspace
 * dependencies: jquery-latest.js (1.2.6)
 * description: This library contains commonly used functions relating to 
 * system, navigation, locale, window, cookies, messages, browsers and forms.
 ******************************************************************************/

/*******************************************************************************
 * BROWSER DETECTION AND VERSION
 ******************************************************************************/
var MSIE = (jQuery.browser.msie) ? jQuery.browser.version : 0;

/*******************************************************************************
 *  LOCALE STRING FUNCTIONS
 ******************************************************************************/
/**
 * Locale_Print
 *
 * Merges dynamic data with a Locale String. Accepts unlimited arguments.
 * @param   string  localeString    Passed Locale String
 * @return  string
 */
function Locale_Print(localeString)
{
    for (var i = 1; i <= arguments.length; i++)
    localeString = localeString.replace("%s", arguments[i]);
    return localeString;
}

/*******************************************************************************
 * $Helper: SHARED HELPER FUNCTIONS
 * variables: none
 * functions: maximiseContent, addBlockActions, makeSortable, toggleActivation,
 * keyCode, switchTab, restoreTab
 ******************************************************************************/
$Helper = {
	
	/**
	* maximiseContent
	* 
	* Maximises or restores a content block
	* @param    bool	maximise	Maximise or Restore?
	* @return   nil
	*/
	maximiseContent : function (maximise) {
	
		if (maximise) {
			
			// Change the navigation and content styles
			$("#menu").addClass("blockMaximise");
			$("#content").addClass("blockMaximise");
			
			// Update the click events and icon
			$(".maximiseIcon")
				.addClass("restore")
				.unbind("click")
				.bind("click", function(){
					
					$Helper.maximiseContent(false);
					
				});
			
		} else {
			
			// Change the navigation and content styles
			$("#menu").removeClass("blockMaximise");
			$("#content").removeClass("blockMaximise");
			
			// Update the click events and icon
			$(".maximiseIcon")
				.removeClass("restore")
				.unbind("click")
				.bind("click", function(){
					
					$Helper.maximiseContent(true);
					
				});
		}
	},
	
	/**
	* addBlockActions
	* 
	* Adds the collapse, restore and close icons to content blocks and applies
	* the appropriate events.
	* @param	str		blockClass	Block elements to apply to (jQuery String)
	* @param	bool	IEDrop		Allow collapse/restore events for IE7
	* @param    func	cbClose		Call back function on close event
	* @return   nil
	*/
	addBlockActions : function (blockClass, IEDrop, cbClose) {
		
		// Add a collapse/restore icon to all blocks header tag
		var html = "";
		var blockCount = $(blockClass).size();
		var blockSplit = (blockCount > 5) ? (blockCount / 2) - 1 : 0;
		$(blockClass)
			.each(function(i){
			
				// Add toggle buttons for all blocks to the customise frame
				var id = $(this).parent().attr("id");
				var checked = ($("#"+id).hasClass("wsHidden"))
					? "nocustomise"
					: 'customise';
				if ($(this).attr("title")) {
					
					var value = $(this).attr("title");
					var css = 'button buttonCustomise ';
					
				} else {
					
					var value = $(this).html();
					var css = 'button ';
				
				}
				html += $("#customiseBlocks").html()
					+ '<input type="button" class="button buttonCustomise '
					+ checked+'" id="block_'+id+'" value="'+value+'">';
				if (blockSplit && i == blockSplit) html += "<br>";
				
				/**
				* We don't want to show the expand and collapse functionlity
				* for IE7 as it doesn't refresh the page content correctly
				* when these events are triggered and causes blocks to 
				* overlap and in some instance disappear altogether.
				*/
				if (!IEDrop && MSIE && MSIE == 7) {
					
					$(this).html(
						'<span class="closeIcon">&nbsp;</span>'+
						$(this).html()
					);
						
				} else {
					
					$(this).html(
						'<span class="closeIcon">&nbsp;</span>'+
						'<span class="dropDownIcon">&nbsp;</span>'+
						$(this).html()
					);
						
				}
				
			});
			$("#customiseBlocks").html(html);
			
		// Add the onclick events to the toggle buttons
		$("#customiseBlocks .button")
			.click(function(){
				var id = $(this).attr("id").substring(6);
				if ($("#"+id).hasClass("wsHidden")) {
					$("#"+id)
						.removeClass("wsHidden")
						.fadeTo(300, 1);
					$(this)
						.removeClass("nocustomise")
						.addClass("customise");
				} else {
					$("#"+id)
						.fadeTo(300, 0.1, function() {
							$(this).addClass("wsHidden");
						});
					$(this)
						.removeClass("customise")
						.addClass("nocustomise");
				}
			});
			
		// Apply the onclick funciton to all collapse/restore icons
		$(".dropDownIcon")
			.click(function(){
			
				$Workspace.collapse(this);
				
			})
			.each(function(){
			
				// Attempt to restore previous collapsed settings
				if ($Cookie.get($(this).parent().parent().attr("id")+"_Collapsed", false)) {
					$Workspace.collapse(this, true, true, true);
				}
				
			});
			
		// Apply the onclick funciton to all close block icons
		$(".closeIcon")
			.click(function(){
			
				$(this).parent().parent()
					.fadeTo(300, 0.1, function() {
						$(this).addClass("wsHidden");
						cbClose();
					});
				$("#block_"+$(this).parent().parent().attr("id"))
					.removeClass("customise")
					.addClass("nocustomise");
				
			});
		
	},
	
	/**
	* makeSortable
	* 
	* Wrapper function for the jQuery sortable.
	* @param    str		frame		Sort area frame (jQuery String)
	* @param	str		items		Items to make sortable (jQuery String)
	* @param	str		connect		Elements to allow connection (jQuery String)
	* @param	func	cbStop		Call back function on stop event
	* @return   nil
	*/
	makeSortable : function(frame, items, connect, cbStop) {
	
		$(frame).sortable({
		
			items: items,
			connectWith: [connect],
    		scroll: true,
    		handle: "h2",
    		cursor: "move",
    		tolerance: "pointer",
    		containment: "document",
    		cancel: "span",
    		placeholder: 'contentPlaceholder',
    		forcePlaceholderSize: true,
    		helper: 'clone',
    		stop: function(event, ui) {
    		
    			// Drag Stop
    			setTimeout(function(){
    				cbStop();
				}, 100);
				
    		}
		});
		
	},
	
	/**
	* toggleActivation
	* 
	* Toggles the activation flag on or off for an action
	* @param    obj		e			Element Event
	* @param    int		varID		ID of action record to change
	* @param    var		action		Deactivate ("no"||0), Activate ("yes"||1)
	* @param    int		p			POST Value (Default: 4)
	* @return   nil
	*/
	toggleActivation: function (e, varID, action, p) {
		
		// Can this record be deleted
		if ($("#recordRow-"+varID).hasClass("recordDeleted")) return false;
		
		// Prepare
		$Messages.clear();
		var target = $System.eTarget(e);

		target.onclick = null;
		$(target)
			.removeClass()
			.addClass("status_loading")
			.unbind("click");

		if (!p) p = 4;
		if (action=="no"||action=="No") action = 1;
		if (action=="yes"||action=="Yes") action = 0;
		
		// Disable any "delete" buttons if they exist
		$('#Delete_'+varID).attr("disabled", "disabled");

		// Process
		$.ajax({
			data: {
			    "val": action,
			    "id": varID,
			    "p": p
			},
			success: function(data) {
				switch (data.result) {
					
					// Success
		        	case true:
		        	
		        		$(target)
		        			.removeClass()
		        			.addClass((action)
		        				? "status_yes"
		        				: "status_no")
		        			.bind("click", function(){
		        				$Helper.toggleActivation(e,varID,(action)
		        					? 0
		        					: 1,p);
		        				return false;
							});
							
						if (!action) $('#Delete_'+varID).removeAttr("disabled");
							
						switch (curDir) {
							
							case "/admin/stock":
								if (p == 4)
									$('#itemDelete_'+varID)
										.css("display",(action)
											? "none"
											: "block");
								if (p == 5)
									$('#varDelete_'+varID)
										.css("display",(action)
											? "none"
											: "block");
								break;
							
						}
		        		break;
		        		
		        	// Failure
		        	default:
		        		
		        		$(target)
		        			.removeClass()
		        			.addClass((action)
		        				? "status_no"
		        				: "status_yes")
		        			.bind("click", function(){
		        				$Helper.toggleActivation(e,varID,(action)
		        					? 1
		        					: 0,p);
		        				return false;
							});
				}
			}
		});
	},
	
	/**
	* keyCode
	* 
	* Checks a pressed key for a matched keyCode
	* @param	event	e		Element Event
	* @param    int		code	Key Code to check for
	* @return   bool
	*/
	keyCode: function (e, code) {
		
		var keyCode = (window.event) ? e.keyCode : e.which;
		return keyCode == code;
		
	},
	
	/**
	* switchTab
	*
	* Change the items displayed in the view all tables.
	* @param    event	e			Target Event
	* @param    str		rowClass	Show only rows with this class
	* @param    bool	noCookie	Determines if we store the change in a cookie
	* @return   nil
	*/
	switchTab: function (e, rowClass, noCookie) {
		
		if (!rowClass) rowClass = "";
		var target = (!noCookie)
			? $System.eTarget(e)
			: $("#"+e);
		var tabs = $(".tabFrame").find("div");
		var tabID = $(target).attr('id');

		// Set only the target as selected
		$(tabs).each(function(){$(this).removeClass("selected");})
		$(target).addClass("selected");
		
		var recordCount = 0;
		$("tr.tabRow").each(function(){
			if (rowClass == "" || $(this).hasClass(rowClass)) {
				$(this).attr("style", "");
				recordCount++;
			} else {
				$(this).attr("style", "display:none");
			}
		});
		
		// If there are no records, show the generic holder row
		if (recordCount) {
			$(".recordNone").addClass("recordNoneHidden");
		} else {
			$(".recordNone").removeClass("recordNoneHidden");
		}
		
		// Update the table footer (if one exists) with the record count for the
		// current view state.
		if ($("tfoot").length == 1) {
			
			$("tfoot tr td").html((recordCount == 1)
				? "1 Record Found."
				: recordCount+" Records Found."
			);
		}
		
		// Store the information in a cookie
		if (curDir.lastIndexOf("/") && !noCookie)
		{
			var cookieName = curDir.substring(curDir.lastIndexOf("/") + 1) + "_"
				+ curPageBase.substring(0, curPageBase.length - 4).replace(".","_");
			$Cookie.set(cookieName+"_tabID", tabID);
			$Cookie.set(cookieName+"_tabClass", rowClass);
		}
		
	},
	
	/**
	* restoreTab
	* 
	* Attempts to locate a cookie relating to any tab views for this page.
	*/
	restoreTab: function () {
	
		if ($(".recordNone").length) {
			var cookieName = curDir.substring(curDir.lastIndexOf("/") + 1) + "_"
				+ curPageBase.substring(0, curPageBase.length - 4).replace(".","_");
			
			$Helper.switchTab($Cookie.get(cookieName+"_tabID",'view0'),
							  $Cookie.get(cookieName+"_tabClass",''),true);
		}
		
	}
}

/*******************************************************************************
 * $System: SYSTEM AND DOCUMENT
 * variables: none
 * functions: eTarget, go, cursor
 ******************************************************************************/
$System = {
	
	/**
	* eTarget
	* 
	* Helper Function to get the target element of the fired event
	* @param	event	event	Event of the element to find target
	* @return	obj
	*/
	eTarget: function (event) {
		
		// Ensure the event exists
	    if (!event) event = window.event;

	    // Reference the Object that fired the event
	    return (event.srcElement) ? event.srcElement : event.target;
	    
	},
	
	/**
	* go
	* 
	* Wrapper function for the "document.location" call containing a bugfix for IE.
	* @param    str     page        Page name to navigate to (index.php)
	* @param    str     dir         Directory which contains the page (if applicable)
	* @return   nil
	*/
	go: function (page, dir) {
		
		if (!page) page = "index.php";
	    if (dir == "/") page = "../"+page;
	    document.location = page;
	    
	},
	
	/**
	* cursor
	* 
	* Changes the cursor type
	* @param    str		type		Cursor Type to use
	* @return   nil
	*/
	cursor: function (type) {
		
		document.getElementsByTagName('body')[0].style.cursor = type;
		
	}
	
}

/*******************************************************************************
 * $Window: POPUP WINDOWS
 * variables: none
 * functions: popup
 ******************************************************************************/
$Window = {
	
	/**
	* popup
	* 
	* Create a new popup window
	* @param    str     url         URL Location (document.location)
	* @param    enum    type        'console' || 'elastic' || ''
	* @param    int     width       Popup Window Width (400)
	* @param    int     height      Popup Window Height (300)
	* @param    str     winID       Window ID (newWindow)
	* @return   
	*/
	popup: function (url, type, width, height, winID) {
		
		// Param Valdation
	    if (!url) url = document.location;
	    if (!width) width = 400;
	    if (!height) height = 300;
	    if (!winID) winID = "newWindow";
	    
	    // Preset params
	    var params = '';
	    if (type == 'console') params += 'resizable,';
	    if (type == 'elastic') params += 'toolbar,menubar,scrollbars,resizable,location,';
	    params += 'width='+width+',height='+height;
	    
	    // Center the window
	    posX = ($Lightbox.getDimension('width', 800) / 2) - (width / 2);
	    posY = ($Lightbox.getDimension('height', 600) / 2) - (height / 2);
	    params += 'screenX='+posX+',left='+posX+',screenY='+posY+',top='+posY;
	    
	    // Create the window
	    var newWindow = window.open(url, winID, params);
	    if (window.focus) window.focus;
	    return false;
	    
	}
	
}

/*******************************************************************************
 * $Cookie: COOKIE MANAGEMENT
 * variables: none
 * functions: set, get, clear
 ******************************************************************************/
$Cookie = {
	
	/**
	* set
	* 
	* Creates a with the provided information
	* @param    str		name	Name of the cookie variable to create
	* @param	mixed	value	Value to store in the cookie
	* @param	int		days	Number of days to store the cookie
	* @return   nil
	*/
	set: function (name, value, days) {
		
		// Default to 1 year store time
		if (!days) days = 365;
		
		// Create the expires timestamp
	    var date = new Date();
	        date.setTime(date.getTime()+(days*24*60*60*1000));
	    var expires = "; expires="+date.toGMTString();
	    
	    // Store the cookie
	    document.cookie = name+"="+value+expires+"; path=/";
	    
	},
	
	/**
	* get
	* 
	* Reads the value of a saved cookie
	* @param    str		name		Name of the cookie variable to load
	* @param	mixed	dValue		Default value to return
	* @return   mixed
	*/
	get: function (name, dValue) {
	
		// Prepare the cookie information
	    var nameEQ = name + "=";
	    var ca = document.cookie.split(';');
	    
	    // Find the cookie value
	    for(var i = 0; i < ca.length; i++) {
	    
	        var c = ca[i];
	        while (c.charAt(0)==' ') c = c.substring(1,c.length);
	        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	        
	    }
	    
	    // Return the value
	    return dValue;
	    
	},
	
	/**
	* clear
	* 
	* Erases a stored cookie
	* @param    str		name		Name of the cookie variable to erase
	* @return   nil
	*/
	clear: function (name) {
		
		// Replace the stored cookie with a blank string
    	$Cookie.set(name,"",-1);
    	
	}
}

/*******************************************************************************
 * $Nav: NAVIGATION
 * variables: none
 * functions: toggle, go
 ******************************************************************************/
$Nav = {
	
	/**
	 * toggle
	 *
	 * Hide/Show Navigation Child Elements (Admin)
	 * @param	event	e		Element Event
	 * @return	nil
	 */
	toggle: function (e) {
		// Setup Elements
	    var target = $System.eTarget(e).parentNode;
	    while (target.tagName != "LI" && target.parentNode)
	    {
    		target = target.parentNode;
		}

	    if ($(target).hasClass("hideKids")) {
	    
	    	$(target).removeClass("hideKids");
	    	$(target).find("ul").hide().slideDown(75);
    		
		} else {
		
			$(target).addClass("hideKids");
			$(target).find("ul").slideUp(75);
			
		}
	},
	
	/**
	 * go
	 *
	 * This function is called when the user clicks on a navigation link while there
	 * are still process active. This will show a wait screen and attempt to finish 
	 * all processes. If failed, will automatically abort all process in 30 seconds.
	 * The function will then navigation to the specified URL.
	 * @param	str		url		Location to navigate to upon process completion
	 * @return	nil
	 */
	go: function (url) {
		
		if (!url) url = "";
    	$AJAX.queue.go = url;
    	$Lightbox.show('waiting', {
    		"method": "waiting"
    	});
    
	}
}

/*******************************************************************************
 * $Messages: MESSAGES
 * variables: none
 * functions: clear, add
 ******************************************************************************/
$Messages = {
	
	/**
	 * clear
	 *
	 * Clears any system messages displayed on the screen
	 * @param	nil
	 * @return	nil
	 */
	clear: function () {
	
		// Check if the parent DIV exists
	    if (!$('#messages').length) return false;

	    // Remove the parent DIV
	    $('#messages').remove();
	    
	},
	
	/**
	 * add
	 *
	 * Adds a system Message
	 * @param	str		type		Type of message to add
	 * @param	str		message		Message string to add
	 * @return	nil
	 */
	add: function (type, message) {
		
		if (!type) return false;
    
	    // If the parent message DIV doesn't exist, we need to create it
	    if (!$('#messages').length) {
	        
	        var parentDiv = document.createElement("div");
	            parentDiv.setAttribute('id','messages');
				$("#content *:first").before(parentDiv);
	    }
	    
	    // Make sure the UL exists
	    if (!$("#"+type).length) {
	    
	        var childUL = document.createElement("ul");
	            childUL.setAttribute('id',type);
	            $('#messages').append(childUL);
	            
	    }
	    
	    $("#"+type).html('<li><span class="messageIcon">&nbsp;</span>'+message+'</li>');
	    $("#"+type).css("display","block");
	    $('#messages').css("display","block");
	    
	}
}

/*******************************************************************************
 * $Forms: FORM RELATED FUNCTIONS
 * variables: none
 * functions: highlight, disable, enable, focus, submit, selectAll
 ******************************************************************************/
$Forms = {
	
	/**
	 * highlight
	 *
	 * Select the contents of a form element on focus
	 * @param	event	e		Element Event
	 * @return	nil
	 */
	highlight: function (e) {
		
		// Reference the Object that fired the event
	    var target = $System.eTarget(e);
	    if (target.tagName == "input") target.select();
	    
	},
	
	/**
	* disable
	* 
	* Disables all SUBMIT, RESET and BUTTON elements on a form page.
	* @param    nil
	* @return   nil
	*/
	disable: function () {
		
		$(".button.disable").each(function(){
			
			if (!$(this).attr("disabled") !== undefined)
	    		$(this)
	    			.addClass("_formDisabled")
	    			.attr("disabled","disabled");
			
		});
	    
	},
	
	/**
	* enable
	* 
	* Enables all SUBMIT, RESET and BUTTON elements on a form page.
	* @param    nil
	* @return   nil
	*/
	enable: function () {
		
		$(".button.disable._formDisabled").each(function(){
			
	    	$(this)
	    		.removeClass("_formDisabled")
	    		.removeAttr("disabled");
			
		});
		
		$(".submit.process").removeClass("process");
	    
	},
	
	/**
	* focus
	* 
	* Puts the cursor focus on a target element.
	* @param    str     elem	Element ID to focus on
	* @return   nil
	*/
	focus: function (elem) {

		// Does the element exist?
	    if (!elem || !$("#"+elem).length) return false;
	    
	    // Focus
	    $("#"+elem).focus();
	    $("#"+elem).select();
	    
	},
	
	/**
	* submit
	* 
	* Adjusts the form variables and submits the form by an onclick method.
	* @param    str     name    Name of the form to submit
	* @param    int     pID     $('p').value
	* @param    int     rID		$('recordID').value
	* @return   nil
	*/
	submit: function (name, pID, rID) {
		
		// Configure Submit
	    $('#p').val(pID);
	    $('#recordID').val(rID);
	    
	    // Disable form buttons
	    $Forms.disable();
	    
	    // Submit Form
	    $("#"+name).submit();
	    
	},
	
	/**
	* selectAll
	* 
	* Select all elements in a select box
	* @param    obj		elem		The control to use
	* @param    bool	method		Do we select or deselect all
	* @return   nil
	*/
	selectAll: function (elem, method) {
		
		if (!$("#"+elem)) return false;
		
		$("#"+elem)
			.children("option")
				.each(function(){
				
					$(this).attr("selected", (method) ? "selected" : "");
					
				});
				
	},
	
	/**
	* checkAll
	* 
	* Checks/Unchecks all checkboxes in a parent element
	* @param	event	e		Element Event
	* @param    obj		elem		The parent element to check all inside
	* @return   nil
	*/
	checkAll: function (e, elem) {
		
		if (!$("#"+elem)) return false;
		
		$("#"+elem+" input[type=checkbox]")
			.each(function(){
			
				if ($(e).attr("checked")) {
					$(this).attr("checked", "checked");
				} else {
					$(this).removeAttr("checked");
				}
				
			});
				
	}
}

/*******************************************************************************
 * $Workspace: WORKSPACE RELATED FUNCTIONS
 * variables: none
 * functions: collapse, limitDays, update, customise
 ******************************************************************************/
$Workspace = {
	
	/**
	* collapse
	* 
	* Collapse and Restore a workspace content block
	* @param    obj		e			Element Event
	* @param	bool	force		Instant change without animation?
	* @param	bool	state		TRUE=>SlideUp, FALSE=>SlideDown
	* @param	bool	noCookie	Determines if the change is saved to a cookie
	* @return   nil
	*/
	collapse: function (e, force, state, noCookie) {
		
		var hasDrop = $(e).hasClass("dropDownIcon");
		var hasDropReal = hasDrop;
		if (force) hasDrop = state;
		
		// Change the classNames
		$(e)
			.addClass((hasDrop) ? "dropUpIcon" : "dropDownIcon")
			.removeClass((hasDrop) ? "dropDownIcon" : "dropUpIcon");
		
		// Collapse the block
		if (force) {
			$(e).parent().siblings()
				.attr("style",(hasDrop)
					? "display:none"
					: "display:block"
				);
		} else {
			(hasDrop)
				? $(e).parent().siblings().slideUp(300)
				: $(e).parent().siblings().slideDown(300);
		}
		
		// Save state to cookie
		if (!noCookie) {
			(!hasDropReal)
				? $Cookie.clear($(e).parent().parent().attr("id")+"_Collapsed")
				: $Cookie.set($(e).parent().parent().attr("id")+"_Collapsed", true);
		}
		
	},
	
	/**
	* limitDays
	* 
	* Hide and Shows table rows based on the number of days selected. This feature 
	* is used in the workspace for multiple blocks.
	* @param    str		table		ID of the Table to manipulate
	* @param	int		days		Number of days to limit by
	* @param	bool	noCookie	Determines if we store the change to a cookie
	* @return   nil
	*/
	limitDays: function (table, days, noCookie) {
		
		if (!days) days = 7;
		days = parseInt(days);
		var numFound = 0;
		
		if (!noCookie) {
		
			// Store the change in a cookie
			$Cookie.set(table+"_Days", days);
			
		} else {
		
			// Update the textbox value
			$("#"+table+"_DaysNum").val(days);
			
		}

		// For each table row...
		$("#"+table+" tbody tr")
			.each(function(index){
			
				// do we have a valid day count?
				if ($("#"+table+"_Days_"+index)) {
				
					// if it isn't the default "no records" row...
					if (!$(this).hasClass("recordNone")) {
					
						// if the record is within the day limit
						if ($("#"+table+"_Days_"+index).val() <= days) {
						
							// Make it visible
							$(this).removeClass("trHidden");
							numFound++;
							
						} else {
						
							// Make it invisible
							$(this).addClass("trHidden");
							
						}
					}
				}
			});

		if (!numFound) {
		
			// Show the default "no records" row
			$("#"+table+" .recordNone").addClass("recordNoneShown");
			
		} else {
		
			// Hide the default "no records" row
			$("#"+table+" .recordNone").removeClass("recordNoneShown");
			
		}
		
		// Adjust the footer text
		$("#"+table+" tfoot tr td:first").html((numFound == 1)
			? "1 Record Found."
			: numFound+" Records Found."
		);
		
	},
	
	/**
	* update
	* 
	* Stores the current workspaceBlock layout to the users workspace database
	* @param    nil
	* @return   nil
	*/
	update: function () {
		
		var left = '';
		var right = '';
		
		// Get all blocks in the left column
		$("#wsContentLeft .workspaceBlock")
			.each(function(){
			
				left += ($(this).hasClass("wsHidden"))
					? $(this).attr("id")+"|h,"
					: $(this).attr("id")+",";
					
			});
			
		// Get all blocks in the right column
		$("#wsContentRight .workspaceBlock")
			.each(function(){
			
				right += ($(this).hasClass("wsHidden"))
					? $(this).attr("id")+"|h,"
					: $(this).attr("id")+",";
					
			});
			
		// Save the data to the database
		$.ajax({
			url: baseDir+"home.php",
			data: {
			    "left": left,
			    "right": right
			},
			success: function(data) {
				
				// No Action Required
				
			}
		});
    		
	},
	
	/**
	* customise
	* 
	* Hide or Show the customise screen.
	* @param    nil
	* @return   nil
	*/
	customise: function () {
		
		$Messages.clear();
		if ($("#customise").hasClass("wsHidden")) {
			
			$("#customise")
				.slideDown(300, function(){
					$(this).removeClass("wsHidden");
				});
				
		} else {
			
			$("#customise")
				.slideUp(300, function(){
					$(this).addClass("wsHidden");
				});
				
		}
		
	}
}