function Trim( d )
{
	if ( typeof( d ) != 'string' )
		return d;
		
	while ( d.charAt( 0 ) == ' ' || d.charCodeAt( 0 ) == 160 )
		d = d.substr( 1 );
	while ( d.charAt( d.length - 1 ) == ' ' || d.charCodeAt( 0 ) == 160 )
		d = d.substr( 0, d.length - 1 );
			
	return d;
}

function IsNull( a, b ) { return ( typeof( a ) == 'undefined' || a == null ? b : a ); }
function IsNaN( a, b ) { return ( typeof( a ) == 'undefined' || isNaN( a ) || a == null ? b : a ); }

function Package( fields, data, elementid, escaped )
{
	this.data = data; 
	this.fields = fields; 
	this.length = data == null ? 0 : (data.length / fields.length);
	
	function KeyItem( fields, data, index )
	{
		this.Value = function( name )
		{
			name = name.toLowerCase();
			for ( var i = 0 ; i < fields.length ; i++ )
				if ( fields[ i ] == name )
					return data[ index + i ]
						
			return null;
		}
		
		this.SetValue = function( name, value )
		{
			name = name.toLowerCase();
			for ( var i = 0 ; i < fields.length ; i++ )
				if ( fields[ i ] == name )
					data[ index + i ] = value;
		}		
	}
	
	this.Item = function( index ) { return new KeyItem( this.fields, this.data, index * this.fields.length ); }
	this.Write = function() { return SafeJoin( [ SafeJoin( this.fields ), SafeJoin( this.data ) ] ); }
	this.Read = function( elementid, escaped ) 
	{ 
		var e = GetElement( elementid );
		var r = null;
		if ( e.tagName.toLowerCase() == 'input' )
			r = e.value;
		else
			r = e.innerHTML;
		
		if ( escaped )
			r = unescape( r );
		this.ReadBlock( r );
	}
	
	this.ReadBlock = function( r )
	{
		r = SafeSplit( r );
		this.fields = SafeSplit( r[ 0 ] );
		this.data = SafeSplit( r[ 1 ] );
		this.length = this.data.length / this.fields.length;
	}
	this.SetValue = function( index, name, value )
	{
		name = name.toLowerCase();
		for ( var i = 0 ; i < this.fields.length ; i++ )
			if ( this.fields[ i ] == name )
				break;
				
		this.data[ (index * this.fields.length) + i ] = value;
	}

	this.CopyItem = function( from, to )
	{
		from *= this.fields.length;
		to *= this.fields.length;
		for ( var i = 0 ; i < this.fields.length ; i++ )
			this.data[ to++ ] = this.data[ from++ ];
	}
	
	this.InsertAt = function( index )
	{
		if ( index == null )
			index = this.length;
			
		var i = index * this.fields.length;
		this.data = this.data.slice( 0, i ).concat( this.fields ).concat( this.data.slice( i ) );
		this.length += 1;
		
		return this.Item( index );
	}
	
	if ( elementid )
		this.Read( elementid, escaped );
}

function StringStream()
{
	this.s = '';
	this.Write = function( t ) { this.s += t; }
	this.String = function() { return this.s; }
	this.Close = function()	{}
}

function SafeJoin( a )
{
	if ( a == null || a.length == 0 )
		return '';

	var jn = 0;
	var joiners = ',. ;:|/&$#@!~*()<>[]{}abcdefg01234';
	var joiner = joiners.charAt( jn );
	var b = new Array;
	for ( var i = 0 ; i < a.length ; i++ )
	{
		if ( a[ i ] == null )
			b[ i ] = '';
		else if ( typeof( a[ i ] ) == 'boolean' )
			b[ i ] = (a[ i ] ? '1' : '0')
		else if ( typeof( a[ i ] ) != 'string' )
			b[ i ] = String( a[ i ] );
		else
			b[ i ] = a[ i ];
				
		if ( b[ i ].indexOf( joiner ) > -1 )
		{
			joiner = joiners.charAt( ++jn );
			for ( var j = 0 ; j <= i ; j++ )
				if ( b[ j ].indexOf( joiner ) > -1 )
					joiner = joiners.charAt( ++jn ), j = -1;
		}
	}
	
	return joiner + b.join( joiner );
}

function SafeSplit( a )
{
	if ( typeof( a ) != 'string' || a.length < 2 )
		return new Array;
		
	return a.substr( 1 ).split( a.charAt( 0 ) );
}

