// RDJavascript.js
//
//	*** INSERT HEADER HERE ***
//
//  RDJavascript 1.5
//
// 	Adapted from RDJavascript 1.0 with additions from
//  'Advanced DOM Scripting' by Jefferey Sambells

(function(){
// BEGIN RDJavascript

if( !window.RDJ ) { window[ 'RDJ' ] = {}}

// RDJ.$
//
// A replacement for RDJ.$()
// return the DOM element specified, either by ID or by
// reference
function $() {
	var elements = new Array();
	
	for( var i = 0; i < arguments.length; i++ ) {
		// Grab an argument from the list
		var element = arguments[ i ];
		
		// If the argument is a string, get the object associated
		// with it
		if( typeof element == 'string' ) {
			if( document.getElementById ) {
				element = document.getElementById( element );
			} else if( document.all ) {
				element = document.all[ element ];
			} else if( document.layers ) {
				element = document.layers[ element ];
			}
		}
		
		// If there was only one argument, we're done. Return.
		if( arguments.length == 1 )
			return element;
			
		// If not, add it to the array
		elements.push( element );
	}
	
	return elements;
};
window[ 'RDJ' ][ '$' ] = $;

// RDJ.bindFunction( obj, func )
// Apply a particular function using obj as 'this'

function bindFunction( obj, func ) {
	return function() { func.apply( obj, arguments ); }
};
window[ 'RDJ' ][ 'bindFunction' ] = bindFunction;


// RDLogger

// RDJ.logger( id )
// Constructor for the Logger object

function logger( id ) {
	id = id || 'RDLogWindow';
	var logWindow = null;
	
	var createWindow = function( msg ) {
		var size = RDS.getBrowserWindowSize();
		var top = ( ( size.height - 200 ) / 2 ) || 0;
		var left = ( ( size.width - 200 ) / 2 ) || 0;
		
		logWindow = RDCreateElement( 'ul' );
		logWindow.setAttribute( 'id', id );
		
		logWindow.style.position = 'absolute';
		logWindow.style.top = top + 'px';
		logWindow.style.left = left + 'px';
		
		logWindow.style.width = '200px';
		logWindow.style.height = '200px';
		logWindow.style.overflow = 'scroll';
		
		logWindow.style.padding = '0';
		logWindow.style.margin = '0';
		logWindow.style.border = '1px solid black';
		logWindow.style.backgroundColor = 'white';
		logWindow.style.listStyle = 'none';
		logWindow.style.font = '10pt/10pt Verdana, Tahoma, Sans';
		
		document.body.appendChild( logWindow );
	};
	
	this.writeRaw = function( msg ) {
		if( !logWindow ) createWindow();
		
		var li = RDCreateElement( 'li' );
		li.style.padding = '2px';
		li.style.border = '0';
		li.style.borderBottom = '1px dotted black';
		li.stylemargin = '0';
		li.style.color = '#000';
		li.style.font = '9pt/9pt Verdana, Tahoma, Sans';
		
		if( typeof msg == 'undefined' ) {
			li.appendChild( document.createTextNode( 'Message was undefined!' ) );
		} else if( typeof li.innerHTML != undefined ) {
			li.innerHTML = msg;
		} else {
			li.appendChild( document.createTextNode( msg ) );
		}
		
		logWindow.appendChild( li );
		
		return true;
	};
}
window[ 'RDJ' ][ 'logger' ] = new logger();

logger.prototype = {
	write: function ( msg ) {
		if( typeof msg == 'string' && msg.length == 0 ) {
			return this.writeRaw( 'RDJ.logger: null message' );
		}
		
		if( typeof msg != 'string' ) {
			if( msg.toString ) 
				return this.writeRaw( msg.toString() );
			else
				return this.writeRaw( typeof msg );
		}
		
		msg = msg.replace( /</g, "&lt;" ).replace( />/g, "&gt;" );
	},
	
	header: function( msg ) {
		msg = '<span style="color: white; background-color: black; font-weight: bold; padding: 0px 5px;">' + msg + '</span>';
		
		return this.writeRaw( msg );
	},
	
	link: function( msg ) {}};

// RDDOM

function walkElementsLinear( func, node ) {
	var root = node || window.document;
	var nodes = root.getElementsByTagName( '*' );
	
	for( var i = 0; i < nodes.length; i++ )
		func.call( nodes[ i ] );
}

function walkTheDOM( node, func ) {
	func( node );
	node = node.firstChild;
	
	while( node ) {
		walkTheDOM( node, func );
		node = node.nextSibling;
	}
}

function walkTheDOMRecursive( func, node, depth, returnedFromParent ) {
	var root = node || window.document;
	var returnedFromParent = func.call( root, depth++, returnedFromParent );
	var node = root.firstChild;
	
	while( node ) {
		walkTheDOMRecursive( func, root.childNodes[ i ], depth, returnedFromParent );
		node = node.nextSibling
	}
}

function walkTheDOMWithAttributes( node, func, depth, returnedFromParent ) {
	var root = node || window.document;
	var returnedFromParent = func( root, depth++, prefix );
	
	if( root.attributes )
		for( var i = 0; i < root.attributes.length; i++ )
			walkTheDOMWithAttributes( root.attributes[ i ], func, depth - 1, returnedFromParent );
	
	if( root.nodeType != Node.ATTRIBUTE_NODE ) {
		var node = root.firstChild;
		
		while( node ) {
			walkTheDOMWithAttributes( node, func, depth, returnedFromParent );
			node = node.nextSibling;
		}
	}
}

// RDBrowser

function getBrowserWindowSize() {
	var de = document.documentElement;
	
	return {
		'width': ( window.innerWidth || ( de && de.clientWidth ) || document.body.clientWidth ),
		'height': ( window.innerHeight || ( de && de.clientHeight ) || document.body.clientHeight )
	}
};
window[ 'RDJ' ][ 'getBrowserWindowSize' ] = getBrowserWindowSize;

// RDJ.isCompatible()
// Check to see if the browser is compatible with
// this version of the library.
function isCompatible( other ) {
	if( 
		other === false
		|| !Array.prototype.push
		|| !Object.hasOwnProperty
		|| !document.createElement
		|| !document.getElementsByTagName
	) return false;
	
	return true;

};
window[ 'RDJ' ][ 'isCompatible' ] = isCompatible;

// RDJ.isIE6()
// Check to see if the browser is IE6.
function isIE6() {
	var arVersion = navigator.appVersion.split( "MSIE" );
	var version = parseFloat( arVersion[ 1 ] );
	
	if( ( version >= 5.5 ) && ( version < 7 ) )
		return true;
	else
		return false;
};
window[ 'RDJ' ][ 'isIE6' ] = isIE6;

// RDJ.bindFunction( obj, func )
// Change the call scope
function bindFunction( obj, func ) {
	return function() { func.apply( obj, arguments ); };
}

// RDEvent

// RDJ.attachEvent( node, type, listener )
// Attach an event handler to a DOM Object
// node: the element to listen for events
// type: the event to listen for
// listener: a function reference. This function is called when the event fires.
function attachEvent( node, type, listener ) {
	if( !isCompatible() ) return false;
	
	if( node.addEventListener ) { // W3C
		node.addEventListener( type, listener, false );
		return true;
	}
	
	if( node.attachEvent ) { // MSIE
		node[ 'e' + type + listener ] = listener;
		node[ type + listener ] = function() {
			node[ 'e' + type + listener ]( window.event );
		}
		node.attachEvent( 'on' + type, node[ type + listener ] );
		return true;
	}
	
	return false;
};
window[ 'RDJ' ][ 'attachEvent' ] = attachEvent;

// RDJ.removeEvent( node, type, listener )
// Remove an event handler from a DOM Object
function removeEvent( node, type, listener ) {
	if( !( node = $( node ) ) ) return false;
	
	if( node.removeEventListener ) { // W3C
		node.removeEventListener( type, listener, false );
		return true;
	}
	
	if( node.detachEvent ) { // MSIE
		node.detachEvent( 'on' + type, node[ type + listener ] );
		node[ type + listener ] = null;
		return true;
	}
	
	return false;
};
window[ 'RDJ' ][ 'removeEvent' ] = removeEvent;

// RDJ.getEventObject
// Always retrieve the correct event from the DOM
function getEventObject( theEvent ) {
	return theEvent || window.event;
};
window[ 'RDJ' ][ 'getEventObject' ] = getEventObject;

// RDJ.preventEventDefault
// Ignore the default event handler when firing an event
function preventEventDefault( event ) {};
window[ 'RDJ' ][ 'preventEventDefault' ] = preventEventDefault;

// RDDOM

// RDJ.getElementsByClassName( className, tag, parent )
// Return all elements with a given className and tag
// that are children of the given parent element.
function getElementsByClassName( className, tag, parent ) {
	parent = parent || document; // Use document if parent is undefined
	if( !( parent = $( parent ) ) ) return false;
	
	var tags = ( tag == "*" && parent.all ) ? parent.all : parent.getElementsByTagName( tag );
	var matches = new Array();
	
	className = className.replace( /\-/g, "\\-" );
	var regex = new RegExp( "(^|\\s)" + className + "(\\s|$)" );
	
	var element;
	for( var i = 0; i < tags.length; i++ ) {
		element = tags[ i ];
		if( regex.test( element.className ) ) matches.push( element );
	}
	
	return matches;
};
window[ 'RDJ' ][ 'getElementsByClassName' ] = getElementsByClassName;

// RDJ.insertAfter( node, refNode )
// Append a node to the DOM tree after the given reference node
function insertAfter( node, refNode ) {
	if( !( node = $( node ) ) ) return false;
	
	if( !( refNode = $( refNode ) ) ) return false;
	
	return refNode.parentNode.insertBefore( node, refNode.nextSibling );
};
window[ 'RDJ' ][ 'insertAfter' ] = insertAfter;

// RDJ.removeChildren( parent )
// Remove all children from the specified parent node.
function removeChildren( parent ) {
	if( !( parent = $( parent ) ) ) return false;
	
	while( parent.firstChild )
		parent.firstChild.parentNode.removeChild( parent.firstChild );
		
	return parent;
};
window[ 'RDJ' ][ 'removeChildren' ] = removeChildren;

// RDJ.prependChild( parent, child )
// Insert a new child under the parent, before any existing children
function prependChild( parent, child ) {
	if( !( parent = $( parent ) ) ) return false;
	
	if( !( child = $( child ) ) ) return false;
	
	if( parent.firstChild )
		parent.insertBefore( child, parent.firstChild );
	else
		parent.appendChild( child );
		
	return parent;
};
window[ 'RDJ' ][ 'prependChild' ] = prependChild;

// RDElement

// RDJ.Element.enable
// Enable the listed elements
var Element = {
	// Check if the element in question is an array
	isArray: function( input ) {
		if( input == undefined )
			return false;
			
		return input.constructor == Array;
	},
	
	enable: function( input ) {
		if( input == undefined )
			return false;
			
		if( !RDJ.Element.isArray( input ) ) {
			if( !( input = $( input ) ) ) return false;
			input.disabled = false;
		} else {
			for( i in input ) {
				if( !( input[ i ] = $( input[ i ] ) ) ) continue;
				input[ i ].disabled = false;
			}
		}
		
		return true;
	},
	
	disable: function( input ) {
		if( input == undefined )
			return false;
			
		if( !RDJ.Element.isArray( input ) ) {
			if( !( input = $( input ) ) ) return false;
			input.disabled = true;
		} else {
			for( i in input ) {
				if( !( input[ i ] = $( input[ i ] ) ) ) continue;
				input[ i ].disabled = true;
			}
		}
		
		return true;
	}
};
window[ 'RDJ' ][ 'Element' ] = Element;

// RDJ.toggleDisplay( node, value )
// Toggle the element's runtime display
function toggleDisplay( node, value ) {
	if( !( node = $( node ) ) ) return false;
	
	node.style.display = ( node.style.display != 'none' ) ? 'none' : ( value || '' );
	
	return true;
};
window[ 'RDJ' ][ 'toggleDisplay' ] = toggleDisplay;

function getWindowSize() {
	var size = new Array();
	
	
	if (self.innerHeight) {	// all except Explorer
		size[ 'w' ] = self.innerWidth;
		size[ 'h' ] = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		size[ 'w' ] = document.documentElement.clientWidth;
		size[ 'h' ] = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		size[ 'w' ] = document.body.clientWidth;
		size[ 'h' ] = document.body.clientHeight;
	}
	
	window.scrollBarSize = RDJ.getScrollBarSize();
	
	return size;
};
window[ 'RDJ' ][ 'getWindowSize' ] = getWindowSize;

function getPageSize() {
	var xScroll, yScroll;
	
	if( window != undefined && window.innerHeight != undefined && window.scrollMaxY != undefined ) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if( document.body.scrollHeight > document.body.offsetHeight ) { // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var window = getWindowSize();
	var page = new Array();	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < window[ 'h' ] ){
		page[ 'h' ] = window[ 'h' ];
	} else { 
		page[ 'h' ] = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < window[ 'w' ] ){	
		page[ 'w' ] = window[ 'w' ];
	} else {
		page[ 'w' ] = xScroll;
	}
	
	return page;
};
window[ 'RDJ' ][ 'getPageSize' ] = getPageSize;

function getSize( element ) {
	if( !( element = $( element ) ) ) return false;
	
	var size = new Array();
	
	size[ 'w' ] = element.offsetWidth;
	size[ 'h' ] = element.offsetHeight;
	
	return size;
	
};
window[ 'RDJ' ][ 'getSize' ] = getSize;

function setSize( element, w, h ) {
	if( !( element = $( element ) ) ) return false;
	
	if( w != undefined ) element.style.width = w + 'px';
	if( h != undefined ) element.style.height = h + 'px';
};
window[ 'RDJ' ][ 'setSize' ] = setSize;

// Get scrollbar width/height
function getScrollBarSize() {
	var i = RDJ.createElement( 'p' );
	i.style.width = '100%';
	i.style.height = '100%';
	
	var o = RDJ.createElement( 'div' );
	o.style.position = 'absolute';
	o.style.top = '0px';
	o.style.left = '0px';
	o.style.visibility = 'hidden';
	o.style.width = '200px';
	o.style.height = '150px';
	o.style.overflow = 'hidden';
	o.appendChild( i );
	
	document.body.appendChild( o );
	var w1 = i.offsetWidth;
	var h1 = i.offsetHeight;
	o.style.overflow = 'scroll';
	var w2 = i.offsetWidth;
	var h2 = i.offsetHeight;
	if( w1 == w2 ) w2 = o.clientWidth;
	if( h1 == h2 ) h2 = o.clientWidth;
	
	document.body.removeChild( o );
	
	var size = new Array();
	size[ 'w' ] = w1 - w2;
	size[ 'h' ] = h1 - h2;
	
	return size;
}
window[ 'RDJ' ][ 'getScrollBarSize' ] = getScrollBarSize;
if( !RDJ.isIE6() ) RDJ.attachEvent( window, 'load', function() { window.scrollBarSize = RDJ.getScrollBarSize(); } );

// RDImage
// Fix PNG Files
// From http://homepage.ntlworld.com/bobosola/pngfix_map.js

function fixPNG() {
	function findImgInputs( oParent ) {
		var oChildren = oParent.children
		if( oChildren ) {
		  for (var i=0; i < oChildren.length; i++ ) {
		     var oChild = oChildren( i );
		     if( ( oChild.type == 'image' ) && ( oChild.src ) ) {
		         var origSrc = oChild.src;
		         oChild.src = strGif;
		         oChild.style.filter = strFilter + "(src='" + origSrc + "')";
		     }
		     findImgInputs( oChild );
		  }
		}
	}

	var strGif = "/images/site/transparent";
	var strFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader";
	var arVersion = navigator.appVersion.split( "MSIE" );
	var version = parseFloat( arVersion[ 1 ] );
	
	if( RDIsIE6() && ( document.body.filters ) ) {
		for( var i=0; i < document.images.length; i++ ) {
		   var img = document.images[ i ];
		   var imgName = img.src.toUpperCase();
		   if( imgName.substring( imgName.length - 3, imgName.length ) == "PNG" ) {
			  var imgID = ( img.id ) ? "id='" + img.id + "' " : "";
			  var imgClass = ( img.className ) ? "class='" + img.className + "' " : "";
			  var imgTitle = ( img.title ) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
			  var imgStyle = "display:inline-block;" + img.style.cssText;
			  if( img.align == "left" ) imgStyle = "float:left;" + imgStyle;
			  if( img.align == "right" ) imgStyle = "float:right;" + imgStyle;
			  if( img.parentElement.href ) imgStyle = "cursor:hand;" + imgStyle;
			  if( img.useMap )  {  
				 strAddMap = "<img style=\"position:relative; top: -" + img.height + "px; "
				 + "height:" + img.height + "px; width:" + img.width +"\"; "
				 + "src=\"" + strGif + "\" usemap=\"" + img.useMap 
				 + "\" border=\"1px solid black;\">";
				 //+ "\" border=\"1px solid b" + img.border + "\">";
			  }
			  var strNewHTML = "<span " + imgID + imgClass + imgTitle
			  + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
			  + "filter:" + strFilter
			  + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>";
			  if( img.useMap ) strNewHTML += strAddMap;
			  img.outerHTML = strNewHTML;
			  i--;
		   }
		}
	
	   for( i=0; i < document.forms.length; i++ ) findImgInputs( document.forms( i ) );
	}
};
window[ 'RDJ' ][ 'fixPNG' ] = fixPNG;

// fixHR()
//
// Fix IE6's horrible implementation of styled HRs
function fixHR() {
	//if( !isIE6() ) return;
	
	var els = document.getElementsByTagName( 'hr' );
	for( var i = 0; i < els.length; i++ ) {
		var hr = els[ i ];
		var div = RDCreateElement( 'div' );
		div.style.backgroundImage = hr.style.backgroundImage;
		div.style.width = hr.offsetWidth;
		div.style.height = hr.offsetHeight;
		hr.parentNode.replaceChild( div, hr );
	}
};
window[ 'RDJ' ][ 'fixHR' ] = fixHR;

// RDJ.confirmAction( action, target, undo )
// Confirm that the user wants to perform the selected action on the selected object,
// telling the user if the action can be undone

function confirmAction( action, target, undo ) {
	if( typeof( action ) == 'undefined' || action == '' ) action = 'do';
    if( typeof( target ) == 'undefined' || target == '' ) target = '';
    if( typeof( undo ) == 'undefined' || undo < 0 || undo > 1 ) undo = 0;
    
    var str = 'Are you sure you want to ' + action + ' this';
    if( target != '' )
        str = str + ' ' + target + '?';
    else
        str = str + '?';
        
    if( !undo )
        str = str + '\nThis action cannot be undone.';

    return confirm( str );
};
window[ 'RDJ' ][ 'confirmAction' ] = confirmAction;

// RDDateFunctions

// RDJ.incrementDate( date, count, unit )
// Return a new date offset by the supplied date by the specified number of units

function incrementDate( date, count, unit ) {
	var d2 = new Date();
	var offset = 0;
	switch( unit ) {
		case 'second':
			offset = count;
			break;
		case 'minute':
			offset = count * 60;
			break;
		case 'hour':
			offset = count * 3600;
			break;
		case 'week':
			offset = count * 604800000;
			break;
		case 'month':
			
			break;
		case 'year':
			
			break;
		case 'day':
		default:
			offset = ( count * 86400000 );
	}
	
	d2.setTime( date.getTime() + offset );
	
	return d2;
};
window[ 'RDJ' ][ 'incrementDate' ] = incrementDate;

function isValidDate( date ) {
	var objRegExp = /^\d{1,2}(\-)\d{1,2}\1\d{4}$/;
	return objRegExp.test( date );
};
window[ 'RDJ' ][ 'isValidDate' ] = isValidDate;

function isValidTime( value ) { // Deprecated. Use RDJ.Validator.isTime() instead
   return RDJ.Validator.isTime( value, false );
};
window[ 'RDJ' ][ 'isValidTime' ] = isValidTime;

function isValidEmail( value ) { // Deprecated. Use RDJ.Validator.isEmail() instead.
	return RDJ.Validator.isEmail( value, false );
};
window[ 'RDJ' ][ 'isValidEmail' ] = isValidEmail;

// RDJ.Validator
Validator = {
	isNull: function( value ) {
		return ( value == undefined || value === null || value === '' );
	},
	
	isURL: function( value, ajax ) {
		// Do nothing if empty
		if( RDJ.Validator.isNull( value ) )
			return false;
			
		var ok = false;
		var regex = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/;
		ok = regex.test( value );
		
		if( ok && ajax === true ) { // Test to see if url is reachable
		
		}
		
		return ok;
	},
	
	isEmail: function( value, ajax, url, options ) {
		// Do nothing if value is empty
		if( RDJ.Validator.isNull( value ) )
			return false;
			
		var ok = false;
		var regex = /^[a-zA-Z]+([_\.-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([\.-]?[a-zA-Z0-9]+)*(\.[a-zA-Z]{2,4})+$/;
		ok = regex.test( value );
		
		if( ok && ajax === true ) { // Test via server
			ok = ( !RDJ.Validator.isNull( url ) );
			
			RDJ.ajaxRequestQueue( url, options, 'email-queue' );
			//req.send( options.send );
			
			// Set to false while script is running
			// This value should be set by the proper completionHandler.
			ok = false;
		}
		
		return ok;
	},
	
	isTime: function( value, ajax ) {
		// Do nothing if value is empty
		if( value == undefined && value == '' )
			return false;
			
		var hasMeridian = false;
   		var regex = /^\d{1,2}[:]\d{2}([:]\d{2})?( [aApP][mM]?)?$/;
   		ok = regex.test( value );
   		if( ok ) {
   			hasMeridian = ( value.toLowerCase().indexOf("p") != -1 ) ? true : false;
   			hasMeridian = ( value.toLowerCase().indexOf("a") != -1 ) ? true : false;
   			
   			// Get hour::minute
   			var values = value.split( ":" );
   			var hour = parseInt( values[ 0 ] );
   			var minute = parseInt( values[ 1 ] );
   			var second = ( values.length > 2 ) ? parseInt( values[ 2 ] ) : 0;
   			
   			// Check Hours
   			ok = ( ( hour >= 0 ) && ( hour <= 23 ) ) ? true : false;
   			if( ok && hasMeridian )
   				ok = ( ( hour >= 1 ) && ( hour <= 12 ) )? true : false;
   			
   			// Check Minutes
   			if( ok )
   				ok = ( ( minute >= 0 ) && ( minute <= 59 ) ) ? true : false;
   				
   			// Check Seconds
   			if( ok )
   				ok = ( ( second >= 0 ) && ( second <= 59 ) ) ? true : false;
   		}
   			
   		return ok;
	},
	
	isUSZip: function( value ) {
		try{
			var regex = /^\d{5}([\-]\d{4})?$/;
			return regex.test( value );
		} catch( ex ) { return false; }
	},
	
	isUSPhone: function( value ) {
		try{
			var regex = /^\(?[2-9]\d{2}[\)-]?\s?\d{3}[\s-]?\d{4}$/;
			return regex.test( value );
		} catch( ex ) { return false; }
	},
	
	isNumeric: function( value ) {
		try{
			var regex = /^[0-9]?$/;
			return regex.test( value );
		} catch( ex ) { return false; }
	},
	
	isAlphaNumeric: function( value ) {
	
	},
	
	isAddress: function( value, ajax ) {
		if( value == '' )	// Do nothing if address is empty
			return false;
			
		var ok = false;	
	}
};
window[ 'RDJ' ][ 'Validator' ] = Validator;

Formatter = {
	toUSPhone: function( str ) {		
		var regex = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
		
		if( regex.test( str ) )
			return str.replace( regex, "($1) $2-$3" );
		
		return false;
	}
};
window[ 'RDJ' ][ 'Formatter' ] = Formatter;

Link = {
	fixExternal: function() {
		if( !document.getElementsByTagName ) return;   
		 var anchors = document.getElementsByTagName("a");   
		 for( i = 0; i < anchors.length; ++i ) {   
		   var anchor = anchors[i];   
		   if( anchor.href && anchor.rel == "external" )   
		     setAttribute( anchor, 'target', '_blank' ); 
		 }
	}
};
window[ 'RDJ' ][ 'Link' ] = Link;
RDJ.attachEvent( window, 'load', RDJ.Link.fixExternal );

// RDElement
//
// A class for quickly creating DOM elements
// Inspired by Javascript: The Definitive Guide, 5th Edition,
// and the MochiKit library (http://mochikit.com) by Bob Ippolito

// Create an element from a tag, accepting 1, 2, or three arguments
function createElement( tag, attrs, children ) {
	function _RDMakeElement( tag, name ) {
		var element = null;
		if( name == undefined ) name = '';
		
		
		// Try W3C dom first
		if( typeof document.createElementNS != 'undefined' ) {
			element = document.createElementNS( 'http://www.w3.org/1999/xhtml', tag );
		} else {
			// Next, try old IE
			try { 
				if( name != '' )
					element = document.createElement( '<' + tag + ' name=\"' + name +'\">' );
				else
					element = document.createElement( '<' + tag + '>' );
			} catch( e ) {}
			
			// Third, try everything else
			if( element == null || element.nodeName != tag.toUpperCase() )
				element = document.createElement( tag );
		}
		
		if( name != '' )
			setAttribute( element, 'name', name );
		
		return element;
	}
	
	function _RDPrototypeElement( tag ) {
		return function( attrs, children ) {
			if( arguments.length == 1 )
				return createElement( tag, attrs );
			else
				return createElement( tag, attrs, children );
		}
	}

	if( arguments.length == 2 && ( attrs instanceof Array || typeof attrs == "string" ) ) {
		children = attrs;
		attrs = null;
	}
	
	var e = null;
	
	if( attrs && attrs[ 'name' ] )
		e = _RDMakeElement( tag, attrs[ 'name' ] );
	else
		e = _RDMakeElement( tag );
	
	if( attrs )
		for( var name in attrs ) RDJ.setAttribute( e, name, attrs[ name ] );
				
	if( children != null ) {
		if( children instanceof Array ) {
			for( var i = 0; i < children.length; i++ ) {
				var child = children[ i ];
				if( typeof child == "string" ) {
					child = document.createTextNode( child );
				}
				e.appendChild( child );
			}
		} else if ( typeof children == "string" ) {
			e.appendChild( document.createTextNode( children ) );
		} else {
			e.appendChild( children );
		}
	}
	
	return e;
};
window[ 'RDJ' ][ 'createElement' ] = createElement;

// Create element attributes
function setAttribute( elem, attr, val ) {
	if( document.createAttribute != undefined ) {
		theAttribute = document.createAttribute( attr );
		theAttribute.value = val;
		elem.setAttributeNode( theAttribute );
	} else {
		elem.setAttribute( attr, val );
	}
};
window[ 'RDJ' ][ 'setAttribute' ] = setAttribute;

// RDJ.getFileName( elem )
// Get file name from upload element
function getFileName( elem ) {
	var str = '';
	
	elem = RDJ.$( elem );
	if( elem.type == 'file' ) {
		str = elem.value;
		if( str.indexOf( '/' > -1 ) ) 
			str = str.substring( str.lastIndexOf( '/' ) + 1, str.length );
		else
			str = str.substring( str.lastIndexOf( '\\' ) + 1, str.length );
	}
	
	return str;
};
window[ 'RDJ' ][ 'getFileName' ] = getFileName;

// RDJ.rand( n )
// Return a random integer between 1 and n
function rand( n ) {
	return ( Math.floor( Math.random ( ) * n + 1 ) );
}
window[ 'RDJ' ][ 'rand' ] = rand;

// RDSocialNetworking
function shareOnFacebook( u, t ) {
	var target = 'http://www.facebook.com/sharer.php?u=' + encodeURIComponent( u ) + '&t=' + encodeURIComponent( t );
	window.open( target, 'sharer', 'toolbar=0,status=0,width=626,height=436' );
	
	return false;
}
window[ 'RDJ' ][ 'shareOnFacebook' ] = shareOnFacebook;

function shareOnMyspace( t, c, u, l ) {
	var target = 'http://www.myspace.com/index.cfm?fuseaction=postto&' + 't=' + encodeURIComponent( t ) + '&c=' + encodeURIComponent( c ) + '&u=' + encodeURIComponent( u ) + '&l=' + l;
	window.open( target, 'sharer', 'toolbar=0,status=0,width=626,height=436' );
	
	return false;
}
window[ 'RDJ' ][ 'shareOnMyspace' ] = shareOnMyspace;

// RDURLEncode
function urlEncode( str ) {
	return escape(str).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
};
window[ 'RDJ' ][ 'urlEncode' ] = urlEncode;

// RDGoogleMapLink
var gmURL = 'http://maps.google.com?q=';

function googleMapLink( addr, city, state, zip ) {
	addr = ( addr != undefined ) ? addr : '';
	city = ( city != undefined ) ? city : '';
	state = ( state != undefined ) ? state : '';
	zip = ( zip != undefined ) ? zip : '';
	
	return urlEncode( gmURL + addr + ', ' + city + ' ' + state + ' ' + zip );
};
window[ 'RDJ' ][ 'googleMapLink' ] = googleMapLink;

// RDCookie
function writeCookie( key, value, expire ) {
	var expires = "";
	if( expire ) {
		var date = new Date();
		date.setTime( date.getTime() + ( expire * 24 * 60 * 60 * 1000 ) );
		expires = "; expires="+date.toGMTString();
	}
		
	document.cookie = key+"="+value+expires+"; path=/";
}
window[ 'RDJ' ][ 'writeCookie' ] = writeCookie;

function readCookie( key ) {
	key += "=";
	var ca = document.cookie.split(';');
	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( key ) == 0 ) return c.substring( key.length, c.length );
	}
	return null;
}
window[ 'RDJ' ][ 'readCookie' ] = readCookie;

function deleteCookie( key ) { 
	writeCookie( key, "", -1 );
}
window[ 'RDJ' ][ 'deleteCookie' ] = deleteCookie;


// AJAX
function parseJSON( s, filter ) {
	var j;
	
	function walk( k, v ) {
		var i;
		if( v && typeof v === 'object' )
			for( i in v )
				if( v.hasOwnProperty( i ) )
					v[ i ].walk( i, v[ i ] );
		return filter( k, v );
	}
	
	var pattern = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/
	if( pattern.test( s ) ) {
		try {
			j = eval( '(' + s + ')' );
		} catch( e ) {
			throw new SyntaxError( 'parseJSON' );
		}
	} else {
		throw new SyntaxError( 'parseJSON' );
	}
	
	if( typeof filter === 'function' )
		j = walk( '', j );
		
	return j;
};
window[ 'RDJ' ][ 'parseJSON' ] = parseJSON;

function getRequestObject( url, options ) {
	// Create the request object
	var req = false;
	if( window.XMLHttpRequest ) {
		var req = new window.XMLHttpRequest();
	} else if( window.ActiveXObject ) {
		var req = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
	}
	
	if( !req ) return false; // Request object undefined
	
	// Get the default options
	options = options || {};
	options.method = options.method || 'POST';
	options.send = options.send || null;
	options.enctype = options.enctype || 'application/x-www-form-urlencoded';
	
	result = {
		status: true,
		text: ''
	};
	
	req.result = result;
	
	// Define the event listeners
	req.onreadystatechange = function() {
		switch( req.readyState ) {
			case 1: // Loading
				if( options.loadListener )
					options.loadListener.apply( req, arguments );
				break;
			case 2: // Loaded
				if( options.loadedListener )
					options.loadedListener.apply( req, arguments );
				break;
			case 3: // Interactive
				if( options.interactiveListener )
					options.interactiveListener.apply( req, arguments );
				break;
			case 4: // Complete
				try {
					if( req.status && req.status == 200 ) {
						var contentType = req.getResponseHeader( 'Content-Type' );
						var mimeType = contentType.match( /\s*([^;]+)\s*(;|$)/i )[ 1 ];
						switch( mimeType ) {
							case 'text/javascript':
							case 'application/javascript':
								if( options.jsResponseListener )
									options.jsResponseListener.call( req, req.responseText );
								break;
							case 'application/json':
								if( options.jsonResponseListener ) {
									try {
										var json = parseJSON( req.responseText );
									} catch( e ) {
										var json = false;
									}
									options.jsonResponseListener.call( req, json );
								}
								break;
							case 'text/xml':
							case 'application/xml':
							case 'application/xhtml+xml':
								if( options.xmlResponseListener )
									options.xmlResponseListener.call( req, req.responseXML );
								break;
							case 'text/html':
							case 'text/plain':
								if( options.htmlResponseListener )
									options.htmlResponseListener.call( req, req.responseText );
								break;
							default:
								alert( 'Invalid mime type (' + mimeType + ') returned!' );
						}
						
						if( options.completeListener )
							options.completeListener.apply( req, arguments );
					} else { // completed with error
						if( options.errorListener )
							options.errorListener.apply( req, arguments );
					}
				} catch( e ) {
					alert( 'An unexpected error occurred with your request. (' + e.name + ') ' + e.message );
				}
				break;
		
		}
	};
	
	// Open the request
	req.open( options.method, url, true );
	req.setRequestHeader( 'Content-Type', options.enctype );
	req.setRequestHeader( 'X-RDJ-AJAX-Request', 'AjaxRequest' ); // AJAX identifier
	
	return req;
};
window[ 'RDJ' ][ 'getRequestObject' ] = getRequestObject;

function ajaxRequest( url, options ) {
	var req = getRequestObject( url, options );
	return req.send( options.send );
};
window[ 'RDJ' ][ 'ajaxRequest' ] = ajaxRequest;

function clone( obj ) {
	if( typeof( obj ) != 'object' )
		return obj;
		
	if( obj == null )
		return obj;
		
	var obj2 = new Object();
	for( var i in obj )
		obj2[ i ] = clone( obj[ i ] );
		
	return obj2;
}

window[ 'RDJ' ][ 'requestQueue' ] = [];

function ajaxRequestQueue( url, options, queue ) {
	queue = queue || 'default';
	
	options = clone( options ) || {};
	if( !RDJ.requestQueue[ queue ] ) RDJ.requestQueue[ queue ] = [];
	
	// Grab and add a new complete listener to the queue
	var userCompleteListener = options.completeListener;
	options.completeListener = function() {
		if( userCompleteListener )
			userCompleteListener.apply( this, arguments );
			
		RDJ.requestQueue[ queue ].shift();
		
		if( RDJ.requestQueue[ queue ][ 0 ] ) {
			var q = RDJ.requestQueue[ queue ][ 0 ].req.send( RDJ.requestQueue[ queue ][ 0 ].send );
		}
	}
	
	// Grab and add new error listener to the queue
	var userErrorListener = options.errorListener;
	options.errorListener = function() {
		if( userErrorListener )
			userErrorListener.apply( this, arguments );
			
		RDJ.requestQueue[ queue ].shift();
		
		// If there is anything on the queue, remove them after calling their errorListeners
		if( RDJ.requestQueue[ queue ].length ) {
			var q = RDJ.requestQueue[ queue ].shift();
			q.req.abort(); // abort
			
			var fake = new Object();
			fake.status = 0;
			fake.readyState = 4;
			fake.responseText = null;
			fake.responseXML = null;
			fake.statusText = 'A request in the queue reported an error';
			q.error.apply( fake );
		}
	}
	
	RDJ.requestQueue[ queue ].push( {
		req:getRequestObject( url, options ),
		send:options.send,
		error:options.errorListener
	});
	
	// If there is only one request in the queue, send it
	if( RDJ.requestQueue[ queue ].length == 1 )
		ajaxRequest( url, options );
};
window[ 'RDJ' ][ 'ajaxRequestQueue' ] = ajaxRequestQueue;

// RDMedia

function playMovie( base, mov, div, w, h ) {
	if( !( div = $( div ) ) ) return false;
	
	if( swfobject == undefined ) alert( 'swfobject');
	
	w = ( w != undefined ) ? w : 320;
	h = ( h != undefined ) ? h : 240;
	
	removeChildren( div );
	var url = base + 'MoviePlayer.swf';
	var vars = {'src':mov};
    var params =  { loop:'false', quality:'high', wmode:'transparent', allowScriptAccess:'sameDomain', swliveconnect:'true', play:'true', scale:'showall', menu:'true', base:base }; //
    var attr = { id:div, name:div }; // , style:'display:block;' , type:'application/x-shockwave-flash'

    swfobject.embedSWF( url, div, w, h, '9.0.0', 'http://energysavepa-home.com/media/expressInstall.swf', vars, params, attr );
};
window[ 'RDJ' ][ 'playMovie' ] = playMovie;

function getURLValueForKey( key ) {
  key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+key+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
};
window[ 'RDJ' ][ 'getURLValueForKey' ] = getURLValueForKey;

// Crossfader
// Based on Timothy Grove's code
// http://www.brandspankingnew.net

window[ 'RDJ' ][ 'Crossfader' ] = function( ds, time, delay ) {
	this.act = -1;
	this.divs = new Array();

	for( var i = 0; i < ds.length; ++i ) {
		this.divs[ i ] = $( ds[ i ] );
		this.divs[ i ].style.opacity = 0;
		this.divs[ i ].style.position = "absolute";
		this.divs[ i ].style.filter = "alpha( opacity=0 )";
		this.divs[ i ].style.visibility = "hidden"
	}
	
	this.duration = time;
	this.delay = delay;
	
	this._start();
};

window[ 'RDJ' ][ 'Crossfader' ].prototype._start = function() {
	if( this.i0 )
		clearInterval( this.i0 );
		
	this.old = this.act++;
	if( !this.divs[ this.act ] ) this.act = 0;
	if( this.act == this.old )
		return false;
		
	this.divs[ this.act ].style.visibility = "visible";
	
	this.interval = 50;
	this.time = 0;
	
	var p = this;
	this.i1 = setInterval( function() {p._fade();}, this.interval );
};

window[ 'RDJ' ][ 'Crossfader' ].prototype._fade = function() {
	this.time += this.interval;
	
	var interp = Math.round( this._interpolate( this.time, 0, 1, this.duration ) * 100 );
	var op = interp / 100;
	
	this.divs[ this.act ].style.opacity = op;
	this.divs[ this.act ].style.filter = "alpha( opacity=" + interp + ")";
	
	if( this.old > - 1 ) {
		this.divs[ this.old ].style.opacity = 1 - op;
		this.divs[ this.old ].style.filter = "alpha( opacity=" + ( 100 - interp ) + ")";
	}
	
	if( this.time == this.duration ) {
		clearInterval( this.i1 );
		
		if( this.old > -1 )
			this.divs[ this.old ].style.visibility = "hidden";
			
		var p = this;
		this.i0 = setInterval( function() {p._start()}, this.delay );
	}
};

window[ 'RDJ' ][ 'Crossfader' ].prototype._interpolate = function( t, b, c, d ) {
	return c / 2 * ( 1 - Math.cos( Math.PI * t / d ) ) + b;
};

// END RDJavascript
})();

