/**
 * jQuery Sabramedia Plugin Library - Function for Sabramedia Virtual Office System
 * Copyright (C) 2008 - 2009 Sabramedia, LLC
 * http://www.sabramedia.com
 *
 * @author Nick Johnson {@link http://nickjohnson.com}
 */

/* Global Variables */
var sabramediaSpinnerSmall = '<span class="pending-spinner"><img src=\'/admin/theme/default/img/spinner-small.gif\' /></span>';
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,""); };
String.prototype.ltrim = function() { return this.replace(/^\s+/,""); };
String.prototype.rtrim = function() { return this.replace(/\s+$/,""); };


/* jQuery Begins */
(function ($)
{

/**
 *	@name listCollapser
 *	@desc Simple function that makes a list collapsible. 
 *	 
 *	Note: jQuery UI Accordion widget should be used instead of this in most cases.
 *	
 *	@example <ul id="collapse"><li><h2>Click to Expand</h2><ul><li>Content</li></ul><li><ul>
 *	@example $('#collapse').listCollapser();
 *	@desc
 */	
	$.fn.listCollapser = function()
	{
		$('li:has(ul)',this).children('ul').hide().end()
		.find(':first').click(function(event){
			if(event.target){
				if($(this).parent().children('ul').is(':hidden')){
					$(this)
						.parent().children('ul').slideToggle('normal');
				}else{
					$(this)
						.parent().children('ul').slideToggle('normal');
				}
				return false;
			}
			
		});
	};
/**
 *  @name paginatedSearch
 *  @desc Paginated Search Function
*/

	$.paginatedSearch = function(searchObject){
	window.paginatedSearch = {};
	searchObject.backButton.attr("disabled",true);
	searchObject.nextButton.attr("disabled",true);
	(searchObject.pageLimit) ? window.paginatedSearch.pageLimit = searchObject.pageLimit : window.paginatedSearch.pageLimit = 20 ;
	var search = function(search,page){
	if (window.paginatedSearch.searchRequest != undefined){
		window.paginatedSearch.searchRequest.abort();
		$('.pending-spinner').remove();
	}
	window.paginatedSearch.entryCount = 1;
	window.paginatedSearch.lastSearch = '';
	window.paginatedSearch.currentPage = page;
	var searchLength = window.paginatedSearch.lastSearch.length;
	var cutString = search.substring(0,searchLength);
	if ( ( window.paginatedSearch.entryCount != 0 ) || ( window.paginatedSearch.currentPage != 0 ) || ( cutString.toLowerCase() != window.paginatedSearch.lastSearch.toLowerCase() ) )
	{
		$('#search-field').after(sabramediaSpinnerSmall);
		window.paginatedSearch.lastSearch = search;
		window.paginatedSearch.searchRequest = $.ajax({
				type:"POST",
				url:searchObject.url,
				dataType:"json",
				data:{search:search,limit:window.paginatedSearch.pageLimit,page:page},
				success:function(data){
					$('#transaction-list').empty();
					$('#transaction-table .inserted').remove();
					$('.pending-spinner').remove();
					window.paginatedSearch.entryCount = 0;
					$.each(data,function(key,value){
						window.paginatedSearch.entryCount += 1;
					})
					if (window.paginatedSearch.entryCount < window.paginatedSearch.pageLimit){
						$('#forward-page').attr("disabled",true);
					} else {
						$('#forward-page').attr("disabled",false);
					};
					if (page > 0){
						$('#back-page').attr("disabled",false);
					} else {
						$('#back-page').attr("disabled",true);
					}
					searchObject.callback(data);
					
				}
		});
	}};
	searchObject.backButton.click(function(){
			searchObject.backButton.attr("disabled",true);
			if (searchObject.searchField){
				var searchkey = searchObject.searchField.val();
			} else {var searchkey = ''}
			window.paginatedSearch.currentPage -= 1;
			search(searchkey,window.paginatedSearch.currentPage);
	});
	searchObject.nextButton.click(function(){
		searchObject.nextButton.attr("disabled",true);
		if (searchObject.searchField){
			var searchkey = searchObject.searchField.val();
		} else {var searchkey = ''}
		window.paginatedSearch.currentPage += 1;
		search(searchkey,window.paginatedSearch.currentPage)
	});
	
	if (searchObject.searchField){
		window.paginatedSearch.search_timeout = undefined;
		searchObject.searchField.keyup(function(){
			if (window.paginatedSearch.search_timeout != undefined) {
				clearTimeout(window.paginatedSearch.search_timeout);
			}
			window.paginatedSearch.search_timeout = setTimeout(function(){
				window.paginatedSearch.search_timeout = undefined;
				var searchkey = searchObject.searchField.val();
				search(searchkey,0);
			},750);
			
		});
	};
	search('',0);
	
	};


	
/**
 *	@name navigationMenu
 *	@desc Makes <ul> tags with infinite ul children into hover on/off navigation (requires css styling) 
*/
	$.fn.navigationMenu = function( callerSettings )
	{
		var settings = $.extend({
			eventType : 'hover',
			menuWrap: 'ul',
			menuEffect: 'slide',
			menuSpeed: 100,
			timeout: 300
		}, callerSettings || {});
		
		var navigation = $(this);

		$('li:has('+settings.menuWrap+')',this).children(settings.menuWrap).hide().end()
			.each(function(i){
				var menu = $(this).children(settings.menuWrap);
				$(this).addClass('ui-has-child');
				$(this).mouseover(function(event){
					$(this).addClass('ui-on-child');
					if(event.target){
						if($(menu).is(':hidden')){
							switch( settings.menuEffect ){
							case 'slide':
								$(menu).slideDown( settings.menuSpeed );
							break;
							case 'fade':
								$(menu).fadeIn( settings.menuSpeed );
							break;
							}
							
							menuHandler(menu);
						}
					}
				});
			});
				
		function menuHandler(menu)
		{
			var timerID = 0;
			
			switch(settings.eventType){
				case 'hover':
					$(menu).parent().hover(function(event){
						if(timerID){ clearTimeout(timerID); };
						timerID  = 0;
						switch( settings.menuEffect ){
						case 'slide':
							$(this).siblings().children(settings.menuWrap).slideUp( settings.menuSpeed );
						break;
						case 'fade':
							$(this).siblings().children(settings.menuWrap).fadeOut( settings.menuSpeed );
						break;
						}
						
						$(menu).parent('li').removeClass('ui-on-child');
					},
					function(){
						timerID = setTimeout(function(){
							switch( settings.menuEffect ){
							case 'slide':
								$(menu).slideUp( settings.menuSpeed );
							break;
							case 'fade':
								$(menu).fadeOut( settings.menuSpeed );
							break;
							}
							
							$(menu).parent('li').removeClass('ui-on-child');
						},settings.timeout);
					});
				break;
				
				case 'toggle':
					// We can do this later
				break;
			
			}
		};
	};

	
/* Ajax Handling Functions */

	// Ajax event handler for submiting input fields with in a set of <li> or <tr> tags 
	$.fn.setListFieldEvents = function(callerSettings)
	{
		var settings = $.extend({
			actionDeletePath: false,
			actionSavePath: false,
			rowEvents: false, // For passing custom row-level events to the added row
			showAddButton:false,
			placeAddButton:false,
			removeObject:false,
			index:false
		}, callerSettings || {});
		
		// Hide all parent format containers
		$('.sibling-format').hide();
		var parentContainer = $(this).parent();
		
		if(settings.actionSavePath && settings.index == 0){
			$('.template-add', parentContainer).hide();
			
			if(settings.showAddButton){
				var addButton = $('<input type=\"button\" value=\"Add\" class=\"button-add\" />').click(function(){
					$('.template-add',parentContainer).toggle();
				});
				
				if(settings.placeAddButton){
					settings.placeAddButton( addButton );
				}else{
					$(addButton).insertBefore(parentContainer);
				}
			}
			
			$('.key-enter-add', parentContainer).ajaxEventHandler({
				dataContainer:'.template-add',
				dataObject:{'vo-action':'insert'},
				eventType:'keyup',
				keyCode:13,
				actionController: settings.actionSavePath,
				success:[successAdd]
			});
		}
			$.fn.rowEvents = function()
			{
				var obj = $(this);
				
				if(settings.actionSavePath){
					$('.key-enter-update',this).ajaxEventHandler({
						dataContainer:obj,
						dataObject:{'vo-action':'update'},
						eventType:'keyup',
						keyCode:13,
						actionController: settings.actionSavePath
					});
					
					$('.keyup-update',this).ajaxEventHandler({
						dataContainer:obj,
						dataObject:{'vo-action':'update'},
						eventType:'keyup',
						actionController: settings.actionSavePath
					});
					
					$('.click-update',this).ajaxEventHandler({
						dataContainer:obj,
						dataObject:{'vo-action':'update'},
						eventType:'click',
						actionController: settings.actionSavePath
					});
				}
				
				if(settings.actionDeletePath){
					$('.click-delete',this).ajaxEventHandler({
						dataContainer:obj,
						dataObject:{'vo-action':'delete'},
						eventType:'click',
						actionController: settings.actionDeletePath,
						verifyAction: 'Are you sure you want to delete this?',
						success:[function(data, status){
								// Change class name so that the .click-delete class does not get re-enabled.
								$('.click-delete',obj).attr('class','click-delete-remove');
								var removeObject = obj;
								if(settings.removeObject){
									removeObject = settings.removeObject;
								}
								$(removeObject).fadeOut('normal',function(){
									$(removeObject).remove();
								});
							}]
					}).hover(function(){
						$(this).addClass('ui-state-hover');
					},
					function(){
						$(this).removeClass('ui-state-hover');
					});
				}
			};
		
		$(this).rowEvents();
		
		var rowTemplate = $('.template', parentContainer).hide().clone();
		// Custom success function for adding
		function successAdd( data, status, ajaxOptions )
		{
			var newRow = $(rowTemplate).show().clone();
			
			$.each(data.newRow, function( key, val ){
				if($('.'+key,newRow).is('input')){
					$('.'+key,newRow).val(val);
				}else{
					$('.'+key,newRow).text(val);
				}
			});
			
			$('.template-add', parentContainer).hide(function(){
				$('input',this).val('');
				$(newRow)
					.removeClass('template-add')
					.attr('data-json','{id:' + data.newId + '}')
					.insertAfter('.template-add')
					.rowEvents();
			});
			
			if(settings.rowEvents){
				settings.rowEvents( newRow, data );
			}
		};
		
		function checkULContent(parentContainer)
		{
			if($(parentContainer).children().length == 0){
				$(parentContainer).append('<li>No data here.</li>').hide().slideDown('normal');
			}
		};
	};
	/**
		Default: Assume that the event handler is a parent tag with children input tags.<b>
		If dataObject is set from outside, then only send that and don't run data row functions 
	*/
	
/**
 *	@name ajaxEventHandler
 *	@desc Standard method for connecting dom elements with events that send data to php action controllers.
 *	@dependency livejquery
 * 	@param Object of options
 *	
*/
	$.fn.ajaxEventHandler = function( callerSettings )
	{
		var settings = $.extend({
			eventType: '',
			keyCode: null,
			dataContainer: null, // Container where data-json attributes holds data and any children inputs represent data
			dataObject: null, // Raw JSON data object that can be sent by itself or appended to the dataContainer
			actionController: '/action/public/404-json.php',
			verifyAction: false,
			beforeSend: null,
			waiting: null,
			success: null,
			complete: null,
			global: true, // Allows global ajax events to be triggered
			spinner: true
		}, callerSettings || {});
		
	// If dataObject is passed, send as Ajax data
		var thisUpdateField = $(this);
		
		
	// Set event here
		$(this).bind(settings.eventType,function(event){
			$.voAjax( settings, thisUpdateField );	
			return false;
		});	
		
		return this;
	};
	
	$.voAjax = function( settings , thisUpdateField )
	{
		
	// Data Preparation
	
		// if tinyMCE variable set then we need to trigger the new values.
		if(typeof(tinyMCE) != 'undefined'){
			//tinyMCE.triggerSave();
		}
		
		// This doesn't work... I know how to get it to work now, think iframe.
		if(typeof(editAreaLoader) != 'undefined'){
			$('textarea#content-js').append(editAreaLoader.getValue('content-js'));
		}
		
	// Methods
		function getSerializedData()
		{
			var serializedData = '';
			// Set data here. Important to set after this just in case we need to do an preparation.
			if(settings.dataContainer){
				serializedData += $(settings.dataContainer).serializeRowData();
			}
			
			if(settings.dataObject){
				if(settings.dataContainer){ serializedData += '&'; } // Appending character if both are set
				serializedData += serializeJSON(settings.dataObject);
			}
			
			
			return serializedData;
		};
		
		function beforeSend( xhr )
		{
			if(settings.spinner){
				$(thisUpdateField).after(sabramediaSpinnerSmall);
			}
			
			var verify = true;
			if(settings.verifyAction){
				verify = confirm(settings.verifyAction);
			}
			
			if( !verify ){
				return false;
			}
			
			// Disable all sibling fields only dataObject is not passed and rowData is used
			// $('button').attr('disabled','disabled');
	
			// Iterate through custom fields
			if(settings.beforeSend){
				$.each(settings.beforeSend,function(i,customFunction){
					// Pass field object of event handler
					customFunction(xhr,thisUpdateField);
				});
			}
		};
		
		function success( data, status )
		{
			$('.pending-spinner').remove();
			if(settings.success){
				$.each(settings.success,function(i,customFunction){
					// Pass field object of event handler
					if($.isFunction( customFunction )){
						customFunction( data, status, thisUpdateField );
					}
				});
			}else{
//				$(thisUpdateField)
//					.focus()
//					.siblings('.temp-message').remove().end()
//					.parent('li').removeAttr('style').end();
			}
			
			if(data.warning){
				$.voMessage.alert( data.warning );
			}
			if(data.message){
				$.voMessage.dock( data.message );
			}
		};
		
		function complete( xhr, status)
		{
			// Re-enable disabled fields upon success
			// $('button').removeAttr('disabled');
			if(settings.complete){
				$.each(settings.complete,function(i,customFunction){
					// Pass field object of event handler
					if($.isFunction( customFunction )){
						customFunction( xhr, status );
					}
				});
			}
		};

	// Ajax intializes here
		
		return $.ajax({
			type:'POST',
			url:settings.actionController,
			dataType:'json',
			data:getSerializedData(),
			beforeSend:beforeSend,
			success:success,
			complete:complete,
			global:settings.global
		});
	};
	
	/**
	* serializeJSON()
	* Turns JSON object into a serialized string in the form of: key=val&key2=val2 
	*
	* @param object literal object
	* @return string serialized for Ajax
	*/
	function serializeJSON(dataObject)
	{
		var dataArray = [];
		var retval;
		
		$.each(dataObject,function(key,data){
			dataArray.push(key + '=' + escape(data));
		});
		
		retval = dataArray.join('&');
		return retval;
	};
	
	function simplifyInputData(dataObject)
	{
		var object = [];
		var retval;
		
		$.each(dataObject,function(key,data){
			
			object[data.name] = data.value;
		});
		
		retval = object;
		return retval;
	};
	
	/** 
	* serializeRowData()
	* Accesses this elements parent element data-json attribute and all sibling element form-type
	* fields, then serializes data for sending via Ajax XHR.<b>
	*
	* @return string serialized data to send via Ajax
	* @dependency metadata
	*/
	$.fn.serializeRowData = function()
	{
		// Gets all json data contained in the parent tag's data-json wrapper 
		var metaData='';
		if($.metadata){
			$.metadata.setType('attr','data-json');
			jsonObject = $('[data-json]',this).andSelf().metadata();
			metaData += serializeJSON(jsonObject)+'&';
		}
		if($(this).data('postdata')){
			metaData += serializeJSON($(this).data('postdata'))+'&';
		}
		// Gets all form type fields based on the current field's containing parent,
		// Then it serializes the data for passing to the ajax controller.
		var inputData = $(this).find(':input');
		
		// Concatentate the jsonData and the inputData
		var serialData = metaData+inputData.serialize();
		//return jsonData;
		// Optional dual-type data object
		
		return serialData;
	};
		
	// Takes JSON returned data and places data in fields or tags with data.key == '.class'
	$.fn.setDataDisplay = function( data )
	{
		if(data){
			object = $(this);
			$.each(data, function( key, val ){
				if(typeof(val) != 'object'){
					var input_type = $('.'+key, object).attr('type');
					
					if($('.'+key, object).is('select')){
						input_type = 'select';
					}
					
					switch (input_type) {
						case 'text':
							$('.'+key, object).val(val);
						break;
						case 'textarea':
							$('.'+key, object).val(val);
						break;
						case 'radio':
							if(val == true){ val=1; }
							if(val == false){ val=0; }
							$('.'+ key +'[value='+ val +']', object).attr('checked','checked');
						break;
						case 'checkbox':
							if(val == true){ val=1; }
							if(val == false){ val=0; }
							$('.'+ key +'[value='+ val +']', object).attr('checked','checked');
						break;
						case 'select':
							$('.'+key+' option[value='+val+']', object).attr('selected','selected');
						break;
						default:
							$('.'+key, object).text(val);
						break;
					}
					//$('.'+key, object).text(val);
				}
			});
			return this;
		}
	};
		
	$.extend({
	
	/**
	* @name jqPhp
	* @desc Purpose is for php variables to be passed into object to be globally accessed.
	*/
		jqPHP : {
		
			phpUrl : {}, // Url object
			phpVar : {}, // Url object

			// Set the urls from php so custom plugins can access the unique urls created by Sabramedia Virtual Office.
			setUrl : function( name, url )
			{
				this.phpUrl[name] = url;
			},
			// Get the urls in the plugin by name
			getUrl : function( name )
			{
				return this.phpUrl[name];
			},
			
			setVar : function( name, variable )
			{
				this.phpVar[name] = variable;
			},

			getVar : function( name )
			{
				return this.phpVar[name];
			},
			removeVar : function( name )
			{
				delete this.phpVar[name];
			}
		},
	/**
	* @name voMessage
	* @desc Standard method for bringing basic messages to system users.
	*/
		voMessage : {
			// Replaces standard alert with a nicer popup
			alert : function( message )
			{
				var randomId = Math.floor(Math.random()*11);
				var $dialog = $('<div id="vo-dialog'+randomId+'" />');
				$dialog.append('<span class="ui-icon ui-icon-alert" style="float:left; margin:2px 7px 20px 0;"></span>' + message);
				$dialog.appendTo('body'); 
				
				$dialog.dialog({
					title: 'Virtual Office Alert',
					bgiframe: true,
					resizable: false,
					height:200,
					width:300,
					modal: true,
					overlay: {
						backgroundColor: '#000',
						opacity: 0.5
					},
					buttons: {
						'Ok': function() {
							$(this).dialog('close');
							$(this).dialog('destroy');
							$('#vo-dialog'+randomId).remove();
						}
					}
				});
				
			},
			
			// Footer alert
			dock : function( message )
			{
				$("#dock-container").hide();
				$("#dock-container #ajax-message").empty().append( message );
				$("#dock-container").fadeIn('normal');
				setTimeout("$('#dock-container').fadeOut('slow')",4000);
			},
			
			// Safer way to post to Firebug console
			debug : function( message )
			{
				if(window.console){
					console.log(message);
				}else{
					if(typeof message != 'string'){
						message = 'Your browser doesn\'t support advanced debugging. Try Firefox and Firebug!';
					}
					//alert(message);
				}
			}
		},
		
		/**
		* @name log
		* @desc Alias of $.voMessage.debug(); 
		*/
		
		log : function( message )
		{
			$.voMessage.debug( message );
		}
	});
	
		
/* Not Standardized */

	$.fn.addInput = function(name,value,type)
	{
		type = type ? type : 'hidden';
		$('input[type='+type+'][name='+name+']',this).remove();
		$(this).prepend($('<input>').attr({'type':type,'name':name,'value':value}));
	};
	
// Start form setup and validation
//	$.fn.checkWarnings = function( buttonValue )
//	{
//		buttonValue = buttonValue ? buttonValue : 'Next Step >';
//		
//		var numWarnings = $('.warning').length;
//		if(numWarnings > 0){
//			$('.submit',this).attr('disabled','disabled').val('Fill in required fields');
//		}else{
//			$('.submit',this).removeAttr('disabled').val(buttonValue);
//		}
//	};
//
//	$.fn.setFormValidation = function( buttonValue )
//	{
//		var requiredFlag = '<span class="required-flag">*</span>';
//		$('.required-flag',this).remove();
//	
//		$(':input',this).filter('.required')
//		.prev('label').addClass('required')
//		.append(requiredFlag)
//		.parents('li').addClass('warning');
//		
//		$(this).checkWarnings(buttonValue);
//	
//		$(':input:visible',this).each(setRequired).bind('keyup change',setRequired);
//		
//		function setRequired()
//		{
//			if($(this).is('.required')){
//				if($(this).val()){
//					$(this).parents('li:first').removeClass('warning');
//				}else{
//					$(this).parents('li:first').addClass('warning');
//				}
//				$(this).parents('form').checkWarnings(buttonValue);
//			}
//		};
//	};

	/*	Blog Entry:
		jQuery Comments() Plug-in To Access HTML Comments For DOM Templating
		
		Author:
		Ben Nadel / Kinky Solutions
		
		Link:
		http://www.bennadel.com/index.cfm?dax=blog:1563.view
		
	*/
	
	$.fn.comments = function( blnDeep ){
		var blnDeep = (blnDeep || false);
		var jComments = $( [] );
	 
		// Loop over each node to search its children for
		// comment nodes and element nodes (if deep search).
		this.each(
			function( intI, objNode ){
				var objChildNode = objNode.firstChild;
				var strParentID = $( this ).attr( "id" );
				// Keep looping over the top-level children
				// while we have a node to examine.
				while (objChildNode){
					// Check to see if this node is a comment.
					if (objChildNode.nodeType === 8){
						// We found a comment node. Add it to
						// the nodes collection wrapped in a
						// DIV (as we may have HTML).
						/*jComments = jComments.add(
							"<div rel='" + strParentID + "'>" +
							objChildNode.nodeValue +
							"</div>"
							);*/
						
						jComments = jComments.add(objChildNode.nodeValue); // Nick modifed this
					} else if (
						blnDeep &&
						(objChildNode.nodeType === 1)
						) {
	 
						// Traverse this node deeply.
						jComments = jComments.add(
							$( objChildNode ).comments( true )
							);
					}
					// Move to the next sibling.
					objChildNode = objChildNode.nextSibling;
				}
			}
			);
		// Return the jQuery comments collection.
		return( jComments );
	};
	
	// For comparing two arrays.. thanks David @ stackflow
	$.fn.compare = function(t) {
	    if (this.length != t.length) { return false; }
	    var a = this.sort(),
	        b = t.sort();
	    for (var i = 0; t[i]; i++) {
	        if (a[i] !== b[i]) { 
	                return false;
	        }
	    }
	    return true;
	};

	
	
	/*
	 * The backbone for click and discover interaction
	 */
	
	$.voCnd = {
			'settings':
				{
					'controller':null,
					'panel':'#cnd-navigation',
					'pagination':'.cnd-pagination',
					'contentDom': '',
					'contentDomRow': '',
					'filterPanel' : 0,
					'initContent' : 1
				},
			'hierarchyArray' : {}, // Cached arrays for mult-dimensional catgories
			'filterArray' : {}, // sent via ajax to controller
			'data':{}, // Set externally to be sent via ajax to controller
			'panelGroups' : {},
			'customContentFunction':{},
			'ajaxCompleteFunction': function( data, status ){},
			'resultTotal' : '', // resultTotal set in setInterface() and filterResults()
			'_currentXhr' : null,
			
			
			'init' :
				function()
				{
					$.voAjax({
						'actionController': $.voCnd.settings.controller,
						'dataObject':$.extend($.voCnd.data,{'vo-action':'init','filter_conditions':$.toJSON($.voCnd.filterArray)}),
						'beforeSend':[$.voCnd.waitingForResults],
						'success':[$.voCnd.ajaxSuccessFunction,$.voCnd.setInterface],
						'complete':[$.voCnd.ajaxCompleteFunction]
					});
				},
				
			'setPaginationMessage' :
				function()
				{
					if($.voCnd.resultTotal){
						$('span.results .current-page',$.voCnd.settings.pagination).text(($.voCnd.filterArray['page'] + 1));
						$('span.results .total-page',$.voCnd.settings.pagination).text( Math.ceil( ($.voCnd.resultTotal / $.voCnd.filterArray['limit'])) );
						$('span.results .total-item',$.voCnd.settings.pagination).text($.voCnd.resultTotal);
					}
				},
				
			'setPagination' :
				function()
				{
					if(!$.voCnd.filterArray['page']){ $.voCnd.filterArray['page'] = 0; }

					$.voCnd.setPaginationMessage();
					$('button',$.voCnd.settings.pagination).unbind('click').click(function(e){
						var resultTotal = $.voCnd.resultTotal ? $.voCnd.resultTotal : $($.voCnd.settings.pagination+':first .total-item').text();
						if($(e.target).is('.previous')){
							var previousPage = $.voCnd.filterArray['page'] - 1;
							if( previousPage + 1 > 0 ){
								$.voCnd.filterArray['page'] = previousPage;
							}else{
								$.voCnd.filterArray['page'] = Math.floor( resultTotal / $.voCnd.filterArray['limit'] ); // go to last page
							}
							$.voCnd.getResults();
						}else{
							// page * limit < results
							var nextPage = $.voCnd.filterArray['page'] + 1;
							
							if( nextPage * $.voCnd.filterArray['limit'] < resultTotal ){
								
								$.voCnd.filterArray['page'] = nextPage;
							}else{
								$.voCnd.filterArray['page'] = 0;
							}
							$.voCnd.getResults();
						}
						
						$.voCnd.setPaginationMessage();
					});
				},
				
			'setFilterPanel' : 
				function( boolean )
				{
					$.voCnd.settings.filterPanel = boolean;
				},
				
			'setLimit' : 
				function( limit )
				{
					
					// For true customizabliity in SEO friendly versions I will need to get the limit from the DOM
					if( $('#pagination-limit',$.voCnd.settings.pagination).length > 0 ){
						$.voCnd.filterArray.limit = parseInt($('#pagination-limit',$.voCnd.settings.pagination).text());
					}else if( !limit ){
						// Default if the limit is not set
						$.voCnd.filterArray.limit = 12;
					}else{
						$.voCnd.filterArray.limit = limit;
					}
				},
				
			'getResults' :
				function()
				{
					// **Key efficiency logic - abort other ajax requests in favor of current
					// speeds up response
					if($.voCnd._currentXhr){ $.voCnd._currentXhr.abort(); }
					$.voCnd._currentXhr = $.voAjax({
						'actionController': $.voCnd.settings.controller,
						'dataObject':$.extend($.voCnd.data,{'vo-action':null,'filter_conditions':$.toJSON($.voCnd.filterArray)}),
						'beforeSend':[$.voCnd.waitingForResults],
						'success':[$.voCnd.ajaxSuccessFunction,$.voCnd.filterResults],
						'complete':[$.voCnd.ajaxCompleteFunction]
					});
				},
				
			'setController' :
				function( location )
				{
					$.voCnd.settings.controller = location;
				},
			
			'setContentDom' :
				function( contentDom, contentDomRow )
				{
					$.voCnd.settings.contentDom = contentDom;
					$.voCnd.settings.contentDomRow = contentDomRow;
				},
				
			'preload' :
				function()
				{
					
				},
				
			'setPanelGroup' :
				function( callerSettings )
				{
					// groupName, groupDisplayName , multiDimension, defaultValue
					// Build the group object, but don't overwrite it proecedurally.
					// The interface conrtoller gets precedence over the Ajax data settings for group.
					$.voCnd.panelGroups[callerSettings.group] = $.extend({
						'displayName' : (callerSettings.displayName ? callerSettings.displayName : callerSettings.group ),
						'multiDimension' : (callerSettings.multiDimension ? 1 : 0), // if true then treat the group like a categoric hierarchy
						'dataFormatSingle' : callerSettings.dataFormatSingle,
						'filter' : callerSettings.filter,
						'filterEffect' : callerSettings.filterEffect
					},$.voCnd.panelGroups[callerSettings.group] || {});
				},
			'setGroupDefault' :
				function( groupName, id )
				{
					if(typeof($.voCnd.filterArray[groupName]) != 'object'){
						$.voCnd.filterArray[groupName] = [];
					}
					$.voCnd.filterArray[groupName].push(id);
					$.voCnd.panelGroups[groupName] = $.extend({'defaultValue':id},$.voCnd.panelGroups[groupName] || {});
				},
				
			// Group class
			'group' : 
				function( domObject, groupName, groupSettings )
				{
					var thisGroup= this;
					
					this.menuClose =
						function( e )
						{
							$('h3 span',domObject).removeClass('ui-icon-triangle-1-s');
							$('h3 span',domObject).addClass('ui-icon-triangle-1-e');
							$('.cnd-list',domObject).slideUp('fast');
						};
						
					this.menuOpen = 
						function( e )
						{
							$('h3 span',domObject).removeClass('ui-icon-triangle-1-e');
							$('h3 span',domObject).addClass('ui-icon-triangle-1-s');
							$('.cnd-list',domObject).slideDown('fast');
						};
						
					this.itemClick =
						function( e )
						{
						if($(this).is('.ui-state-disabled')){
							e.stopPropagation();
						}else{
							// Click on
							if(!$(this).is('.ui-state-active')){
								// Format interface so group data is sent as a single string
								if(groupSettings.dataFormatSingle){
									$.voCnd.filterArray[groupName] = [$(this).attr('rel')];
								}else{
								// Format interface so group data is sent as an array
									if((clearItemId =$.inArray($('.crumb-current',domObject).attr('rel'), $.voCnd.filterArray[groupName])) != -1){
										$.voCnd.filterArray[groupName].splice(clearItemId,1);
									}
									$.voCnd.filterArray[groupName].push($(this).attr('rel'));
									
									// Show filter-cancel button							
									if($.voCnd.filterArray[groupName].length  > 0){
										$(domObject).find('.cnd-button.cancel').show();
									}
								}
								$.voCnd.filterArray['page'] = 0;
								
								// Simulate toggle unbind current event and bind another
								/*$(this)
									.unbind('click')
									.bind('click',thisGroup.itemClickOff);*/
								if(groupSettings.dataFormatSingle){
									$(this).siblings().removeClass('ui-state-active');
								}
								$(this).addClass('ui-state-active');
								
								$.voCnd.getResults(); // Remember with new parameters we need to set page to 0
							}else{
							// Click off
								$(domObject).find('.cnd-button.cancel').show();
								
								// Remove the clicked item id
								var clickedItem = $(this).attr('rel');
								
								/*if(groupSettings.dataFormatSingle){
									$.voCnd.filterArray[groupName] = 0;
								}else{*/
									if((clearCategoryId = $.inArray(clickedItem,$.voCnd.filterArray[groupName])) != -1){
										$.voCnd.filterArray[groupName].splice(clearCategoryId,1);
									}
								//}
								$.voCnd.filterArray['page'] = 0;
								
								// Remove filter-cancel button
								if(groupSettings.dataFormatSingle || $.voCnd.filterArray[groupName].length  < 1){
									if($('.crumb-current',domObject).attr('rel')){
										/*if(groupSettings.dataFormatSingle){
											$.voCnd.filterArray[groupName] = $('.crumb-current',domObject).attr('rel');
										}else{*/
											$.voCnd.filterArray[groupName] = [$('.crumb-current',domObject).attr('rel')];
										//}
									}
									$(domObject).find('.cnd-button.cancel').hide();
								}
								
								// Set class to off
								$(this).removeClass('ui-state-active');
								$.voCnd.getResults(); // Remember with new parameters we need to set page to 0
							}
						}
					};
						
					this.reset =
						function( e )
						{
							$(this).hide();
							$('li.ui-state-active', domObject)
								.removeClass('ui-state-active');
							
							if($('.crumb-current',domObject).attr('rel')){
								/*if(groupSettings.dataFormatSingle){
									$.voCnd.filterArray[groupName] = $('.crumb-current',domObject).attr('rel');
								}else{*/
									$.voCnd.filterArray[groupName] = [$('.crumb-current',domObject).attr('rel')];
								//}
							}else{
								$.voCnd.filterArray[groupName] = [];
							}
							$.voCnd.getResults();
						};
					/**
					 * filterResults turns group items on or off based on returned panelFilter data.
					 */
					this.filterResults =
						function( groupFilter )
						{
							//$.voMessage.debug(groupFilter);
							
/**/						// Hack: If results are filtered out, e.g. brand, then we need to remove them from query
							// and go get results again. This should be done on php side eventually
							var rerunResults = false;
							$('ul.cnd-list li', domObject).each(function(i, item){
								if($.inArray(parseInt($(item).attr('rel')), groupFilter) != -1){
									if(groupSettings.filterEffect == 'hide'){
										$(item).show();
									}else{
										$(item).removeClass('ui-state-disabled');
									}
								}else{
									if(groupSettings.filterEffect == 'hide'){
										$(item).hide();
									}else{
										$(item).addClass('ui-state-disabled');
									}
									
								// Remove filter ids
									/*if(groupSettings.dataFormatSingle){
										$.voCnd.filterArray[groupName] = 0;
									}else{*/
										if((clearCategoryId = $.inArray($(item).attr('rel'),$.voCnd.filterArray[groupName])) != -1){
											$.voCnd.filterArray[groupName].splice(clearCategoryId,1);
											rerunResults = true;
										}
									//}
										
								}
							});
							if(rerunResults){ $.voCnd.getResults(); }
						};
					
					this.formatMultiDimension =
						function( cid, data )
						{
							// Initialize cache and breadcrumb dom here
							if(typeof($.voCnd.hierarchyArray[groupName]) != 'object'){
								
								$.voCnd.hierarchyArray[groupName] = (data.panel[groupName]['array'] ? data.panel[groupName]['array'] : data.panel[groupName] ); // cache the hierarchy
								
								$('h3',domObject).append('<span class="crumb-parent" />');
								$('h3',domObject).append('<span class="crumb-current" />');
								
								// Events		
								
								// Current Category and Parent
								$('h3 span.crumb-parent',domObject).unbind('click').click(function(){
									/*if(groupSettings.dataFormatSingle){
										if($(this).attr('rel') > 0){
											$.voCnd.filterArray[groupName] = $(this).attr('rel');
										}else{
											$.voCnd.filterArray[groupName] = '';
										}
									}else{*/
										$.voCnd.filterArray[groupName] = [];
										if($(this).attr('rel') > 0){
											$.voCnd.filterArray[groupName].push($(this).attr('rel'));
										}
									//}
									
									$.voCnd.filterArray['page'] = 0;
									$(domObject).find('.cnd-button.cancel').hide();
									$.voCnd.getResults();
									thisGroup.formatMultiDimension( $(this).attr('rel') );
									return false;
								});
							}
							
							function getCategoryStructure(categoryArray, cid, parentObject)
							{
							// first level if there will be no parent object, the return category array
								
								if(typeof(cid) == 'undefined' || cid == 0 ){
									return {'parent':null,'categoryArray':{'children':categoryArray}};
								}else{
								// If cid is set then start looking for the id
									if(typeof(retVal) != 'object'){ var retVal = {}; };
									$.each(categoryArray, function(key, category){
										if( category.id == cid ){										
											parentObject = typeof(parentObject) == 'object' ? parentObject : null;
											
											// If this category has no children, then step back up the branch
											if($(category.children).length > 0){
												retVal = {'parent':parentObject,'categoryArray':category};
											}else{
												if(parentObject != null){
													retVal = {'parent':parentObject.parentObject,'categoryArray':parentObject};
												}else{
													retVal = {'parent':null,'categoryArray':{'children':categoryArray}};
												}
											}
											
											return false;
										}else{
											
											if( $(category.children).length > 0 && typeof(retVal.categoryArray) != 'object' ){
												var parent = category;
												parent.id = category.id;
												parent.parentObject = parentObject; // (parent's parent) allows for stepping back up the branch
												retVal = getCategoryStructure(category.children, cid, parent);
											}
										}
									});
									
									return retVal;
								}
							};
							
							var categoryStructure = getCategoryStructure($.voCnd.hierarchyArray[groupName],cid);
							
							var category = categoryStructure.categoryArray;
							var parent = categoryStructure.parent ? categoryStructure.parent : null;
							
								if(cid > 0){
									// $.voMessage.debug(category.name);
									if(category.name){
										$('h3 span.crumb-current',domObject).html('&gt; '+category.name).attr('rel',category.id).css('display','block');
									}
								}else{
									$('h3 span.crumb-current',domObject).empty().removeAttr('rel').hide();
								}
								
								if(parent){
									$('h3 span.crumb-parent',domObject).text(parent.name).attr('rel',parent.id);
								}else{
									
									$('h3 span.crumb-parent',domObject).text(groupSettings.displayName).attr('rel',0);
								}
								
								$('li',domObject).remove();
								if( category.children ){
									var fragment = document.createDocumentFragment();
									
									$.each(category.children, function(i,child){
						
										var newList = $('<li rel=\"'+child.id+'\" class="'+groupName+' ui-state-default">'+child.name+'</li>');
										
										//if(!groupSettings.dataFormatSingle){
											if($.inArray(child.id,$.voCnd.filterArray[groupName]) != -1){
												newList.addClass('ui-state-active');
												if(!groupSettings.dataFormatSingle){
													$(domObject).find('.cnd-button.cancel').show();
												}
											}
										/*}else{
											if(child.id == $.voCnd.filterArray[groupName]){
												newList.addClass('ui-state-active');
												$(domObject).find('.cnd-button.cancel').show();
											}
										}*/
										
										if($(child.children).length > 0 ){
											newList.click(function(){
											// If the single data format is set, then set the ajax data as a string rather than an array
												/*if(groupSettings.dataFormatSingle){
													$.voCnd.filterArray[groupName] = $(this).attr('rel');
												}else{*/
													$.voCnd.filterArray[groupName] = [];
													$.voCnd.filterArray[groupName].push($(this).attr('rel'));
												//}
												$.voCnd.filterArray['page'] = 0;
												//$.voMessage.debug($.voCnd.filterArray[groupName]);
												$.voCnd.getResults();
												thisGroup.formatMultiDimension($(this).attr('rel'));
												//
												$('.cnd-list li.ui-state-active',domObject).removeClass('ui-state-active');
												$('.cnd-list li[rel='+$(this).attr('rel')+']',domObject).unbind('hover').removeClass('ui-state-hover').addClass('ui-state-active');
												return false;
											});
										}else{
											// Removing the parent only matters on array formatted ajax data
											if(!groupSettings.dataFormatSingle){
												// !! Important, remove the parent id from the array.
												if((clearParent = $.inArray(category.id,$.voCnd.filterArray[groupName])) != -1){
													$.voCnd.filterArray[groupName].splice(clearParent,1);
												}
											}
											newList.click(thisGroup.itemClick);
										}
										fragment.appendChild( newList.get(0) );
									});
									
									$('.cnd-list', domObject).append( fragment );
								}
						};
						
					this.formatSingleDimension =
						function( data )
						{
							$('h3',domObject).prepend($('<span>'+groupSettings.displayName+'</span>'));
							
							var panelArray = (data.panel[groupName]['array'] ? data.panel[groupName]['array'] : data.panel[groupName] ); // Backward compat
							var fragment = document.createDocumentFragment();
							
							$.each(panelArray, function( liKey, liData ){
								var newList = $('<li rel=\"'+liKey+'\" class="'+groupName+' ui-state-default">'+liData.name+'</li>');
								$(newList).attr('rel',liKey);
								
								if(!groupSettings.dataFormatSingle){
									if($.inArray(liKey,$.voCnd.filterArray[groupName]) != -1){
										newList.addClass('ui-state-active');
										$(domObject).find('.cnd-button.cancel').show();
									}
								}
								$(newList).click( thisGroup.itemClick );
								fragment.appendChild( newList.get(0) );
							});
							
							$('.cnd-list',domObject).append( fragment );
						};
						
					return this;
				},
				
			'setInterface' :
				function(data, status)
				{
					$.voCnd.resultTotal = data.resultTotal;
					$.voCnd.setPagination();
					
				// Set panel dynamically from ajax feed
					$.each(data.panel, function(groupName, groupSettings){
						$.voCnd.setPanelGroup({
							'group':groupName,
							'displayName':groupSettings.display_name,
							'multiDimension':(groupSettings.multi_dimension ? groupSettings.multi_dimension : 0),
							'dataFormatSingle':(groupSettings.data_format_single ? 1 : 0),
							'filter':(groupSettings.filter_panel ? 1 : 0),
							'filterEffect':(groupSettings.filter_effect ? groupSettings.filter_effect : 'disable')
						});
					});
					
					// Set Each Panel Group
					var fragment = document.createDocumentFragment();
					$.each(data.panel, function(groupName){
						var groupSettings = $.voCnd.panelGroups[groupName];
					
						if( typeof($.voCnd.filterArray[groupName]) != 'object'){ 
							groupSettings.defaultValue = $.voCnd.filterArray[groupName] ? $.voCnd.filterArray[groupName] : [];
							$.voCnd.filterArray[groupName] = $.voCnd.filterArray[groupName] ? $.voCnd.filterArray[groupName] : []; 
						}
						/* else{
							groupSettings.defaultValue = $.voCnd.filterArray[groupName] ? $.voCnd.filterArray[groupName] : "";
							$.voCnd.filterArray[groupName] = $.voCnd.filterArray[groupName] ? $.voCnd.filterArray[groupName] : "";
						}*/
	
						object = $('<div id="cnd-'+ groupName +'" class="cnd-header" />');
						groupObject = new $.voCnd.group( object, groupName, groupSettings );

						$('li',object).remove();
						var collapseButton = $('<div class="ui-state-default ui-corner-all cnd-button collapse"><span class="ui-icon ui-icon-triangle-1-s" /></div>')
												.toggle(groupObject.menuClose, groupObject.menuOpen );
						var cancelButton = $('<div class="ui-state-default ui-corner-all cnd-button cancel"><span class="ui-icon ui-icon-cancel" /></div>')
												.hide()
												.bind('click',groupObject.reset);

						$('<h3 />')
							.addClass('ui-corner-all')
							//.text( groupSettings.displayName ) for now I am doing this in the singleDim and multiDim functions
							.appendTo(object)
							.append(cancelButton)
							.append(collapseButton);
						
						$('<ul class="cnd-list"></ul>').appendTo(object);
						
						// Load group's item list
						
						// Multi Dimensional
						if( groupSettings.multiDimension ){
							groupObject.formatMultiDimension((groupSettings.defaultValue ? groupSettings.defaultValue : 0), data);
							
						// Single Dimension
						}else{
							groupObject.formatSingleDimension( data );
						}
						
						if(typeof(data.panelFilter[groupName]) == 'object'){
							object.show();
							if(groupSettings.filter){
								groupObject.filterResults( data.panelFilter[groupName] );
							}
						}else{
							object.hide();
						}
						fragment.appendChild( object.get(0) );
					});
					$($.voCnd.settings.panel).empty().append(fragment);
					
					// Set Content
					if( $.voCnd.settings.initContent ){
						$.voCnd.setContent(data.content);
					}
					$('.waiting-for-results').hide();
					$($.voCnd.settings.contentDom).fadeIn('fast');
				},
			'waitingForResults' :
				function()
				{
					$($.voCnd.settings.contentDom).hide();
					$('.no-results').hide();
					$('.waiting-for-results').show();
				},
				
			'filterResults' :
				function( data )
				{
					$.voCnd.resultTotal = data.resultTotal;
					$.voCnd.setPaginationMessage();
					// Set Each Panel Group
					$.each($.voCnd.panelGroups, function(groupName, groupSettings){
						var groupObject = new $.voCnd.group( $('#cnd-'+ groupName), groupName, groupSettings );
						if(typeof(data.panelFilter[groupName]) == 'object'){
							$('#cnd-'+ groupName).show();
							if(groupSettings.filter){
								groupObject.filterResults( data.panelFilter[groupName] );
							}
						}else{
							$('#cnd-'+ groupName).hide();
						}
					});
					
					// Set Content
					$('.waiting-for-results').hide();
					// Slower but more flexible for interface developers
					if(data.content_html){
						$($.voCnd.settings.contentDom).replaceWith($(data.content_html).filter('ul'));
					}else{
					// Faster because unformatted Json data is sent and is formatted by javascript.
						$.voCnd.setContent(data.content);
					}
					//$($.voCnd.settings.contentDom).fadeIn('fast');
				},
				
			'setContent':
				function( content )
				{
				var thisObject = this;
					var $rowTemplate = $(thisObject.settings.contentDom).comments();
					$(thisObject.settings.contentDomRow,thisObject.settings.contentDom).remove();
					
					if($(content).length > 0 ){
						$('.no-results').hide();
						var fragment = document.createDocumentFragment();
						$.each(content, function(key, contentItem){
							// Set list display
								var $newRow = $rowTemplate.clone();
								$newRow.setDataDisplay( contentItem );
								$.voCnd.customContentFunction( key, contentItem, $newRow );
								fragment.appendChild($newRow.get(0));
						});
						
						$(thisObject.settings.contentDom).append( fragment );
						$($.voCnd.settings.contentDom).fadeIn('fast');
					}else{
						$('.no-results').show();
					}
				}
	};
	
	$.voSlugFormat = function( slug )
	{
		var newSlug = slug.replace(/[^a-zA-Z0-9\s\-]/g,'');
		newSlug = newSlug.trim().replace(/\s+/g,'-');
		return newSlug.toLowerCase();
	};
	
/* Non-Standard */
	$.fn.setRSSItemDisplay = function(jsonObject)
	{
		$('.title',this).text(jsonObject.title[0].Text);
		$('.link',this).attr('href',jsonObject.link[0].Text);
		$('.description',this).html(jsonObject.description[0].Text);
		
		//$(this).show();
		return this;
	};
	
	$.fn.setRSSChannelDisplay = function(jsonObject)
	{
		$('.title',this).text(jsonObject.title[0].Text);
		$('.link',this).attr('href',jsonObject.link[0].Text);
		$('.description',this).text(jsonObject.description[0].Text);
		//$('.image',this).attr('src',jsonObject.image[0].url[0].Text);
		
		//$(this).show();
		return this;
	};
	
	// Depends on jquery.XMLUtils.pack.js
	$.fn.XMLReader = function(callerSettings)
	{
		var settings = $.extend({
			feed: false,
			sortName: 'title',
			sortOrder: 'ASC',
			limit: false
		}, callerSettings || {});
		
		var object = this;
		var feed = settings.feed ? settings.feed : $(this).attr('data-feed');
		
		$.ajax({
			type: 'POST',
			url: 'xml',
			data:{feed:feed},
			dataType: 'xml', //Make sure that you specify the type of file you expecting (XML)
			complete: function(data) {
				// Grab the display template
				var feedChannelTemplate = $('.rss-channel',object).remove();
				var feedItemTemplate = $('.rss-items .template',object).remove();
				var json = $.xmlToJSON(data.responseXML); //Please notice that we use responseXML here which is DOMDocument object
				
				$(object).prepend($(feedChannelTemplate).setRSSChannelDisplay(json.channel[0]));
				
				// Now I want to sort all item nodes by their value
				json.channel[0].item.SortByNode(settings.sortName,settings.sortOrder); //Default order is ASC
				for(var i = 0; i < json.channel[0].item.length; i++) {
					var newList = $(feedItemTemplate).clone();
					$('.rss-items', object).append($(newList).setRSSItemDisplay(json.channel[0].item[i]));
				}
				
				if( settings.limit > 0 ){
					$('.rss-items li:gt('+ (settings.limit - 1) +')', object).hide();
				}
			}
		});
	};
	
	// Twitter Interface
	$.voTwitter = {
		'settings':
			{
				'controller':null,
				'panel':'#twitter-feed',
				'contentDom': '',
				'contentDomRow': '',
				'limit': 5
			},
			
		'init': function()
		{
			$.voAjax({
				'actionController': '/action/public/common/twitter',
				'dataObject':{'count':$.voTwitter.settings.limit},
				//'beforeSend':[$.voTwitter.waitingForResults],
				'success':[$.voTwitter.setInterface]
			});
		},

		'waitingForResults' : function()
		{
			
		},

		'setInterface' : function( data )
		{
			var $tweetPanel = $($.voTwitter.settings.panel+' ul');
			var $rowTemplate = $tweetPanel.comments();
				$tweetPanel.empty();
			
			if( !data.message ){
				var fragment = document.createDocumentFragment();
				$.each( data, function( key, tweet){
					$newRow = $rowTemplate.clone();
					$newRow.find('.text').html( tweet.text );
					$newRow.find('.created_at').html( tweet.created_at );
					fragment.appendChild( $newRow.get(0) );
				});
				$tweetPanel.append( fragment );
			}else{
				$tweetPanel.append('<li>'+data.message+'</li>');
			}

			
		},

		'ajaxComplete' : function()
		{

		}
	};
	
/* Deprecated */
	
	// Deprecated because setDataDisplay    
	$.fn.setAddressForm = function(addressObject)
	{
		$(this).attr('data-json','{id:' + addressObject.id + '}');
		$('input[name=full_name]',this).val(addressObject.full_name);
		$('input[name=address1]',this).val(addressObject.address1);
		$('input[name=address2]',this).val(addressObject.address2);
		$('input[name=city]',this).val(addressObject.city);
		$('input[name=state]',this).val(addressObject.state);
		$('input[name=zip]',this).val(addressObject.zip);
		$('input[name=phone]',this).val(addressObject.phone);
		
		addressObject.default_billing ? $('input[name=type_billing]').attr('checked','checked') : $('input[name=type_billing]').attr('checked','');
		addressObject.default_shipping ? $('input[name=type_shipping]').attr('checked','checked') : $('input[name=type_shipping]').attr('checked','');
		
		//addressObject.default_billing ? $('input[name=phone]',this)
		
		return this;
	};
	
})(jQuery);
	
