if( ! console )
{
	var console = new Object();
	console.timers = new Object();
	console.log = function()
	{
		$A(arguments).each(
			function(arg, idx)
			{
				if( ! $('consoleLog') )
				{
					if( idx > 0)
						$('consoleLog').innerHTML += ('<p class="entry">' + htmlEditFormat(arg) + '</p>');				
					else
						new Insertion.Top(document.body,'<div style="z-index: 100;" id="consoleLog"><p class="entry">'+htmlEditFormat(arg)+"</p></div>");
				}
				else
					$('consoleLog').innerHTML += ('<p class="entry">' + htmlEditFormat(arg) + '</p>');				
			}
		)
		
	}
	
	
}

htmlEditFormat = function(str)
{
	if( typeof str == 'String')
		return str.replace(/>/gi,'&gt;').replace(/</gi,'&lt;');
	else
		return str.toString();
}

/* i tried to put these fns onto console, but it doesnt work in FF with firebug.
to use:

profiler.startTimer('speedtest1');

//slow code

profiler.endTimer('speedtest1');

 */
var profiler = new Object();
profiler.timers = new Object();

profiler.startTimer = function(timerCode)
{
	this.timers[timerCode] = new Object();
	this.timers[timerCode].startTime = (new Date()).valueOf();		
}

profiler.endTimer = function(timerCode)
{
	if ( this.timers[timerCode] )
	{
		this.timers[timerCode].endTime = (new Date()).valueOf();
		this.timers[timerCode].timeSecs = (this.timers[timerCode].endTime - this.timers[timerCode].startTime) / 1000;
		console.log(timerCode + ': ' + this.timers[timerCode].timeSecs + ' seconds\n');
		delete this.timers[timerCode];
	}
}





var INCLUDED_FILES = new Array();

function include(script_filename) 
{
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    
	js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    js.setAttribute('src', script_filename);
	
    html_doc.appendChild(js);
	
    return false;
}


function include_once(script_filename) 
{
    if (!in_array(script_filename, INCLUDED_FILES)) 
	{
        INCLUDED_FILES[included_files.length] = script_filename;
        include(script_filename);
    }
}

var RedSquare = Class.create();

RedSquare.Lang = new Object();

RedSquare.Window = 
{
	getWidth: function(){
		return window.innerWidth || document.documentElement.clientWidth || 0;
	},
	
	/*
	Property: getHeight
		Returns an integer representing the height of the browser.
	*/

	getHeight: function(){
		return window.innerHeight || document.documentElement.clientHeight || 0;
	}	
}

