/*
	This library requires jQuery 1.6.2+
	
	Written By: Derek Carr
	Under: Xenium Systems - Web-based framework
	NOTE: A work in progress.
	Version: 0.4.6.d
*/


var x = new Object();

// x > array
x.array = new Object();
x.array.indexOf = function (stack, needle) {
	for (var i=0; i < stack.length; i++) { 
		if (stack[i] == needle) { return i; }
	}
	return -1;
};

x.array.search = function (stack, needle) {
	var length = stack.length;
	for (var i=0; i < length; i++) {
		var TYPE = typeof stack[i];
		if (typeof stack[i] == 'object' || typeof stack[i] == 'array') {
			if (x.array.search (stack[i], needle)) { return true; break; }
		} else {
			if (needle) { if (x.array.indexOf (stack[i], needle) != -1) { return true; break; } }
			else { if (stack[j] == stack) { return true; break; } }
		}
	}
	return false;
};

// x > sys
x.sys = new Object();
x.sys.empty = function (suspect) { return (suspect === null || suspect == '') ? true : false; }

x.sys.inBytes = function (str) {
	var total = 0;
	var LONG2_256 = 8;
	var LN2x8 = Math.LN2 * LONG2_256;
	for (var i=0; i < str.length; i++) {
		total += Math.ceil (Math.log (str[i].charCodeAt()) / LN2x8);
	}
	return total;
};
/*
	chkVar - Variable to check
	statement - An array of operators to check for true or false
	final - The final result. 
		0 - False
		1 - True
		2 - None are true
		3 - Any are true
		4 - None are false
		5 - Any are false
	
	EX:
		var Foo = true;
		exif (Foo, ['==true', '==false', '!=10'], 3);
		
	Checks to see if 'Foo' is true, false, or does not equal 10.
	The final result is based on a 0-5 number system. 0 - false,
	1 - true, 2 - none are true, 3 - any are true, 4 - none are false,
	5 - any are false. In this case we're checking 3, if any are true.
	Therefore this statement will return 'true'. 
	
	This function is patchworked and will require some rewriting.
	
	Multiple stages need to be implemented.
		- Keep 'expecting'
		- Add binary representation to allow for exact sequencing for logical checks
		- Add a third dimension to match the expecting results against the binary rep.
		
		
		EXAMPLE 1:
			var Foo = 10;				
			Statement = ['==10', '!=30', '<11']
			Expecting: 3
			CheckAgainst: 101
			
			Assign Foo the value 10. Check if 10 equals 10, is not 30 and less than 11.
			We're expecting 3 (Any are true).
			Checking against the logic: TRUE, FALSE, TRUE
			The statement will return TRUE.
			
		EXAMPLE 2:
			var Foo = 11;
			Statement = ['==10', '!=30', '<11']
			Expecting = 3
			CheckAgainst: 101
			
			Assign Foo the value 10. Check if 10 equals 10, is not 30 and less than 11.
			We're expecting 3 (Any are true).
			Checking against the logic: TRUE, FALSE, TRUE
			The statement will return FALSE. 11 is NOT less than 11.
		
		
*/
x.sys.exif = function (chkVar, statement, expecting) {
	var tf = null;
	var _ret = String();
	if (typeof statement == 'object') {
		for (var i in statement) { eval (chkVar + statement[i]) == true ? _ret += '1' : _ret += '0'; }
		expecting = expecting.toString();
		switch (expecting) {
			case '2': _ret.search('1') == -1 ? _ret=1 : _ret=0; break;
			case '3': _ret.search('1') != -1 ? _ret=1 : _ret=0; break;
			case '4': _ret.search('0') == -1 ? _ret=1 : _ret=0; break;
			case '5': _ret.search('0') != -1 ? _ret=1 : _ret=0; break;
			default: _ret == expecting ? _ret = 1 : _ret = 0;
		}
	} else { throw "Invalid use of exif(). Arg2 must be an array."; }
	return _ret;
};
x.sys.parseFlags = function (flags, modifier) {
	if (flags !== undefined) {
		flags = flags.split ('-');
		for (var i=0; i<flags.length; i++) {
			if (flags[i] === undefined || flags[i] == null || flags[i] == '') {
				flags.splice (i, 1);
			}
			flags[i] = $.trim (flags[i]);
		}
		if (modifier !== undefined && modifier != null) {
			if (modifier == 'bin_rep') {
				var bin_rep = 1;
				for (var a=0; a<flags.length; a++) {
					for (var b=0; b<flags[a].split ('|').length; b++) {
						bin_rep *= 2;
					}
				}
				return bin_rep;
			}
		}
	}
	return flags;
};