// Base Functionality
// RDBase.js
//
// Codebase for multi-browser Javascript functionality
//
// Copyright 2008, Rob Dotson. All Rights Reserved. Used by Permission.
//
// This software may be used for any purpose whatsoever, including educational,
// personal and commercial as long as this file is included in its entirety,
// or this copyright message is included along with documented changes in all
// referencing files. This software may be modified to suit any purpose, but it
// may not be sold, re-packaged or re-distributed by any means. Copies of the
// software must be retrieved from http://www.robdotson.info

function RDConfirmAction( action, target, undo ) {
    return RDJ.confirm( action, target, undo );
}

function RDNullOp() {return;}

function RDIncrementDate( date, count, unit ) {
	return RDJ.incrementDate( date, count, unit );
}

function RDRand( n ) { return RDJ.rand( n ); }

function RDIsIE6() {
	var arVersion = navigator.appVersion.split( "MSIE" );
	var version = parseFloat( arVersion[ 1 ] );
	
	if( ( version >= 5.5 ) && ( version < 7 ) )
		return true;
	else
		return false;
}

function RDCorrectPNG() {
	// This function is deprecated. Use RDJ.fixPNG() instead.
	RDJ.fixPNG();
}
//if( RDIsIE6() ) { RDJ.attachEvent( window, 'load', RDJ.fixPNG ); }