// This assists file uploads. We can clean this up later
	var newStageImageTemplate; // For adding dom outside of ready function
	var voFile = {
		'settings':
			{
				'ulDom':''
			}
		,
		'addFileToDom':
			function( id, fileName )
			{
				var $newRow = typeof(newStageImageTemplate) == 'object' ? newStageImageTemplate.clone() : $(voFile.settings.ulDom).comments();
				$newRow.attr('id','loading'+id);
				$newRow.attr('class','loading');
				var $progressBar = $('<div class="progress-bar" />').progressbar({value:0});
				$newRow.append('<div class="loading-title">Loading '+ fileName +'</div>');
				$newRow.append($progressBar);
				$('img', $newRow).hide();
				
				$newRow.appendTo(voFile.settings.ulDom);
				needToSave = 1;
			}
		,
		'setProgressBar':
			function setProgressBar( id, percent )
			{
				$('#loading'+id+' .progress-bar').progressbar('option', 'value', percent);
			}
		,
		'loadThumbnail':
			function loadThumbnail( id, flashEvent )
			{
				$('#loading'+id+' .progress-bar').progressbar('destroy');
				$('.progress-bar, .loading-title',$('#loading'+id)).remove();
				// Load image here
				var data = $.evalJSON(flashEvent.data);
				voFile.setInterface( '#loading'+id, data );
				$('#loading'+id).attr('id','').removeClass('loading');
			}
		,
		'setInterface':
			function( loadingObject, data )
			{
				// Set externally 
			}		
	};