RedSquare.ParentFinder = Base.extend 
({
	constructor: function(element)
	{
		this.element = element;
	},
	
	findTag: function(tagName)
	{
		// check if the id or class has been specified
		
		var matches;
		var className;
		var id;
		var useTagName;
		
		// check for the class name
		matches = tagName.match(/\.([\w\-]+)/i);
		
		if (matches)
			className = matches[1];
		
		// check for the id
		matches = tagName.match(/\#([\w\-]+)/i);
		
		if (matches)
			id = matches[1];
		
		// extract tag name
		matches = tagName.match(/^([\w\-]+)/i);
		
		if (matches)
			useTagName = matches[1];
		else
			useTagName = tagName;
		
		return this.doFindTag(this.element, useTagName, className, id);
	},
	
	
	doFindTag: function(element, tagName, className, id)
	{
		var re = new RegExp('^' + tagName + '$', 'i');
		
		if (element.tagName)
		{
			if (element.tagName.match(re))
			{
					
				if (className && id)
				{
					if (Element.hasClassName(element, className) && element.id == id)
						return element;
				}
				else if (className)
				{
					
					if (Element.hasClassName(element, className))
						return element;
				}
				else if (id)
				{
					if (element.id == id)
						return element;
				}
				else
					return element;
			}
		}
		else if (element.nodeType == 3)
		{
			// Some browsers even report you being in a text node (Safari 1.3, looking at you)
			// fall through
		}
		else
		{
			// we've reached the document element
			return false;
		}
		
		if (element.parentNode)
			return this.doFindTag(element.parentNode, tagName, className, id);
		else
			return false;
	},
	
	findElement: function(element)
	{
		return this.doFindElement(this.element, element);
	},
	
	doFindElement: function(baseElement, element)
	{
		if (baseElement == element)
			return element;
		else
		{
			
			if (baseElement.parentNode)
			{
				return this.doFindElement(baseElement.parentNode, element);	
			}
			else
				return false;
		}
		
	}
});


Object.extend
(
 	RedSquare,
	{
		leadingZero: function(number)
		{
			if (number < 10)
				return '0' + number.toString();
			else
				return number.toString();
		},
		
		isSelect: function(element)
		{
			return element.tagName.match(/select/i) != null;		
		},
		
		isTextArea: function(element)
		{
			return element.tagName.match(/textarea/i) != null;		
		},
		
		isInputText: function(element)
		{
			if (element.getAttribute('type'))
				return element.tagName.match(/input/i) != null && element.getAttribute('type').match(/text/i) != null;	
				
			return element.tagName.match(/input/i) != null; // most browsers regard an input with no "type" as a text field, so we catch this here
		},
		
		isInputHidden: function(element)
		{
			if (element.getAttribute('type'))
				return element.tagName.match(/input/i) != null && element.getAttribute('type').match(/hidden/i) != null;	
		},
		
		isInputRadio: function(element)
		{
			if (element.getAttribute('type'))
				return element.tagName.match(/input/i) != null && element.getAttribute('type').match(/radio/i) != null;		
		
			// can't be a radio is type attribute is not supplied
			return false;
		},
		
		isInputCheckbox: function(element)
		{
			
			if (element.getAttribute('type'))
				return element.tagName.match(/input/i) != null && element.getAttribute('type').match(/checkbox/i) != null;		
		
			// can't be a checkbox is type attribute is not supplied
			return false;
			
		},
		
		isSelectable: function(element)
		{
			return this.isInputText(element) || this.isTextArea(element);	
		},
				
		labelOf: function(element)
		{
		   return $$('label').detect
		   (
				function(label)
				{
					// have to use this syntax instead of getAttribute, since IE6 is ... erm .... flawed...
					
					if (label.attributes['for'])
						return label.attributes['for'].value == element.id;
					else
						return label.getAttribute("for") == element.id;
				}
		   );
		}
	}
)
/* Extensions to the javascript String Object prototype */

String.prototype.properCase = function()
{
	var strReturn = "";
	var intLength = this.length;
	var boolUCaseNext = false;
	
	if (intLength == 0)
	{
		return "";
	}
	
	strReturn += this.charAt(0).toUpperCase();
	
	for (var iCounter = 1; iCounter < intLength; iCounter++)
	{
		if (boolUCaseNext == true)
		{
			strReturn += this.charAt(iCounter).toUpperCase();
		}
		else
		{
			strReturn += this.charAt(iCounter).toLowerCase();
		}
		
		var iChar = this.charCodeAt(iCounter);
		
		if (iChar == 32 || iChar == 45 || iChar == 46)
		{
			boolUCaseNext = true;
		}
		else
		{
			boolUCaseNext = false
		}
		
		if (iChar == 99 || iChar == 67)
		{
			if (this.charCodeAt(iCounter-1) == 77 || this.charCodeAt(iCounter-1)==109)
			{
				boolUCaseNext = true;
			}
		}
	} 

	return strReturn;
}

String.prototype.decamelize =  function(delimiter)
{
	return this.replace(/([A-Z0-9])/g, (delimiter ? delimiter: '-') + '$1').toLowerCase();
}

String.prototype.startsWithVowel = function()
{
	return this.match(/^[aeiou]/i) != null;	
}

String.prototype.startsWithConsonant = function()
{
	return this.match(/^[^aeiou]/i) != null;	
}

String.prototype.precedeWithA = function()
{
	// The letter U in english is sometimes pronounced with a "y" sound. e.g. "use", "unit", etc
	return this.startsWithConsonant() || this.match(/^u[stkrlzbnm]/i) != null;	
}

String.prototype.precedeWithAn = function()
{
	return !this.precedeWithA();
}

String.prototype.capitalize = function()
{
	return this.replace(/(\b)([a-z])/g, "$1" + new String("$2").toUpperCase());
}

String.prototype.ltrim = function()
{
	// Match spaces at beginning of text and replace with an empty string
	// i.e. trims leading white space
	return this.replace(/^\s+/,'');
}

String.prototype.rtrim = function() 
{
	// Match spaces at end of text and replace with an empty string
	// i.e. trims trailing white space
	return this.replace(/\s+$/,'');
}

String.prototype.trim = function() 
{
	// Match spaces at beginning and end of text and replace with an empty string
	// i.e. trims trailing and leading white space
	
	//return this.replace(/^\s+/,'').replace(/\s+$/,'');
	return this.ltrim().rtrim();
}


String.prototype.isNumeric = function() 
{
	// returns true if the string is a number (can have optional decimal places, but no commas)
	return this.trim().match(/^[\d]*\.?[\d]*$/);
}

String.prototype.isFloat = function() 
{
	// returns true if the string is a number (can have optional decimal places, but no commas)
	return this.isNumeric();
}


String.prototype.isInteger = function()
{
	// returns true if the string is a valid whole number (no decimal places, commas)
	return this.trim().match(/^\d*$/);
}

String.prototype.isEmailAddress = function()
{
	// returns true if the string is a valid email address
	return this.trim().match(/^([\w-']+)(.[\w-']+)*@([\w-]+)(.[\w]{2,20}){1,4}$/);
}

String.prototype.asFloat = function()
{
	// returns the float-typed value if the string is a float
	// but safely returns a float zero if the value is not a float (useful in arithmetic expressions on form fields)
	
	if (isNaN(this))
		return 0.0;
	else
		if (this.trim() == '')
			return 0.0;
		else
			return parseFloat(this);
}




