/** 
	* @fileoverview
	* This file is the base class for the TLP Library
	* It contains common methods that compliment or provide alternatives to the Prototype and Scriptaculous libraries
	* Permission is hereby granted, free of charge, to any person obtaining
	* a copy of this software and associated documentation files (the
	* "Software"), to deal in the Software without restriction, including
	* without limitation the rights to use, copy, modify, merge, publish,
	* distribute, sublicense, and/or sell copies of the Software, and to
	* permit persons to whom the Software is furnished to do so, subject to
	* the following conditions:
	* 
	* The above copyright notice and this permission notice shall be
	* included in all copies or substantial portions of the Software.
	*
	* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
	* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
	* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
	* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
	*
	* @author Leevi Graham -http://www.leevigraham.com - info@leevigraham.com
	* @version 1.0
	*
	* @requires Prototype Library v1.5
	* @requires Scriptaculous Library v1.6
*/

/**
	* Construct a new TLP object.
	* @class This is the basic TLP class.  
	* It contains common methods that compliment or provide alternatives to the Prototype and Scriptaculous libraries
	* @constructor
	* @return Nothing
*/
var TLP = {
	
	/**
		* Version of TLP
	*/
	Version: '1.0',  	

	/**
		* Load method of TLP
		* Executed immediatley after TLP is created
		* Tests for required JavaScript libraries Prototype v1.5 and Scriptaculous v1.6
		* @returns Nothing
		* @throws General exception if required classes are not available.
	*/
	load: function() {
    
		var errorMsg = null;
		
		// if the class Prototype is undefined
		if((typeof Prototype=='undefined') || 
			// or the version of prototype is less than 1.5
			parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) < 1.5)
				// add error message
				errorMsg = ("the Prototype JavaScript framework >= 1.5.0" + "\n");
		
		// if the class of Scriptaculous is undefined
		if((typeof Scriptaculous =='undefined') ||
			// of the version of Scriptaculous is less than 1.6
			parseFloat(Scriptaculous.Version.split(".")[0] + "." + Scriptaculous.Version.split(".")[1]) < 1.6)
				// add error message
				errorMsg += ("the Scriptaculous JavaScript framework >= 1.6.0" + "\n");
		
		// if the error message is not empty
		if(errorMsg != null)
		{
			// Add a prefix to the error message
			errorMsg = 'TLP version ' + TLP.Version + ' requires:' + "\n" + errorMsg;
			
			// alert the developer
			alert(errorMsg);
			
			// and throw and exception
			throw (errorMsg);
		}
	}
}

/**
	* Execute the load method of TLP
	* @see TLP
*/
TLP.load();



/* FULL CREDIT: Andre (http://www.earthcode.com/ajax/2006/01/optional_args.html) */
TLP.augment = function (oSelf, oOther) {
	if (oSelf == null)
	{
		oSelf = {};
	}
	for (var i = 1; i < arguments.length; i++)
	{
		var o = arguments[i];
		if (typeof(o) != 'undefined' && o != null)
		{
			for (var j in o)
			{
				oSelf[j] = o[j];
			}
		}
	}
	return oSelf;
}


/* Based on a function by: */
TLP.getElementsByAttribute = function(attribute, oOptions) {
	
	var oOptions = TLP.augment({
		value: null,
		tagName: '*',
		parentElement: document
	}, oOptions );
	
	var children = $(oOptions.parentElement).getElementsByTagName(oOptions.tagName);
	
	return $A(children).inject([], function(elements, child){
		var attributeValue = child.getAttribute(attribute);
		if(attributeValue != null)
		{
			if(!oOptions.value || attributeValue == oOptions.value)
			{
				elements.push(child);
			}
		}
		return elements;
	});
}

TLP.throwEx = function(ex){
	// alert Developer
	alert(ex);
	// throw exception
	throw(ex);
}

/******************************************************************************** /*

	GET ELEMENTS BY TAG NAME(s)
	
	getElementsByTagNames takes two arguments:
	1. 	A string with a comma-separated list of tag names.
	2. 	An optional start element. If it's present the script searches only for 
		tags that are descendants of this element, if it's absent the script 
		searches the entire document.

	Example 1:
	var headerList = getElementsByTagNames('h1,h2,h3,h4');
	
	Example 2:
	var element = document.getElementById('test');
	var formFieldList = getElementsByTagNames('input,select,textarea',element);
	
	Originally written by:
	Peter Paul Koch - http://www.quirksmode.org/dom/getElementsByTagNames.html
	
	Modified By: 
	Leevi Graham

/******************************************************************************* */