// x > sys > mem
x.sys.memory = new Object();
x.sys.memory.memCustomStructures = new Array();
x.sys.memory.STRUCTURES = new Array();
x.sys.memory.replicateAllStructures = function () {
	return x.sys.memory.STRUCTURES;
};
x.sys.memory.createStructure = function (structName, _Struct, flag) {
	flag < 0 ? flag = 0 : 0;
	(flag === undefined || flag > 7) ? flag = 7 : 0;
	_Struct = { name: structName, struct: _Struct, perm: flag };
	x.sys.memory.STRUCTURES.push (_Struct);
	return _Struct;
};
x.sys.memory.getStructure = function (hStruct, _getIndex) {
	var hStructures = x.sys.memory.STRUCTURES;
	for (var current in hStructures) {
		if (hStructures[current].name == hStruct) {
			if (x.sys.exif (hStructures[current].perm, ['==1', '==3', '==5', '==7'], 3)) {
				if (_getIndex !== undefined && _getIndex == true) { return current; }
				else { return hStructures[current].struct; }
			} else { throw "READ Permissions are not set for: " + hStructures.name; }
		}
	}
};
x.sys.memory.getStructureIndex = function (hStruct) {
	return x.sys.memory.getStructure (hStruct, true);
};
x.sys.memory.deleteStructure = function (hStruct) {
	for (var i=0; i < x.sys.memory.STRUCTURES.length; i++) {
		if (x.sys.memory.STRUCTURES[i].name == hStruct.name) {
			if (x.sys.exif (x.sys.memory.STRUCTURES[i].perm, ['==4', '==6', '==7'], 3)) {
				x.sys.memory.STRUCTURES.splice (i, 1);
				return i;
			} else { throw "EXECUTE Permissions are not set for: " + hStruct.name; }
		}
	} return 0;
};

// x > ui
x.ui = new Object();
x.sys.memory.createStructure ('widgets.slideOptions', {
	selectors: {
		self: '.SlideOptionsContainer',
		optionsContainer: '.SlideOptionsContainer .OptionsContainer',
		optionsHeader: '.SlideOptionsContainer .OptionsContainer .OptionsHeader',
		optionsContent: '.SlideOptionsContainer .OptionsContainer .OptionsContent',
		extendedContainer: '.SlideOptionContainer .ExtendedContainer',
		extendedHeader: '.SlideOptionsContainer .ExtendedContainer .ExtendedHeader',
		extendedContent: '.SlideOptionsContainer .ExtendedContainer .ExtendedContent',
		defaultState: 'ui-state-default'
	}
}, 7);




/* 
	-------------------------  ATTENTION  -------------------------
	All of the scripts below are considered snippets and still need
	to be converted over to the new 'x' namespace. Keep in mind
	that most of them are unversioned and may require tweaking
	in order to work properly. The final revisions will be re-written
	to perfection.
	------------------------------------------------------------------
*/

var Engine = {
	Current: null,
	Namespace: null,
	Collection: [],
	
	SetEngine: function (SetAs) { this.Current = SetAs; },
	SetNamespace: function (SetAs) { this.Namespace = SetAs; },
	
	FlushEngine: function () { this.Current = null; },
	FlushNamespace: function () { this.Namespace = null; },
	Flush: function () { this.FlushEngine(); this.FlushNamespace(); },
	
	FetchEngine: function () { return this.Current; },
	FetchNamespace: function () { return this.Namespace; },
	Fetch: function () { return [this.Current, this.Namespace]; },
	
	Assoc: function (Engine) { this.Collection.push (Engine); },
	Unassoc: function  (Engine, Instance) { 
		if (Instance === undefined) { var Instance = 1; }
		for (var i=0; i<this.Collection.length; i++) {
			if (this.Collection[i] == Engine) {
				this.Collection.splice (i, Instance);
				return 1;
			}
		}
		return 0;
	}
};

/* Start: Global Variables */
var XMLDefinitionsMap = [];
var XMLInitMap = [];
/* End: Global Variables */