// RDElement.js
//
// Codebase for multi-browser Javascript functionality
//
// Copyright 2008, Rob Dotson. All Rights Reserved. Used by Permission.
//
// This software may be used for any purpose whatsoever, including educational,
// personal and commercial as long as this file is included in its entirety,
// or this copyright message is included along with documented changes in all
// referencing files. This software may be modified to suit any purpose, but it
// may not be sold, re-packaged or re-distributed by any means. Copies of the
// software must be retrieved from http://www.robdotson.info



function RDCreateElement( tag, attrs, children ) {
	return RDJ.createElement( tag, attrs, children );
}

function RDSetAttribute( elem, attr, val ) {
	return RDJ.setAttribute( elem, attr, val );
}

// Create the elements, apply attributes and insert children

function RDGetElementForId( theId ) {
	return RDJ.$( theId );
}

function RDGetElementsForTagName( tag ) {
	return document.getElementsByTagName( tag );
}

function RDGetElementPosition( elementId ) {
	// Get an element's position in the regular document flow
	
	var oTrail = this.getElementForId( elementId );
	var oLeft = 0;
	var oTop = 0;
	
	while( trail ) {
		oLeft += oTrail.offsetLeft;
		oTop += oTrail.offsetTop;
		oTrail = oTrail.offsetParent;
	}
	
	if( navigator.userAgent.indexOf( 'Mac' ) != -1 && typeof document.body.leftMargin != 'undefined' ) {
		oLeft += document.body.leftMargin;
		oTop += document.body.topMargin;
	}
	
	return { left:oLeft, top:oTop };
}