TLP.getElementsByTagNames = function(sList, parentElement)
{
	var parentElement = $(parentElement);
	if (!parentElement) var parentElement = document;
	
	var tagNames = slist.split(',');
	
	var resultArray = new Array();
	
	for (var i=0;i<tagNames.length;i++){
		var tags = obj.getElementsByTagName(tagNames[i]);
		for (var j=0;j<tags.length;j++) {
			resultArray.push(tags[j]);
		}
	}
	var testNode = resultArray[0];
	if (testNode.sourceIndex) {
		resultArray.sort(function (a,b) {
				return a.sourceIndex - b.sourceIndex;
		});
	} else if (testNode.compareDocumentPosition) {
		resultArray.sort(function (a,b) {
				return 3 - (a.compareDocumentPosition(b) & 6);
		});
	}
	return resultArray;
}
/* END GETS ELEMENTS BY TAG NAME(s) */

TLP.DLtypeof = function( vExpression )
{	
	var sTypeOf = typeof vExpression;
	if( sTypeOf == "function" )
	{
		var sFunction = vExpression.toString();
		if( ( /^\/.*\/$/ ).test( sFunction ) )
		{
			return "regexp";
		}
		else if( ( /^\[object.*\]$/i ).test( sFunction ) )
		{
			sTypeOf = "object"
        }
	}
	if( sTypeOf != "object" )
	{
		return sTypeOf;
	}
	
	switch( vExpression )
	{
		case null:
			return "null";
		case window:
			return "window";
		case window.event:	
			return "event";
	}
	
	if( window.event && ( event.type == vExpression.type ) )
	{
		return "event";
	}
	
	var fConstructor = vExpression.constructor;
    if( fConstructor != null )
	{
		switch( fConstructor )
		{																	
			case Array:
				sTypeOf = "array";
				break;
			case Date:
				return "date";
			case RegExp:
				return "regexp";
			case Object:
				sTypeOf = "jsobject";
				break;
			case ReferenceError:
				return "error";
			default:
				var sConstructor = fConstructor.toString();
				var aMatch = sConstructor.match( /\s*function (.*)\(/ );
				if( aMatch != null )
				{
					return aMatch[ 1 ];
				}
			
		}
	}

	var nNodeType = vExpression.nodeType;
	if( nNodeType != null )
	{	
		switch( nNodeType )
		{
			case 1:
				if( vExpression.item == null )
				{
					return "domelement";
				}
				break;
			case 3:
				return "textnode";
		}
	}
	
	if( vExpression.toString != null )
	{
		var sExpression = vExpression.toString();
		var aMatch = sExpression.match( /^\[object (.*)\]$/i );
		if( aMatch != null )	
		{
			var sMatch = aMatch[ 1 ];
			switch( sMatch.toLowerCase() )
			{
				case "event":
					return "event";
				case "math":
					return "math";
				case "error":	
					return "error";
				case "mimetypearray":
					return "mimetypecollection";
				case "pluginarray":
					return "plugincollection";
				case "windowcollection":
					return "window";
				case "nodelist":
				case "htmlcollection":
				case "elementarray":
					return "domcollection";
			}
		}
	}
	
	if( vExpression.moveToBookmark && vExpression.moveToElementText )
	{
		return "textrange";
	}
	else if( vExpression.callee != null )
	{
		return "arguments";
	}
	else if( vExpression.item != null )	
	{
		return "domcollection";
	}
	
	return sTypeOf;
}


String.prototype.trim = function() {
	var re = /^\s+(.*?)\s+$/;
	return this.replace(re,"$1");
}


/* -- BASIC COOKIE MANIPULATION METHODS -- */
TLP.createCookie = function(name,value,days)
{
	if (days)
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

TLP.readCookie = function(name)
{
	var nameEQ = name + "=";
	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(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

TLP.eraseCookie = function(name)
{
	createCookie(name,"",-1);
}