var System = {
	Validate: {
		//Split arguments such as:  instance|object|etc
		//Needed for future implementations
		XMLSplitArguments: function (Str) {
			return Str.split ('|');
		},
		
		//Add an array of elements into the XMLDefinitionMap
		XMLAddDefinitionsMap: function (Arr) {
			for (var i=0; i < Arr.length; i++) {
				XMLDefinitionsMap.push (Arr[i]);
			}
		},
		
		//Add an array of elements into the XMLInitMap
		XMLAddInitMap: function (Arr) {
			for (var i=0; i < Arr.length; i++) {
				XMLInitMap.push (Arr[i]);
			}
		},
		
		//Get the current definition map
		XMLGetDefinitionsMap: function () { return XMLDefinitionsMap; },

		//Validate an XML configuration file
		XMLConfig: function (ConfigURL, Instance) {
			//If Instance isn't defined, use 'default'
			if (Instance === undefined) {  var Instance = 'default'; }
			
			//AJAX the config schema
			$.ajax ({
				url: ConfigURL,
				type: 'GET',
				async: false,
				success: function (data) {
					//Find the specified instance
					$(data).find (Instance).each (function () {
						//Find the required element
						$(this).find ('required').each (function () {
							//Split the arguments into an array
							var Definitions = System.Validate.XMLSplitArguments ($(this).text());
							//Add the values to the XML definitions map
							System.Validate.XMLAddDefinitionsMap (Definitions);
						});
						//Find the init element
						$(this).find ('init').each (function () {
							//Split the arguments into an array
							var Definitions = System.Validate.XMLSplitArguments ($(this).text());
							//Add the values to the XML init map
							System.Validate.XMLAddInitMap (Definitions);
						});
					});
				
				},
				error: function (xhr, stat, err) {
					if (xhr.status == 404) { alert ('404 - Call to incorrect path: ' + this.url); }
				}
			});
		}
	},
	//All of the required definitions
	Validate_Def_Map: [],
	
	ValidateXMLConfig: function (ConfigURL) {
		//Load in the config Schema
		$.ajax ({
			url: 'schema/XMLConfig.xml',
			type: 'GET',
			success: function (data) {
				//Find the default config schema
				$(data).find ('default').each (function () {
					//Map out all of the definitions
					$(this).children().each (function () {
						
					});
				});
			},
			error: function (xhr, stat, err) {
				if (xhr.status == 404) {
					alert ('This path is incorrect: ' + this.url);
				} 
			}
		});
	}
};

//Validate the default XMLConfig schema
System.Validate.XMLConfig ('schema/XMLConfig.xml');