function RDRemoveElementChildren( theElement ) {
	if( typeof theElement == 'string' ) theElement = RDJ.$( theElement );
	
	if( theElement == null ) return;
	
	while( theElement.childNodes.length ) theElement.removeChild( theElement.childNodes[ 0 ] );
}

function RDReplaceElementContents( theElement, newContents ) {
	if( typeof theElement == 'string' ) theElement = RDJ.$( theElement );
	
	if( theElement == null ) return;
	
	if( typeof newContents == 'string' ) newContents = document.createTextNode( newContents );
	
	theElement.appendChild( newContents );
}

function RDSetElementOpacity( e, opacity ) {
	if( e = RDJ.$( e ) ) {
		e.style.opacity = opacity / 100;
		e.style.MozOpacity = opacity / 100;
		e.style.KhtmlOpacity = opacity / 100;
		e.style.filter = "alpha( opacity=" + opacity + ")";
	}
}

function RDFadeElement( theElement, begin, end, time ) {
	var speed = Math.round( time / 100 );
	var timer = 0;
	
	if( typeof theElement == 'string' )
		theElement = RDJ.$( theElement );
	
	if( begin > end ) {
		for( var i = begin; i >= end; i-- ) {
			setTimeout( function(){ RDSetElementOpacity( theElement, i ) }, ( timer * speed ) );
			timer++;
		}
	} else if( begin < end ) {
		for( var i = begin; i <= end; i++ ) {
			setTimeout( function(){ RDSetElementOpacity( theElement, i ) }, ( timer * speed ) );
			timer++;
		}
	}
	
}

