
	/* public */
	// Add an onload event to the current page load
	function OTaddLoadEvent( func )
	{
		var oldonload = window.onload;

		if (typeof window.onload != 'function')
		{
			window.onload = func;
		}
		else
		{
			window.onload = function()
			{
				if (oldonload)
				{
					oldonload();
				}
				func();
			};
		}
	}

	// Add an onload event to the current page load
	function OTaddResizeEvent( func )
	{
		var oldonresize = window.onresize;

		if (typeof window.onresize != 'function')
		{
			window.onresize = func;
		}
		else
		{
			window.onresize = function()
			{
				if (oldonresize)
				{
					oldonresize();
				}
				func();
			};
		}
	}

	//--------------------------------------------------------------------------------------------
	// extending Object to allow automatic registration of setters and getters for internal variables
	Object.prototype.addProperty = function (sType, sName, vValue)
	{
		// Type will be one of the following
		//		"undefined" the value doesn’t exist.
		//		"string"
		//		"number"
		//		"function"
		//		"object"
		//		"boolean"
		
		if ( typeof sName == 'undefined'){
			// can't add this property because name is not defined, silent return (LPAD-19651)
			return;	
		}
		
		if (typeof vValue != sType) {
			alert("Property " + sName + " must be of type " + sType + ".");
			return;
		}

		this[sName] = vValue;

		var sFuncName = sName.charAt(0).toUpperCase() + sName.substring(1, sName.length);

		this["Get" + sFuncName] = function () { return this[sName]; };
		this["Set" + sFuncName] = function (vNewValue)
			{

				if (typeof vNewValue != sType) {
					alert("Property " + sName + " must be of type " + sType + ".");
					return;
				}

				var vOldValue = this["Get" + sFuncName]();

				var oEvent = {
					propertyName: sName,
					propertyOldValue: vOldValue,
					propertyNewValue: vNewValue,
					returnValue: true
				};

				if ( undefined !== this.onpropertychange )
				{
					this.onpropertychange(oEvent);
				}
				if (oEvent.returnValue)
				{
					this[sName] = oEvent.propertyNewValue;
				}
		};
	};



	//--------------------------------------------------------------------------------------------
	// Utility functions for zero padding
	String.prototype.times = function(n)
	{
		var s = '';
		for (var i = 0; i < n; i++)
		{
			s += this;
		}

		return s;
	};

	//--------------------------------------------------------------------------------------------
	// String extensions
	String.prototype.zp = function(n) { return '0'.times(n - this.length) + this; };
	
	String.prototype.zpa = function(n) { return this + ' '.times(n - this.length); };

	// Safari 2.0 requires this prototype
	if ( Safari )
	{
		String.prototype.localeCompare = function ( theString )
		{
			if (this < theString) {return -1;}
			if (this > theString) {return 1;}
			return 0;
		}
	};
	
	// is the string sent in a number? T/F returned
	String.prototype.isNumber = function()
	{
		var str;
		var re = /^[-]?\d+$/;

		str = this.toString();

		if ( ! str.match( re ) )
		{
			return false;
		}

		return true;
	};

	// NOTE:  not sure how to optimiaze better
	String.prototype.format = function()
	{
		var i;
		var re;
		var str;

		if( 0 === arguments.length )
		{
			return null;
		}

		str = this;

		re = new RegExp('\\%\\%' ,'gm');
		str = str.replace(re, '%');

		for(i = 1; i<arguments.length; i++)
		{
			re = new RegExp('\\{' + (i-1) + '\\}','gm');
			str = str.replace(re, arguments[i]);
		}

		return str;
	};

	// the string class doesn't have a builtin trim function
	String.prototype.trim = function()
	{
		var str = this;

		while (str.substring(0,1) == ' ')
		{
			str = str.substring(1, str.length);
		}

		while (str.substring(str.length-1, str.length) == ' ')
		{
			str = str.substring(0,str.length-1);
		}
		return str;
	};

	String.format = function()
	{
		var i;
		var re;
		var str;

		if( 0 === arguments.length )
		{
			return null;
		}

		str = arguments[0];

		re = new RegExp('\\%\\%' ,'gm');
		str = str.replace(re, '%');

		for(i = 1; i<arguments.length; i++)
		{
			re = new RegExp('\\%' + (i) ,'gm');
			str = str.replace(re, arguments[i]);
		}

		return str;
	};

	String.formatLoc = function()
	{
		var i;
		var re;
		var str;

		if( 0 === arguments.length )
		{
			return null;
		}

		str = LocString( arguments[0] );

		re = new RegExp('\\%\\%' ,'gm');
		str = str.replace(re, '%');

		for(i = 1; i<arguments.length; i++)
		{
			re = new RegExp('\\%' + (i) ,'gm');
			str = str.replace(re, arguments[i]);
		}

		return str;
	};

	//--------------------------------------------------------------------------------------------
	// Array extensions

	// Array.push() - Add an element to the end of an array, return the new length
	if( typeof Array.prototype.push==='undefined' )
	{
		Array.prototype.push = function()
		{
			for( var i = 0, b = this.length, a = arguments, l = a.length; i<l; i++ )
			{
				this[b+i] = a[i];
			}
			return this.length;
		};
	}

	// Array.indexOf( value, begin, strict ) - Return index of the first element that matches value
	Array.prototype.indexOf = function( v, b, s )
	{
		for( var i = +b || 0, l = this.length; i < l; i++ )
		{
			if( this[i]===v || s && this[i]==v )
			{
				return i;
			}
		}
 		return -1;
	};

	// Array.unique( strict ) - Remove duplicate values
	Array.prototype.unique = function( b )
	{
		var i;

		var a = [];
		var l = this.length;

 		for( i=0; i<l; i++ )
 		{
			if( a.indexOf( this[i], 0, b ) < 0 )
			{
				a.push( this[i] );
			}
 		}
 		return a;
	};

	// Localization strings support function
	//--------------------------------------------------------------------------------------------
	/* Private */
	var _testkeyon = false;


	// -- LocString --
	//
	// Gets a localized string. If no string is found or an error occurs, returns
	// the key.
	//
	// Parameters
	//   key - key of string to fetch
	//
	// Returns
	//   localized string, or key on failure
	//
	function LocString(key)
	{
	        try
	        {
	                var ret = lStr[key];
	                if (ret === undefined)
	                {
	                	ret = key;
	                }

	                if ( _testkeyon )
	                {
	                	return "\u00FC" + ret;
	                }

	                return ret;
	        }
	        catch (ex)
	        {
	                // Do nothing.
	                return "NO TRANSLATION: " + key;
	        }

	        return key;
	}

	function setLocalizationTestKeyOn()
	{
		_testkeyon = true;
	}

	// Localization strings support function
	//--------------------------------------------------------------------------------------------

	function exceptionAlert( e, msg )
	{

		var outStr = "An exception occurred in the script." +
					"\nError name: " + e.name +
					"\nError description: " + e.description +
					"\nError number: " + e.number +
					"\nError message: " + e.message;

		if ( null !== msg )
		{
			outStr += "\nDetails: " + msg;
		}

		alert ( outStr );
	}