function Money( a, prefix, negparen )
// format with two decimal places
{
	if ( typeof( a ) != 'number' || isNaN( a ) )
		return '';

	var neg = false;
	
	if ( typeof( prefix ) == 'undefined' )
		prefix = '$';

	if ( a < 0 )
	{
		a = -a, neg = true;
		if ( typeof( negparen ) != 'boolean' )
			negparen = true;
	}

	a = (a + 0.000005).toString();
	
	var whole = a;
	var dec = '00';
	if ( a.indexOf( '.' ) >= 0 )
	{
		// already contains a decimal point
		a.match( /(\d*)\.(\d*)/ );
		whole = RegExp.$1;
		dec = RegExp.$2;
		if ( dec.length > 2 )
			dec = dec.substr( 0, 2 );
		while ( dec.length < 2 )
			dec += '0';
	}

	whole = NumberCommas( whole );
		
	if ( !neg )
		return prefix + whole + '.' + dec;

	if ( negparen )
		return '(' + prefix + whole + '.' + dec + ')';
		
	return prefix + '-' + whole + '.' + dec;
}

function NumberCommas( whole )
{
	whole = whole.toString();
	
	if ( whole.length > 6 )
		whole = whole.substr( 0, whole.length - 6 ) + ',' + whole.substr( whole.length - 6 );
	if ( whole.length > 3 )
		whole = whole.substr( 0, whole.length - 3 ) + ',' + whole.substr( whole.length - 3 );
	
	return whole;
}

function InputTable( inputs, withsubmit ) // prompt, name, type, value, size, or name is a function that returns a control
{
	var s = new StringStream();
	
	s.Write( '<table border=0 cellspacing=0 cellpadding=0>' );
			
	for ( var i = 0 ; i < inputs.length ; i++ )
	{
		s.Write( '<tr><td align="right"><p>' + inputs[ i ][ 0 ] + ':</td>'
				+ '<td><p>' );
				
		if ( typeof( inputs[ i ][ 2 ] ) == 'string' )
			s.Write( '<input type="' 
						+ inputs[ i ][ 2 ] 
						+ '" name="' 
						+ IsNull( inputs[ i ][ 1 ], inputs[ i ][ 0 ] ) 
						+ '" id="' 
						+ IsNull( inputs[ i ][ 1 ], inputs[ i ][ 0 ] ) 
						+ '" value="' 
						+ IsNull( inputs[ i ][ 3 ], '' ) + '" '
						+ ( inputs[ i ][ 4 ] != null ? 'size=' + inputs[ i ][ 4 ] + '" ' : '')
						+ 'class=tx>' );
		else
			s.Write( (inputs[ i ][ 2 ])() );
			
		s.Write( '</td></tr>' );
	}				
	if ( withsubmit )
		s.Write( '<tr><td></td><td><p><input type="submit" name="submit1" value="Submit" class="iv"></td></tr>' );
		
	s.Write( '</table></div>' );

	return s.String();
}

function SecondWindow( href, anchor, wndname, second, clss, w, h )
{
	if ( typeof( w ) == 'undefined' || w == null )
		w = 700;
		
	if ( typeof( h ) == 'undefined' || h == null )
		h = 500;
		
	if ( typeof( clss ) == 'undefined' )
		clss = '';

	if ( typeof( wndname ) != 'string' )
		wndname = 'Popup';
		
	if ( typeof( anchor ) != 'string' )
		anchor = href;
		
	if ( typeof( second ) != 'boolean' )
		second = true;

	href = href + (href.indexOf( '?' ) > 0 ? '&' : '?') + 'format=1&RNDN=' + Math.floor( Math.random() * 10000 );

	return second ?
			'<a class="' 
					+ clss + '" href="javascript:" onclick="javascript:window.open(\'' 
					+ href + '\',\'' 
					+ wndname + '\',\'width=' + w + ',height=' + h + ',status=no,toolbar=no,menubar=no,location=no,resizable=yes,scrollbars=yes\'); return false">'
					+ anchor
					+ '</a>' :
	
			'<a class="'
					+ clss + '" href="javscript:" onclick="javascript:window.open( \'' 
					+ href + '\',\'' 
					+ wndname + '\' ); return false;">' 
					+ anchor + '</a>';
}