function RDToggleDisplay( theElement ) {
        if( typeof theElement == 'string' ) theElement = RDJ.$( theElement );
		theElement.style.display = ( theElement.style.display == 'block' ) ? 'none' : 'block';
}

function RDToggleAndFade( theElement ) {
	if( typeof theElement == 'string' ) theElement = RDJ.$( theElement );
	
	if( theElement.style.display == 'none' ) {
		RDSetElementOpacity( theElement, 0 );
		RDToggleDisplay( theElement );
		RDFadeElement( theElement, 0, 100, 1000 );
	} else {
		RDFadeElement( theElement, 100, 0, 1000 );
		RDToggleDisplay( theElement );
		RDSetElementOpacity( theElement, 100 );
	}
}

function RDValidateDate( elemId ) {
	var elem = RDJ.$( elemId );
	if( !elem ) return false;
	
	// regular expression to match required date format
	re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
	
	if( !elem.disabled && ( elem.value == '' || !elem.value.match( re ) ) ) {
		alert( "You must enter a valid date in the format: MM/DD/YYYY" );
		elem.select();
		return false;
	}
	
	return true;
}

function RDValidateDefaultForm() {
	var elems = RDGetElementsForTagName( 'input' );
	for( var i = 0; i < elems.length; i++ ) {
		if( elems[ i ].className == 'required' && !elems[ i ].disabled && elems[ i ].value === '' ) {
			alert( 'Some required information was not provided!' );
			elems[ i ].focus();
			return false;
		}
	}
	
	return true;
}