// v1.3 Alpha
//Popup Window Class
var QuickBox = {
	//v1.0 Alpha
	//Check to see if a variable is empty.
	//RET: true (if empty) :: false (if not empty)
	isEmpty: function(v) { v == undefined || v == null || v.toString() == "" ? v=true : v=false; return v; },
	//v1.3 Alpha
	//Window Handle
	_HWIND: Array(),
	//v1.3 Alpha
	//[50]-Build Popup Container
	//REQ: None
	//Breadcrumb function
	WindowBuildFramework: function() {
		var _frame = {
			f_main: $(document.createElement('div')),
			f_close: $(document.createElement('div')),
			f_header: $(document.createElement('div')),
			f_headerLabel: $(document.createElement('div')),
			f_content: $(document.createElement('div')),
			f_contentContainer: $(document.createElement('div')),
			f_modal: $(document.createElement('div'))
		};
		return _frame;
	},
	//v1.3 Alpha
	//[49]-Create a named window frame
	//REQ: (wName)
	//Breadcrumb function
	WindowCreateNamed: function(wName) {
		var _frame = this.WindowBuildFramework();
		_frame.f_main.attr('id', 'qBox-Container:' + wName);
		_frame.f_close.attr('id', 'qBox-Close:' + wName);
		_frame.f_header.attr('id', 'qBox-Header:' + wName);
		_frame.f_headerLabel.attr('id', 'qBox-HeaderLabel:' + wName);
		_frame.f_content.attr('id', 'qBox-Content:' + wName);
		_frame.f_contentContainer.attr('id', 'qBox-ContentContainer:' + wName);
		_frame.f_modal.attr('id', 'qBox-Modal:' + wName);
		return _frame;
	},
	//v1.3 Alpha
	//[48]-Set Styles For Framework
	//REQ: (wName)
	//Breadcrumb function
	WindowSetStyle: function(wName) {
		var _frame = this.WindowCreateNamed (wName);
		_frame.f_main.attr('class', 'qBox-Container');
		_frame.f_close.attr('class', 'qBox-Close');
		_frame.f_header.attr('class', 'qBox-Header');
		_frame.f_headerLabel.attr('class', 'qBox-Header-Label');
		_frame.f_content.attr('class', 'qBox-Content');
		_frame.f_contentContainer.attr('class', 'qBox-ContentContainer');
		_frame.f_modal.attr('class', 'qBox-Modal');
		return _frame;
	},
	//v1.3 Alpha
	//[47]-Build and append all elements of the window
	//REQ: (wName)
	//OPT: (custom)
	//Breadcrumb function
	WindowBuild: function(wName,custom) {
		//Breadcrumb function
		//WindowBuildFramework -> WindowCreateNamed -> WindowSetStyle
		var _frame = this.WindowSetStyle (wName);
		//Append container to the body
		_frame.f_main.appendTo ('body');
		//Append the close button to the container
		_frame.f_close.appendTo (_frame.f_main);
		//Append the header to the container
		_frame.f_header.appendTo (_frame.f_main);
		//Append the header label to the header
		_frame.f_headerLabel.appendTo (_frame.f_header);
		//Append the content to the container
		_frame.f_content.appendTo (_frame.f_main);
		//Append the content container to the content
		_frame.f_contentContainer.appendTo (_frame.f_content);
		//Create the window handle by name
		_frame.handle = wName;
		//Push window handle into the global scope of windows
		this._HWIND.push (_frame);
		//Return the handle for the window
		return _frame;
	},
	//v1.3 Alpha
	//[46]-Return the handle of a window by name
	//REQ: (wName)
	WindowGetByName: function (wName,_returnIndex) {
		for (var i=this._HWIND.length-1; i >= 0; i--) {
			if (this._HWIND[i].f_main.attr('id') == "qBox-Container:" + wName) {
				if (_returnIndex == true || _returnIndex == 1) { return i; }
				else { return this._HWIND[i]; }
			}
		}
		return 0;
	},
	//v1.3 Alpha
	//[45]-Set the title of a window
	//REQ: (wName) OR (Window.handle)
	//OPT: (title)
	WindowSetTitle: function (wName,title) {
		var handle = this.WindowGetByName (wName);
		if (handle != 0 && handle != undefined && handle != null) {
			if (title == undefined || title == null) { title = ""; }
			handle.f_headerLabel.html (title);
			return 1;
		} else { return 0; }
	},
	//v1.3 Alpha
	//[44]-Set the content of a window
	//REQ: (wName) OR (Window.handle)
	WindowSetContent: function (wName,content) {
		var handle = this.WindowGetByName (wName);
		if (handle != 0 && handle != undefined && handle != null) {
			if (content == undefined || content == null) { content = ""; }
			handle.f_contentContainer.html (content);
			return 1;
		} else { return 0; }
	},
	//v1.3 Alpha
	//[43]-Build the default configuration for a modal dialog
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowBuildModalConfig: function (wName,custom) {
		var wIndex = this.WindowGetByName (wName, true);
		//If a custom config is not defined, create one
		if (custom == undefined) { var custom = new Object; }
		//Set all default values if they're not set
		this.isEmpty (custom.width) ? custom.width=parseInt ($(window).width()) : 0;
		this.isEmpty (custom.height) ? custom.height=parseInt ($(window).height()) : 0;
		this.isEmpty (custom.position) ? custom.position='absolute' : 0;
		this.isEmpty (custom.top) ? custom.top='0px' : 0;
		this.isEmpty (custom.left) ? custom.left='0px' : 0;
		this.isEmpty (custom.backgroundColor) ? custom.backgroundColor="#FFFFFF" : 0;
		this.isEmpty (custom.duration) ? custom.duration=1 : 0;
		this.isEmpty (custom.modalClickClose) ? custom.modalClickClose=true : 0;
		//Set the CSS values
		this._HWIND[wIndex].f_modal.css({
			'display': 'none',
			'width': custom.width,
			'height': custom.height,
			'position': custom.position,
			'top': custom.top,
			'left': custom.left,
			'background-color': custom.backgroundColor,
			'z-index': '10000000'
		});
	},
	//v1.3 Alpha
	//[42]-Show the modal
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowModalShow: function (wName,custom) {
		if (custom == undefined) { var custom = new Object; }
		this.isEmpty (custom.opacity) ? custom.opacity=1 : 0;
		this.isEmpty (custom.duration) ? custom.duration=500 : 0;
		
		//Return the index of the specified window
		var wIndex = this.WindowGetByName (wName, true);
		if (this._HWIND[wIndex] != undefined) {
			$(this._HWIND[wIndex].f_modal).appendTo('body').fadeTo(custom.duration, custom.opacity);
			return 1;
		} else {
			return 0;
		}
	},
	//v1.3 Alpha
	//[41]-Hide the modal
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowModalHide: function (wName,custom) {
		if (custom == undefined) { var custom = new Object; }
		this.isEmpty (custom.duration) ? custom.duration=1 : 0;
		
		//Return the index of the specified window
		var wIndex = this.WindowGetByName (wName, true);
		if (this._HWIND[wIndex] != undefined) {
			$(this._HWIND[wIndex].f_modal).fadeTo(custom.duration, 0, function() { QuickBox._HWIND[wIndex].f_modal.remove(); });
			return 1;
		} else { return 0; }
	},
	//v1.3 Alpha
	//[42]-Build the default configuration for the window
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowBuildConfig: function (wName,custom) {
		var wIndex = this.WindowGetByName (wName, true);
		var handle = this._HWIND[wIndex].f_main;
		
		//If a custom config is not defined, create one
		if (custom == undefined) { var custom = new Object; }
		//Set all default values if they're not set
		this.isEmpty (custom.width) ? 0 : handle.css({ width: custom.width });
		this.isEmpty (custom.height) ? 0 : handle.css({ height: custom.height });
		this.isEmpty (custom.top) ? 0 : handle.css({ top: custom.top });
		this.isEmpty (custom.left) ? 0 : handle.css({ left: custom.left });
		if (custom.visible == true) { handle.css({ visibility: 'visible' }) }
		else { handle.css({ visibility: 'hidden' }) }
		
		this.isEmpty (custom.isModal) ? custom.isModal=false : 0;
		
		//Create the 'x' to close the window
		this._HWIND[wIndex].f_close.html ('x').click( function() {
			QuickBox.WindowClose (wName, custom);
		});
	},
	//v1.3 Alpha
	//[41]-Create a popup window
	//OPT: (custom.name) (custom.title) (custom.content) (custom.modal[true|false])
	WindowCreate: function (custom) {
		if (custom == undefined || custom == null) { var custom = new Object; }
		//If a name is not specified, generate a random string as the window name
		if (this.isEmpty (custom.name) == true) {
			custom.name = "";
			var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
			var string_length = 16;
			for (var i=0; i<string_length; i++) {
				var rnum = Math.floor (Math.random() * chars.length);
				custom.name += chars.substring (rnum,rnum+1);
			}
		}
		//If content and title are not set, then leave blank
		this.isEmpty (custom.title) ? custom.title="" : 0;
		this.isEmpty (custom.content) ? custom.content="" : 0;
		//Check if the popup is to start off visible
		this.isEmpty (custom.visible) ? custom.visible=false : 0;
		
		//Create the initial window and framework
		var wHandle = this.WindowBuild (custom.name);
		//If modal is enabled, then build/show it
		this.WindowBuildModalConfig (wHandle.handle, custom.modal);
		if (custom.isModal == true && custom.visible == true) { this.WindowModalShow(wHandle, custom.modal); }
		
		//Set the values for title and content
		this.WindowSetTitle (wHandle.handle, custom.title);
		this.WindowSetContent (wHandle.handle, custom.content);
		//Build the window configurations
		this.WindowBuildConfig (wHandle.handle, custom);
		//Return the handle for the window
		return wHandle;
	},
	//v1.3 Alpha
	//[40]-Close the window
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowClose: function (wName,custom) {
		if (custom == undefined) { var custom = new Object; }
		var wIndex = this.WindowGetByName (wName, true);
		var handle = this._HWIND[wIndex].f_main;
		
		handle.hide();
		this.WindowModalHide (wName, custom.modal);
	},
	//v1.3 Alpha
	//[39]-Show the window
	//REQ: (wName) OR (Window.handle)
	//OPT: (custom)
	WindowShow: function (wName,custom) {
		if (custom == undefined) { var custom = new Object; }
		var wIndex = this.WindowGetByName (wName, true);
		var handle = this._HWIND[wIndex].f_main;

		handle.show();
		this.WindowModalShow(wName, custom);
	}
};