// END OF PLUGINS

// Body stuff

/*
Example DOM:
<ul id="n1">
	<li>Level 1
		<ul>
			<li>Level 2</li>
			<li>Level 2</li>
		</ul>
	</li>
	<li>Level 1</li>
</ul>

*/

$(document).ready(function(){
		
$("#main-navigation").navigationMenu();

	var nav1 = $('.dropdowns');
	var nav2 = $('li ul',nav1);

	function nav(level)
	{
		var nextLevel = $('li ul',level);
		$(nextLevel).hide()
			.siblings('a').addClass('button').removeAttr('href')
			.mouseover(function(){
				//$(nextLevel).not(':hidden').hide('slow');

				if($(this).siblings('ul').is(':hidden')){
					$(nextLevel).siblings('a').removeClass('buttonOver');
					$(this).addClass('buttonOver');

					$(nextLevel).slideUp('slow');
					$(this).siblings('ul').slideDown('slow');
				}else{
					$(nextLevel).siblings('a').removeClass('buttonOver');
					$(this).siblings('ul').slideUp('slow');
				}
			});
	}
	
	// Click Image Button
	$('#dialog-media-manager').dialog({
		'autoOpen':false,
		'bgiframe':true,
		'height':450,
		'width':960,
		'modal':true,
		'position':'top',
		'title':'Media Manager'
	});
	
// Forms
	$('label.hint').each(function(){
		
		var forField	= $(this).attr("for");
		var input		= $("input[name='"+forField+"']");
		var replaceMethod = $(this).is('.overlay') ? 'overlay' : 'value';
	
			switch( replaceMethod ){
			case 'overlay':
				var $label = $(this);
				var labelText	= $label.text();
				$(input).focus(function(){
					if($(input).val() == labelText){
						$(input).val('');
					}
					$label.css('text-indent','-10000px');
					
				}).blur(function(){
					if($(input).val() == ''){
						$label.css('text-indent','');
					}
				});
				if( input.val() ){
					$label.css('text-indent','-10000px');
				}
				$label.click(function(){ $(input).trigger('focus'); });
			break;
			
			case 'value':
				var labelText	= $(this).remove().text();
				if( $(input).val() == '' ){ $(input).addClass('placeholder').val(labelText); }
				
				$(input).focus(function(){
					if( this.value == labelText ){
						$(this).removeClass('placeholder').val('');
					}
				}).blur(function(){
					if( this.value == '' ){
						$(this).addClass('placeholder').val(labelText);
					}
				});
			break;
			}
		
	});
	
// Button Events (UI)
if($.isFunction($.fn.button)){
	$('button.gui-save').button({text:false,icons:{primary:'ui-icon-check'}});
	$('button.gui-cancel').button({text:false,icons:{primary:'ui-icon-cancel'}});
	$('button.gui-closethick,a.gui-closethick').button({text:false,icons:{primary:'ui-icon-closethick'}});
	$('button.gui-newwin, a.gui-newwin').button({text:false,icons:{primary:'ui-icon-newwin'}});
	$('button.gui-text').button();
	// To remove the focus state... seems to be a bug.
	$('button.gui-text').ajaxSuccess(function(){ $(this).removeClass('ui-state-focus').removeClass('ui-state-hover'); });
}

});
//Handle money formatting
function isThousands( position )
{
	if (Math.floor(position/3)*3==position) return true;
	return false;
};

function formatMoney (theNumber,theCurrency,theThousands,theDecimal)
{
	var theDecimalDigits = Math.round((theNumber*100)-(Math.floor(theNumber)*100));
	theDecimalDigits= ""+ (theDecimalDigits + "0").substring(0,2);
	theNumber = ""+Math.floor(theNumber);
	var theOutput = theCurrency;
	for (x=0; x<theNumber.length; x++) {
		theOutput += theNumber.substring(x,x+1);
		if (isThousands(theNumber.length-x-1) && (theNumber.length-x-1!=0)) {
			theOutput += theThousands;
		};
	};
	
	theOutput += theDecimal + theDecimalDigits;
	return theOutput;
};