function RDSwapImage( imgId, img0, img1 ) {
	var img = RDJ.$( imgId );
	
	img.setAttribute( 'src', (  img.src == img0 ) ? img1 : img0 );
	//RDCorrectPNG();
}

function RDSwapBackgroundImage( divId, img0, img1 ) {
	var img = RDJ.$( divId );
        img0 = 'url(' + img0 + ')';
        img1 = 'url(' + img1 + ')';
	img.style.backgroundImage = (  ( img.style.backgroundImage != img1 ) ) ? img1 : img0;
        //RDCorrectPNG();
}
// RDCSS.js
//
// Codebase for multi-browser AJAX Calendar functionality
//
// Copyright 2008, Rob Dotson. All Rights Reserved. Used by Permission.
//
// This software may be used for any purpose whatsoever, including educational,
// personal and commercial as long as this file is included in its entirety,
// or this copyright message is included along with documented changes in all
// referencing files. This software may be modified to suit any purpose, but it
// may not be sold, re-packaged or re-distributed by any means. Copies of the
// software must be retrieved from http://www.robdotson.info

// Requirements: RDElement.js

function RDCSS( cssId ) {
    if ( typeof cssId == "number")
    	cssId = document.styleSheets[ cssId ];
    	
    this.cssId = cssId;
}

RDCSS.prototype.cssId = 0;

RDCSS.prototype.enable = function( ok ) {
	this.cssId.disabled = !ok;
}

RDCSS.prototype.getRules = function() {
    return ( this.cssId.cssRules ) ? this.cssId.cssRules : this.ss.rules;
}


RDCSS.prototype.getRule = function( styleId ) {
    var rules = this.getRules();
    if( !rules ) return null;
   
    if( typeof styleId == "number" ) return rules[ styleId ];

    styleId = styleId.toLowerCase();
    for( var i = rules.length - 1; i >= 0; i-- ) {
        if( rules[ i ].selectorText.toLowerCase() == styleId ) return rules[ i ];
    }
    return null;
};

RDCSS.prototype.getStyles = function( styleId ) {
    var rule = this.getRule( styleId );
    if( rule && rule.style )
    	return rule.style;
    else
    	return null;
};

RDCSS.prototype.getStyleText = function( styleId ) {
    var rule = this.getRule( styleId );
    if( rule && rule.style && rule.style.cssText )
    	return rule.style.cssText;
    else
    	return "";
};

RDCSS.prototype.insertRule = function( selector, styles, n ) {
    if( n == undefined ) {
        var rules = this.getRules();
        n = rules.length;
    }
    
    if( this.cssId.insertRule )
        this.cssId.insertRule( selector + "{" + styles + "}", n );
    else if( this.cssId.addRule )
        this.cssId.addRule( selector, styles, n );
};

RDCSS.prototype.deleteRule = function( styleId ) {
    if( styleId == undefined ) {
        var rules = this.getRules();
        styleId = rules.length - 1;
    }

    if (typeof styleId != "number") {
        styleId = styleId.toLowerCase();
        var rules = this.getRules();
        for( var i = rules.length - 1; i >= 0; i-- ) {
            if( rules[ i ].selectorText.toLowerCase() == styleId ) {
                styleId = i;
                break;
            }
        }
        
        if( i == -1 ) return;
    }

    if( this.cssId.deleteRule )
    	this.ss.deleteRule( styleId );
    else
    	if( this.cssId.removeRule ) this.ss.removeRule( styleId );
}


// RDAjax.js
//
// Codebase for multi-browser AJAX functionality
//
// Copyright 2008, Rob Dotson. All Rights Reserved. Used by Permission.
//
// This software may be used for any purpose whatsoever, including educational,
// personal and commercial as long as this copyright message is included in all
// referencing files. This software may be modified to suit any purpose, but it
// may not be sold, re-packaged or re-distributed by any means. Copies of the
// software must be retrieved from http://www.robdotson.info 

// Constructor
function RDAjax( method ) {
    try {
        this.initAjax();
        this.setMethod( method );
    } catch( e ) { throw e; }
}

// Get and Set the request method. Only GET and POST are valid.
RDAjax.prototype.method_ = 'POST';
RDAjax.prototype.getMethod = function() { return this.method_; }
RDAjax.prototype.setMethod = function( method ) {
	method = new String( method ).toUpperCase();
    if( method != "GET" && method != "POST" )
        throw new RangeError( 'Invalid request method: ' + method );
    
    this.method_ = method;
}

// Get and Set the response format. Only JSON, TXT and XML are valid.
RDAjax.prototype.format_ = 'XML';
RDAjax.prototype.getFormat = function() { return this.format_; }
RDAjax.prototype.setFormat = function( format ) {
	switch( format ) {
		case "TXT":
		case "HTML":
		case "XML":
		case "JSON":
			this.format_ = format;
			break;
		default:
			throw new RangeError( 'Invalid response format:' + format );
	}
}

// Get and Set the query string to send to the server
RDAjax.prototype.query_ = null;
RDAjax.prototype.getQuery = function() { return this.query_; }
RDAjax.prototype.setQuery = function( query ) {
    this.query_ = query;
}

// Encode form values into a valid POST query
RDAjax.prototype.encodeFormQuery = function( formId ) {
	var str = '';
	var form = this.getElementForId( formId );
	if( !( form = RDJ.$( formId ) ) )
		throw new Error( 'Object with id ' + formId + ' is not a form, it is a ' + form.tagName + '!' );
	var count = form.elements.length;
	
	for( var i = 0; i < count; i++ ) {
		str += form.elements[ i ].name + '=' + encodeURIComponent( form.elements[ i ].value );
		if( i < ( count - 1 ) ) str += '&';
	}
		
	return str;
}

// Create the xmlHttp object for sending AJAX requests
RDAjax.prototype.xmlhttp_ = null;
RDAjax.prototype.initAjax = function() {
    // Are we on windows?
    if( window.ActiveXObject ) {
        // IE 6 & 7
        try { this.xmlhttp_ = new ActiveXObject( "Msxml2.XMLHTTP" ); }
        catch( e ) { 
            // IE < 6
            try { this.xmlhttp_ = new ActiveXObject( "Microsoft.XMLHTTP" ); }
            catch( e ) { 
                this.xmlhttp_ = null;
                throw new Error( "XMLHTTP not supported in this browser." );
            }
        }
    } else if( window.XMLHttpRequest ) { // All others
        try { this.xmlhttp_ = new XMLHttpRequest(); }
        catch( e ) { 
            this.xmlhttp_ = null;
            throw new Error( "XMLHTTP not supported in this browser." );
        }
    } else { // Ajax not supported
        this.xmlhttp_ = null;
        throw new new Error( "XMLHTTP not supported in this browser." );
    }
}