function fold_er_class() {
	var folder_list = Array();
	//DEBUG: print out a debug report in the debug area.
	function DEBUG(Out) {
		$('<div>' + Out + '</div>').appendTo('div#debug');
	}
	this.DEBUG = DEBUG;

	function define_default(VAR, Default) {
		VAR == null || VAR == undefined || VAR == "" ? VAR = Default : 0;
		return VAR;
	}
	//Bind a folder to an element
	function folder_bind(handle, elementId) {
		if (folder_isArray(handle)) {
			for (fCur in handle) {
				handle[fCur].BoundTo = elementId;
			}
		} else if (folder_isObject(handle)) {
			handle.BoundTo = elementId;
		} else {
			throw "folder_bind(handle,elementId) The specified variable is not an array or object.";
		}
	}
	//Assign a folder to the scope
	function folder_scope(handle, _bool) {
		handle.Scope = _bool;
	}
	//Assign a folder to a group
	function folder_group(handle, groupName) {
		if (folder_isArray(handle)) {
			for (fCur in handle) {
				handle[fCur].Group = groupName;
			}
		} else if (folder_isObject(handle)) {
			handle.Group = groupName;
		} else {
			throw "fold_er.group( handle, groupName ) The specified variable is not an array or object."
		}
	}
	//Parse Serial Number for the ID
	function pSerial(Serial) {
		Serial = Serial.split(':');
		return Serial[3];
	}
	//Create a new folder
	//DEPRECIATED: folder_createEx()
	function folder_create(Content, Class, Ext) {
		Content = define_default(Content, "");
		Class = define_default(Class, "folder_row");
		Ext = define_default(Ext, 'r');
		var _ret = {
			"Index": (folder_list.length),
			"Scope": 1,
			"Group": null,
			"Content": Content,
			"Class": Class,
			"Ext": Ext,
			"BoundTo": null,
			"Serial": null,
			"BeginState": null
		}
		folder_list.push(_ret);
		return _ret;
	}
	//Extended version of folder_create()
	/*
		Accepts flags.
			IE:
				fold_er.createEx( 'My Content', 'SomeCSS_Class', 'r', '$ajax:SomeFile.txt $class:SomeClass' );

			Trailing spaces are removed, but spaces before the string are kept.
			Remember to remove any spaces from files names. Linux/Unix based
			operating systems don't like them.
		
		Supported flags: [$Cmd:Value]
			ajax - Load an external file into the folder.
			class - Change/set the CSS class for the folder.
			ext - Change the extension type: 'r' (row), 'c' (column), 'b' (block)
	
	*/
	function folder_createEx( Content, Class, Ext, Flags ){
		fConfig = {
			Content: Content,
			Class: Class,
			Ext: Ext,
			Flags: Flags
		};
		
		//Parse the flags.
		var Output = fConfig.Flags.split('$');
		for( i=1; i<Output.length; i++ ){
			Output[i] = Output[i].replace( /\s*$/, '' );
			ARG = Output[i].split(':');
			//ARG[0]: Command
			//ARG[1]: Value
			switch( ARG[0] ){
				case "ajax": $.ajax({
						url: ARG[1],
						async: false,
						timeout: 10000,
						success: function(data) {
							fConfig.Content = data;
						}
					});
				break;
				case "class": fConfig.Class = ARG[1];break;
				case "ext": fConfig.Ext = ARG[1];break;
				case "beginState":
					if( ARG[1] == "hidden" || ARG[1] == "shown" ){ fConfig.BeginState = ARG[1];}
					else{ fConfig.BeginState = "shown"; }
				break;
				default: throw "Invalid fold_er.createEx(Flag) parameter: " + ARG[0];break;
			}
		}
		//Create the newly made folder.
		return folder_create( fConfig.Content, fConfig.Class, fConfig.Ext );
	}
	//Check if a variable is an array.
	function folder_isArray(VAR) {
		_ret = "";
		VAR.constructor == Array ? _ret = 1 : _ret = 0;
		return _ret;
	}
	//Check if a variable is an object.
	function folder_isObject(VAR) {
		_ret = "";
		VAR.constructor == Object ? _ret = 1 : _ret = 0;
		return _ret;
	}
	//Initialize all of the folders and display them.
	function folder_init(fHandle) {
		if (folder_isArray(fHandle)) {
			for (cCur in fHandle) {
				fSerial = "folder:" + fHandle[cCur].Group + ":" + fHandle[cCur].Ext + ":" + fHandle[cCur].Index;
				if (fHandle[cCur].Ext == 'r') {
					$('<div class="' + fHandle[cCur].Class + '">' + fHandle[cCur].Content + '</div>').attr("id", fSerial).css({
						"position": "relative",
						"float": "left",
						"clear": "left"
					}).appendTo(fHandle[cCur].BoundTo);
				} else if (fHandle[cCur].Ext == 'c') {
					$('<div class="' + fHandle[cCur].Class + '">' + fHandle[cCur].Content + '</div>').attr("id", fSerial).css({
						"position": "relative",
						"float": "left"
					}).appendTo(fHandle[cCur].BoundTo);
				} else if (fHandle[cCur].Ext == 'b') {
					$('<div class="' + fHandle[cCur].Class + '">' + fHandle[cCur].Content + '</div>').attr("id", fSerial).appendTo(fHandle[cCur].BoundTo);
				} else {
					throw "fold_er.init(fHandle) invalid value in member 'Ext'.";
				}
				fHandle[cCur].Serial = fSerial;
			}
		} else if (folder_isObject(fHandle)) {
			fSerial = "folder:" + fHandle.Group + ":" + fHandle.Ext + ":" + fHandle.Index;
			if (fHandle.Ext == 'r') {
				$('<div class="' + fHandle.Class + '">' + fHandle.Content + '</div>').attr("id", fSerial).css({
					"position": "relative",
					"float": "left",
					"clear": "left"
				}).appendTo(fHandle.BoundTo);
			} else if (fHandle.Ext == 'c') {
				$('<div class="' + fHandle.Class + '">' + fHandle.Content + '</div>').attr("id", fSerial).css({
					"position": "relative",
					"float": "left"
				}).appendTo(fHandle.BoundTo);
			} else if (fHandle.Ext == 'b') {
				$('<div class="' + fHandle.Class + '">' + fHandle.Content + '</div>').attr("id", fSerial).appendTo(fHandle.BoundTo);
			} else {
				throw "fold_er.init(fHandle) invalid value in member 'Ext'.";
			}
			fHandle.Serial = fSerial;
		}
	}
	//Find and return the specified folder.
	function folder_find(folderSerial) {
		for (fCur in folder_list) {
			if (folder_list[fCur].Serial == folderSerial) {
				return folder_list[fCur];
			}
		}
		return null;
	}
	//Create a single event listenter for a folder.
	function folder_fEventEx(fHandle, Type, Callback) {
		//Array of folders
		
		//BROKEN: Does not fully iterate after first action.
		//or if another action is triggered from another folder.
		
		//TODO: Fix the folder trigger technique to handle complete
		//iteration through all folders in array.
		
		//TEMP_FIX: Use fold_er.gEventEx() for multiple folders.
		if (folder_isArray(fHandle)) {
			for (fCur in fHandle) {
				fSelector = $('div[id="' + fHandle[fCur].Serial + '"]');
				switch (Type) {
				case 'left_click':
					fSelector.live({
						'click': function () {Callback(folder_find(fHandle[fCur].Serial), 'left_click');}
					});
					break;
				case 'right_click':
					fSelector.live({
						'contextmenu': function () {Callback(folder_find(fHandle[fCur].Serial), fHandle[fCur], 'right_click');}
					});
					break;
				case 'mouseover':
					fSelector.live({
						'mouseover': function () {Callback(folder_find(fHandle[fCur].Serial), fHandle[fCur], 'mouseover');}
					});
					break;
				case 'mouseout':
					fSelector.live({
						'mouseout': function () {Callback(folder_find(fHandle[fCur].Serial), fHandle[fCur], 'mouseout');}
					});
					break;
				}
			}
		}
		//Single folder
		if (folder_isObject(fHandle)) {
			var fSelector = $('div[id="' + fHandle.Serial + '"]');
			switch (Type) {
			case "left_click":
				fSelector.live({
					'click': function () {Callback(folder_find(fHandle.Serial), 'left_click');}
				});
				break;
			case "right_click":
				fSelector.live({
					'contextmenu': function () {Callback(folder_find(fHandle.Serial), 'right_click');}
				});
				break;
			case "mouseover":
				fSelector.live({
					'mouseover': function () {Callback(folder_find(fHandle.Serial), 'mouseover');}
				});
				break;
			case "mouseout":
				fSelector.live({
					'mouseout': function () {Callback(folder_find(fHandle.Serial), 'mouseout');}
				});
				break;
			}
		}
	}

	function folder_gEventEx(Group, Type, Callback) {
		for (fCur in folder_list) {
			if (folder_list[fCur].Group == Group) {folder_fEventEx(folder_list[fCur], Type, Callback);}
		}
	}

	function folder_sEventEx(Type, Callback) {
		for (fCur in folder_list) {folder_fEventEx(folder_list[fCur], Type, Callback);}
	}
	//Depreciated: folder_fEvent_ex();
	//Create an event for a folder.
	/*
		This function will set ALL of the listening methods
		for the specified folder. Only use if creating 3 or
		more event listenters for a folder.
	*/
	function folder_fEvent(fHandle, Callback) {
		//Array of folders
		if (folder_isArray(fHandle)) {
			for (cCur in fHandle) {
				$('div[id="' + fHandle[cCur].Serial + '"]').live({
					'click': function () {
						for (oCur in folder_list) {
							if (folder_list[oCur].Serial == $(this).attr("id")) {
								Callback(folder_list[oCur], 'left_click');
								break;
							}
						}
					},
					'contextmenu': function () {
						for (oCur in folder_list) {
							if (folder_list[oCur].Serial == $(this).attr("id")) {
								Callback(folder_list[oCur], 'right_click');
								break;
							}
						}
						return false;
					}
				});
			}
			//Single folder
		} else if (folder_isObject(fHandle)) {
			var Selector = $('div[id="' + fHandle.Serial + '"]');
			$(Selector).live({
				'click': function () {
					Callback(fHandle, 'left_click');
				},
				'contextmenu': function () {
					Callback(fHandle, 'right_click');
				}
			});
		}
	}
	//Create a group event
	function folder_gEvent(groupName, Callback) {
		for (fCur in folder_list) {
			if (folder_list[fCur].Group == groupName) {
				folder_fEvent(folder_list[fCur], Callback);
			}
		}
	}
	//Create an event for the entire scope
	function folder_sEvent(Callback) {
		for (fCur in folder_list) {
			folder_fEvent(folder_list[fCur], Callback);
		}
	}
	//Get a list of folders from a group
	function folder_getGroup(groupName) {
		var _ret = Array();
		for (fCur in folder_list) {
			if (folder_list[fCur].Group == groupName) {
				_ret.push(folder_list[fCur]);
			}
		}
		return _ret;
	}
	//Get a list of folders with scope enabled
	function folder_getScope() {
		var _ret = Array();
		for (fCur in folder_list) {
			if (folder_list[fCur].Scope == 1) {
				_ret.push(folder_list[fCur]);
			}
		}
		return _ret;
	}
	//Find if variable is a group name
	function folder_isGroup(Var) {
		for (fCur in folder_list) {
			if (folder_list[fCur].Group == Var) {
				return folder_list[fCur];
			}
		}
		return 0;
	}

	function mSlot() {
		var mem = {
			Locked: false,
			Value: null,
			Job: null
		};

		function mSlot_lock(_BOOL) {
			if (_BOOL == null || _BOOL == undefined) {
				return mem.Locked;
			} else {
				_BOOL ? _BOOL = true : _BOOL = false;
				mem.Locked = _BOOL;
			}
		}

		function mSlot_set(value) {
			if (mem.Locked) {
				throw "mSlot is locked. CURRENT JOB: " + mem.Job;
			} else {
				mem.Value = value;
			}
		}

		function mSlot_get() {
			return mem.Value;
		}

		function mSlot_job(jname) {
			if (mem.Locked) {
				throw "mSlot is locked. CURRENT JOB: " + mem.Job;
			} else {
				mem.Job = jname;
			}
		}
		this.lock = mSlot_lock;
		this.set = mSlot_set;
		this.get = mSlot_get;
		this.job = mSlot_job;
	}
	var mSlot = new mSlot();

	function folder_swapContent(fHandle, To) {
		if (fold_er.isObject(fHandle)) {
			if (!mSlot.lock()) {
				mSlot.set(fHandle.Content);
				mSlot.job("Swap Content");
				mSlot.lock(1);
				if (folder_isObject(To)) {
					fHandle.Content = To.Content;
					To.Content = mSlot.get();
					$('div[id="' + fHandle.Serial + '"]').html(fHandle.Content);
					$('div[id="' + To.Serial + '"]').html(To.Content);
				} else {
					fHandle.Content = To;
					$('div[id="' + fHandle.Serial + '"]').html(To);
				}
				mSlot.lock(0);
			}
		} else if (folder_isGroup(fHandle)) {
			if (!mSlot.lock()) {
				if (!folder_isGroup(To) && !folder_isObject(To)) {
					var list = folder_getGroup(fHandle);
					for (fCur in list) {
						$('div[id="' + list[fCur].Serial + '"]').html(To);
					}
				} else if (folder_isObject(To)) {
					var list = folder_getGroup(fHandle);
					for (fCur in list) {
						$('div[id="' + list[fCur].Serial + '"]').html(To.Content);
					}
				}
			}
			mSlot.lock(0);
		}
	}

	function folder_swapClass(fHandle, To) {
		if (folder_isObject(fHandle)) {
			if (!mSlot.lock()) {
				mSlot.set(fHandle.Class);
				mSlot.job("swapClass");
				mSlot.lock(1);
				if (folder_isObject(To)) {
					fHandle.Class = To.Class;
					To.Class = mSlot.get();
					$('div[id="' + fHandle.Serial + '"]').removeClass(mSlot.get()).addClass(fHandle.Class);
					$('div[id="' + To.Serial + '"]').removeClass(fHandle.Class).addClass(To.Class);
				} else {
					fHandle.Class = To;
					$('div[id="' + fHandle.Serial + '"]').removeClass(mSlot.get()).addClass(fHandle.Class);
				}
			}
			mSlot.lock(0);
		} else if (folder_isGroup(fHandle)) {
			if (!mSlot.lock()) {
				if (!folder_isGroup(To)) {
					mSlot.lock(0);
					mSlot.job("swapCSS-Group-To-Class");
					var list = folder_getGroup(fHandle);
					for (fCur in list) {
						mSlot.set(list[fCur].Class);
						list[fCur].Class = To;
						$('div[id="' + list[fCur].Serial + '"]').removeClass(mSlot.get()).addClass(list[fCur].Class);
					}
				} else {
					mSlot.lock(0);
					mSlot.job("swapCSS-Group-To-Group");
					var oldGroup = folder_getGroup(fHandle);
					var newGroup = folder_getGroup(To);
					for (i = 0; i < oldGroup.length; i++) {
						//Hold the current style
						mSlot.set(oldGroup[i].Class);
						//Swap the classes
						oldGroup[i].Class = newGroup[i].Class;
						newGroup[i].Class = mSlot.get();
						//Swap-1
						$('div[id="' + oldGroup[i].Serial + '"]').removeClass(mSlot.get()).addClass(oldGroup[i].Class);
						//Swap-2
						$('div[id="' + newGroup[i].Serial + '"]').removeClass(oldGroup[i].Class).addClass(mSlot.get());
					}
				}
			}
		} else {
			return 0;
		}
	}
	//SHORTS
	this.bind = folder_bind; //Bind folder to element
	this.create = folder_create; //Create a folder
	this.init = folder_init; //Initialize/Display folders
	this.scope = folder_scope; //Enable/Disable scope for folder
	this.group = folder_group; //Set a group for a folder.
	
	//Extended Shorts
	this.createEx = folder_createEx;
	
	//Events -- All events are initialized at once
	this.fEvent = folder_fEvent; //Define folder event with Callback
	this.gEvent = folder_gEvent; //Define group event with Callback
	this.sEvent = folder_sEvent; //Define scope event with Callback
	
	//Extended Events -- Only one event is initialized at a time.
	this.fEventEx = folder_fEventEx;
	this.gEventEx = folder_gEventEx;
	this.sEventEx = folder_sEventEx;
	
	//Lists
	this.getGroup = folder_getGroup;
	this.getScope = folder_getScope;
	
	//Swapping
	this.swapClass = folder_swapClass;
	this.swapContent = folder_swapContent;
	
	//Extras
	this.isArray = folder_isArray;
	this.isObject = folder_isObject;
	this.isGroup = folder_isGroup;
	
	//Serial number handling
	this.pSerial = pSerial;
}
var fold_er = new fold_er_class();