// Get the content type of the server response, and return the apropriate data type
RDAjax.prototype.response_ = null;
RDAjax.prototype.response = function() { return this.response_; }
RDAjax.prototype.validateResponse = function() {
    var type = this.xmlhttp_.getResponseHeader( "Content-Type" );
    switch( type ) {
        case 'text/xml':
            this.setFormat( 'XML' );
            this.response_ = this.xmlhttp_.responseXML;
            break;
        case 'text/html':
        case 'text/html; charset=utf-8':
        	this.setFormat( 'HTML' );
        	this.response_ = this.xmlhttp_.responseText;
        	break;
        case 'text/plain':
            this.setFormat( 'TXT' );
            this.response_ = this.xmlhttp_.responseText;
            break;
        default:
            throw new Error( 'The server returned an invalid content type: ' + type + '\n' + this.xmlhttp_.responseText );
    }
}

// Handle the response codes from the server
RDAjax.prototype.handleResponse = function() {
    switch( this.xmlhttp_.readyState ) {
        case 1: break;
        case 2: break;
        case 3: break;
        case 4:
            if( this.xmlhttp_.status == 200 ) { // We got a valid response
                try {this.validateResponse();}
                catch( e ) { throw e; }
            } else { throw new Error( 'The server returned a code ' + this.xmlhttp_.status + ' while attempting to process your request.\n\n' + this.xmlhttp_.statusText ); }
            break;
        default:
            throw new Error( 'The ajaxObj is in an unknown state: ' + this.xmlhttp_.readyState );
    }
}

// Submit an AJAX request to the url specified by theURL. If async is true,
// the function will return before recieving a response. If the request method
// equals POST, you must include the id of the form to get POST values from.
RDAjax.prototype.submitRequest = function( theURL, async, formId ) {
	var this_ = this;
	
	if( this.method_ == 'POST' ) {
		if( !( formId = RDJ.$( formId ) ) )
			throw new Error( 'You must enter a formId to send POST requests!' );
		else {
			try { this.setQuery( this.encodeFormQuery( formId ) ); }
			catch( e ) { throw e; }
		}	
	}
		
	try {
		this.xmlhttp_.open( this.method_, theURL, async );
		if( async )
			this.xmlhttp_.onreadystatechange = function() { try {this_.handleResponse();} catch( e ) { alert( e.message ); } }
		/*
if( this.method_ == 'POST' )
			this.xmlhttp_.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
*/
		this.xmlhttp_.send( this.query_ );
		
		if( !async ) this_.handleResponse();
	} catch( e ) { throw e; }
}

// Submit a request from a form directly.
RDAjax.prototype.submitRequestFromForm = function( formId, async ) {
	form = RDJ.$( formId );
	if( form == null || form.tagName != 'FORM' )
		throw new Error( 'Object with id ' + formId + ' is not a form, it is a ' + form.tagName + '!' );
	
	try {	
		this.setMethod( form.method );
		this.submitRequest( form.action, async, formId );
	} catch( e ) { alert( e.message ); }	
}

// Return a more user friendly confirmation box
//
// ** THIS FUNCTION IS DEPRECATED DO NOT USE IT **
RDAjax.prototype.confirm = function( action, target, undo ) {
    return RDConfirmAction( action, target, undo );
}

// Create a DOM element from a tag
//
// ** THIS FUNCTION IS DEPRECATED DO NOT USE IT **
RDAjax.prototype.createElement = function( tag ) {
    return RDCreateElement( tag );
}

// Get a valid object reference from an id tag
//
// ** THIS FUNCTION IS DEPRECATED DO NOT USE IT **
RDAjax.prototype.getElementForId = function( theId ) {
	return RDJ.$( theId );
}

// Set the opacity of an HTML element
//
// ** THIS FUNCTION IS DEPRECATED DO NOT USE IT **
RDAjax.prototype.setOpacity = function( element, opacity ) {
	RDSetElementOpacity( element, opacity );
}

// The RDAjax Object
var ajaxObj = new RDAjax( 'GET' );


// RDCalendar.js
//
// Codebase for multi-browser AJAX Calendar functionality
//
// Copyright 2008, Rob Dotson. All Rights Reserved. Used by Permission.
//
// This software may be used for any purpose whatsoever, including educational,
// personal and commercial as long as this file is included in its entirety,
// or this copyright message is included along with documented changes in all
// referencing files. This software may be modified to suit any purpose, but it
// may not be sold, re-packaged or re-distributed by any means. Copies of the
// software must be retrieved from http://www.robdotson.info

// Requirements: RDCSS.js
// Requirements: RDElement.js

RDCalendar.prototype.targetDiv = 0;
RDCalendar.prototype.selectorForm = 0;
RDCalendar.prototype.headerCell = 0;
RDCalendar.prototype.tableBody = 0;
RDCalendar.prototype.variableName = 0;
RDCalendar.prototype.selectedDate = 0;
RDCalendar.prototype.selectorFunction = function() {}

function RDCalendar( divId, variableName, defaultStyle ) {
	// Grab a pointer to the target div
	this.targetDiv = RDJ.$( divId );
        if( !this.targetDiv ) alert( divId + ' is not a valid div id!' );
	
	// Set the style
	if( defaultStyle == undefined || defaultStyle == true )
		this.setDefaultStyle();
		
	// Set the variable name
	if( variableName == undefined )
		this.variableName = 'cal';
	else
		this.variableName = variableName;
	
	// Create the calendar table
	var table = RDJ.createElement( 'table' );
	table.setAttribute( 'class', 'RDCalendarTable' );
	table.setAttribute( 'cellpadding', 0 );
	table.setAttribute( 'cellspacing', 0 );
	table.setAttribute( 'width', '100%' );
	
	var thead = RDJ.createElement( 'thead' );
	
	// Create the top header row & header tag (Month & Year)
	this.headerCell = RDJ.createElement( 'th' );
	this.headerCell.setAttribute( 'class', 'headerCell' );
	this.headerCell.setAttribute( 'colspan', 7 );
	
	var tr = RDJ.createElement( 'tr', null, this.headerCell );
	thead.appendChild( tr );
	
	// Create the second header row (Day)
	var days = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
	
	tr = RDJ.createElement( 'tr' );
	
	for( d in days ) {
		th = RDJ.createElement( 'th', days[ d ] );
		tr.appendChild( th );
	}
	
	thead.appendChild( tr );
	table.appendChild( thead );
	
	var tfoot = RDJ.createElement( 'tfoot' );
	
	// Create the Month Chooser form
	tr = RDJ.createElement( 'tr' );
	
	var td = RDJ.createElement( 'th' );
	td.setAttribute( 'colspan', 7 );

	
	var p = RDJ.createElement( 'p' );
	
	this.selectorForm = RDJ.createElement( 'form' );
	this.selectorForm.setAttribute( 'name', 'dateChooser' );
	
	// Month Selector
	var select = RDJ.createElement( 'select' );
	select.setAttribute( 'name', 'chooseMonth' );
	select.setAttribute( 'onchange', this.variableName + '.selectMonth();' );
	select.onchange = function() { window[ this.variableName ].selectMonth(); }
	
	var months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
	
	for( var i = 0; i < 12; i++ ) {
		var opt = RDJ.createElement( 'option' );
		opt.appendChild( document.createTextNode( months[ i ] ) );
		select.appendChild( opt );
		
	}
	
	this.selectorForm.appendChild( select );
	
	// Year Selector
	select = RDJ.createElement( 'select' );
	select.setAttribute( 'name', 'chooseYear' );
	select.setAttribute( 'onchange', this.variableName + '.selectYear();' );
	this.selectorForm.appendChild( select );
	
	// Insert all of the nested objects
	p.appendChild( this.selectorForm );
	td.appendChild( p );
	tr.appendChild( td );
	tfoot.appendChild( tr );
	table.appendChild( tfoot );
	
	// Create the table body
	this.tableBody = RDJ.createElement( 'tbody' );
	table.appendChild( this.tableBody );
	
	this.targetDiv.appendChild( table );
	
	this.fillYears( 0, 1 );
	this.populateTable();
	this.selectorFunction();
        this.selectYear( 0 );
}

RDCalendar.prototype.firstDay = function( year, month ) {
	// Get the day of the week of month's first day
	
	var date = new Date( year, month, 1 );
	
	return date.getDay();
}

RDCalendar.prototype.numDays = function( year, month ) {
	// Get the number of days in the month
	
	var nm = new Date( year, month + 1, 1 );
	nm.setHours( nm.getHours() - 3 );
	
	return nm.getDate();
}

RDCalendar.prototype.fillYears = function( past, future ) {
	if( past == undefined ) past = 0;
	if( future == undefined ) future = 0;
		
	var today = new Date();
	var thisYear = today.getFullYear();
	
	for( var i = 0; i < (  ( thisYear + future + 1 ) - ( thisYear - past ) ); i++ ) {
		var opt = RDJ.createElement( 'option' );
		opt.setAttribute( 'selected', ( ( i == ( thisYear - past ) ) ? true : false ) );
		opt.appendChild( document.createTextNode( ( thisYear - past ) + i ) );
		
		this.selectorForm.chooseYear.appendChild( opt );
	}
	
	this.selectorForm.chooseMonth.selectedIndex = today.getMonth();

this.selectorForm.chooseYear.selectedIndex = 0;
}

RDCalendar.prototype.chooseDate = function( date, month, year ) {
	this.selectedDate = date;
	this.selectorForm.chooseMonth.selectedIndex = month;
	this.selectorForm.chooseYear.selectedIndex = year;
	
	this.populateTable();
	this.selectorFunction();
}

RDCalendar.prototype.selectDay = function( date ) {
	this.selectedDate = date;
	
	this.populateTable();
	this.selectorFunction();
}

RDCalendar.prototype.selectMonth = function( month ) {
	this.selectedDate = 0;
	
	this.populateTable();
	this.selectorFunction();
}

RDCalendar.prototype.selectYear = function( year ) {
	//this.selectorForm.chooseYear.selectedIndex = year;
	
	this.selectedDate = 0;
	
	this.populateTable();
	this.selectorFunction();
}

RDCalendar.prototype.setDefaultStyle = function() {
	var css = '';
	
	if( document.styleSheets == 'undefined' ){
		css = new RDCSS( document.styleSheets.length - 1 );
	
		css.insertRule( '.RDCalendarTable', 'position:absolute; left:0px; top:0px; border-collapse: collapse;' );
		css.insertRule( '.RDCalendarTable table', 'font-family:Verdana, Arial, Helvetica, sans-serif; background-color:#999999;' );
		css.insertRule( '.RDCalendarTable table th', 'background-color:#ccffcc; text-align:center; font-size:10px; width:26px;' );
		css.insertRule( '.RDCalendarTable tableth.headerCell', 'background-color:#ffcccc; width:100%;' );
		css.insertRule( '.RDCalendarTable table td', 'background-color:#ffffcc; text-align:center; font-size:10px;' );
		css.insertRule( '.RDCalendarTable tbody tr td', 'width:26px;' );
		css.insertRule( '.RDCalendarTable .today', 'background-color:#ffcc33;' );
		css.insertRule( '.RDCalendarTable a:link', 'color:#000000; text-decoration:none;' );
		css.insertRule( '.RDCalendarTable a:active', 'color:#000000; text-decoration:none;' );
		css.insertRule( '.RDCalendarTable a:visited', 'color:#000000; text-decoration:none;' );
		css.insertRule( '.RDCalendarTable a:hover', 'color:#990033; text-decoration:underline;' );
		
		css.enable( true );
	} else {
		css = 'table.RDCalendarTable { font-family:Verdana, Arial, Helvetica, sans-serif; background-color:white; border-collapse: collapse; border: 1px solid #990000; }';
		css += ' .RDCalendarTable thead { background-color:#990000; color:white; }';
		css += ' .RDCalendarTable th { text-align:center; font-size:10px; width:16px; font-weight: normal;  }';
		css += ' .RDCalendarTable th.headerCell { width:100%; font-size: 12px; font-weight: bold; }';
		css += ' .RDCalendarTable td { text-align:center; font-size:10px; border: 1px solid gray; width: 24px; height: 24px; vertical-align: middle; }';
		css += ' .RDCalendarTable a:link { color:#000000; text-decoration:none }';
		css += ' .RDCalendarTable a:active { color:#000000; text-decoration:none }';
		css += ' .RDCalendarTable a:visited { color:#000000; text-decoration:none }';
		css += ' .RDCalendarTable a:hover { color:#990033; text-decoration:underline }';
		css += ' .RDCalendarTable .today { font-weight: bold; }';
		css += ' .RDCalendarTable #selectedDate { color:#990033; font-weight: bold; }';
		
		var style = RDCreateElement( 'style', {'type':'text/css'} );
		if( style.styleSheet )
			style.styleSheet.cssText = css;
		else
			style.appendChild( document.createTextNode( css ) );
		
		document.getElementsByTagName( 'head' )[ 0 ].appendChild( style );
	}
	
}

RDCalendar.prototype.populateTable = function() {
	// Fill the table with date values
	
	var theForm = this.selectorForm;
	
	// Initialize variables
	var month = this.selectorForm.chooseMonth.selectedIndex;
	var year = parseInt( theForm.chooseYear.options[ theForm.chooseYear.selectedIndex ].text );
	var day = this.firstDay( year, month );
	var count = this.numDays( year, month );
	var today = new Date();
	
	// Grab the header cell & add the month and year
	var th = this.headerCell;
	RDRemoveElementChildren( th );
	th.appendChild( document.createTextNode( this.selectorForm.chooseMonth.options[ month ].text + ' ' + year ) );
	
	// Initialize variables for table creation
	var dayCounter = 1;
	while( this.tableBody.rows.length > 0 ) this.tableBody.deleteRow( 0 );
	
	var row, col, dateNum;
	var done = false;
	
	while( !done ) {
		// Insert a new week
		row = this.tableBody.insertRow( this.tableBody.rows.length );
		if( row ) {
			for( var i = 0; i < 7; i++ ) {
				// Insert a new day
				col = row.insertCell( row.cells.length );
				if( this.tableBody.rows.length == 1 && i < day ) {
					col.appendChild( document.createTextNode( "\u00a0" ) );
					continue;
				}
				
				// No more days, we're done!
				if( dayCounter == count ) done = true;
				
				// Get the link/date
				if( dayCounter <= count ) {
					// Is the date today? If so, set the cell's class to 'today'
					if( today.getFullYear() == year && today.getMonth() == this.selectorForm.chooseMonth.selectedIndex && today.getDate() == dayCounter ) col.setAttribute( 'class', 'today' );
					if( this.selectedDate && dayCounter == this.selectedDate ) col.id = 'selectedDate';
					
					var link = RDJ.createElement( 'a' );
					link.setAttribute( 'href', 'Javascript:' + this.variableName + '.selectDay( ' + dayCounter + ');' );
					link.appendChild( document.createTextNode( dayCounter ) );
					
					col.appendChild( link );
					dayCounter++;
				} else {
					col.appendChild( document.createTextNode( "\u00a0" ) );
				}
			}
		} else {
			done = true;
		}
		
	}
}

// RDTExt

// Repeat a string
if( !String.repeat ) {
	String.prototype.repeat = function( n ) { return new Array( n + 1 ).join( this ); }
}

// Trim whitespace
if( !String.trim ) {
	String.prototype.trim = function() { return this.replace( /^\s|\s+$/g, '' ); }
}

// RDDOMGenerator
(function(){

	function encode( str ) {
		if( !str ) return null;
		
		str = str.replace( /\\/g, '\\\\' );
		str = str.replace( /';/g, "\\'" );
		str = str.replace( /\s+^/mg, "\\n" );
		
		return str;
	}
	
	function checkForVariable( v ) {
		if( v.indexOf( '$' ) == -1 ) { // not found
			v = '\'' + v + '\'';
		} else {
			v = v.substring( v.indexOf( '$' ) + 1 );
			requiredVariables += 'var ' + v + ';\n';
		}
		
		return v;
	}
	
	var domCode = '';
	var nodeNameCounters = [];
	var requiredVariables = '';
	var newVariables = '';
	
	function generate( strHTML, strRoot ) {
		var domRoot = RDCreateElement( 'div' );
		domRoot.innerHTML = strHTML;
		
		domCode == '';
		nodeNameCounters = [];
		requireVariables = '';
		newVariables = '';
		
		var node = domRoot.firstChild;
		
		while( node ) {
			RDJ.walkTheDOMRecursive( processNode, node, 0, strRoot );
			node = node.nextSibling;
		}
		
		domCode = '/* requiredVariables in this code\n' + requiredVariables;
		domCode += '*/\n\n';
		domCode += '/* new objects in this code\n' + newVariables;
		domCode += '*/\n\n';
		
		return domCode;
		
	}
	
	function processAttribute( tabCount, refParent ) {}
	
	function processNode( tabCount, refParent ) {}
	
	window[ 'generateDOM' ] = generate;
	
})();

