/*
 * string_enh.js
 *
 * Copyright (C) 2006 - OS3 srl - http://www.os3.it
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
// PUBLIC: startsWith
String.prototype.startsWith = function ( str )
{
	if ( this.substr ( 0, str.length ) == str ) return ( true );
	
	return ( false );
};

// PUBLIC: endsWith
String.prototype.endsWith = function ( str )
{
	if ( this.substr ( -str.length ) == str ) return ( true );
	
	return ( false );
};

// PUBLIC: join
String.prototype.join = function ( arr )
{
	var l = arr.length;
	var k, t;
	var s = '';
	var is_first = true;

	for ( t = 0; t < l; t ++ )
	{
		if ( ! is_first ) s += this;
		s += arr [ t ];
		is_first = false;
	}

	return s;
};

// PUBLIC: LStrip
String.prototype.LStrip = function ()
{
	var p = 0;

	while ( ( this [ p ] == ' ' ) || ( this [ p ] == '\t' ) || ( this [ p ] == '\n' ) || ( this [ p ] == '\r' ) ) p++;

	return this.substr ( p );
};

// PUBLIC: RStrip
String.prototype.RStrip = function ()
{
	var p = this.length-1;

	while ( ( this [ p ] == ' ' ) || ( this [ p ] == '\t' ) || ( this [ p ] == '\n' ) || ( this [ p ] == '\r' ) ) p--;

	return this.substr ( 0, p+1 );
};

// PUBLIC: Strip
String.prototype.Strip = function () { return this.LStrip ().RStrip (); };

// PUBLIC: isUpper
String.prototype.isUpper = function () 
{
	var l = this.length;
	var c, t;

	if ( ! l ) return false;

	for ( t = 0; t < l; t ++ )
	{
		c = this [ t ].toUpperCase ();
		if ( c != this [ t ] ) return false;
	}

	return true;
	
};

// PUBLIC: isLower
String.prototype.isLower =  function () 
{
	var l = this.length;
	var c, t;

	if ( ! l ) return false;

	for ( t = 0; t < l; t ++ )
	{
		c = this [ t ].toLowerCase ();
		if ( c != this [ t ] ) return false;
	}

	return true;
	
};

// PUBLIC: format
String.format = function ()
{
	var re = /%([0+#-]*)([0-9]*)(\.{0,1})([0-9]*)([ds])/;
	var fmt = arguments [ 0 ];	// The first param is the string format
	var count = 0;
	var res = '';

	var matches;

	while ( ( matches = re.exec ( fmt ) ) )
	{
		count ++;
		fmt = RegExp.leftContext + _string_re_replace ( matches, arguments [ count ] ) + RegExp.rightContext;
	}

	return fmt;
}

// PUBLIC: formatDict
String.formatDict = function ()
{
	var re = /%\(([^)]*)\)([0+#-]*)([0-9]*)(\.{0,1})([0-9]*)([ds])/;
	var fmt = arguments [ 0 ];	// The first param is the string format
	var res = '';
	var f1, p1;

	var matches;

	while ( ( matches = re.exec ( fmt ) ) )
	{
		p1 = matches.shift ();
		f1 = matches.shift ();
		
		matches.unshift ( p1 );
		fmt = RegExp.leftContext + _string_re_replace ( matches, arguments [ 1 ] [ f1 ] ) + RegExp.rightContext;
	}

	return fmt;
}

function _string_re_replace ( matches,  value )
{
	var flags = matches [ 1 ];
	var width = ( matches [ 2 ] ? parseInt ( matches [ 2 ] ) : 0 );
	var precision = ( matches [ 4 ] ? parseInt ( matches [ 4 ] ) : 0 );
	var type = matches [ 5 ];
	var res = '';
	var pad_char = ' ';
	var pad_left = false;
	var show_sign = false;

	// alert ( matches + " - " + value + " - " + flags + " / " + width + " / " + precision  + "/" + type );
	// console.debug ( matches + " - " + value + " - " + flags + " / " + width + " / " + precision  + "/" + type );

	if ( flags.indexOf ( '-' ) >= 0 ) pad_left = true;
	if ( flags.indexOf ( '0' ) >= 0 ) pad_char = '0';
	if ( flags.indexOf ( '+' ) >= 0 ) show_sign = true;

	if ( pad_char == '0' && pad_left ) pad_char = ' ';

	switch ( type )
	{
		case 'd':
			res  = _string_mkpad ( true, value, precision, width, pad_char, false, pad_left, show_sign )
			break;

		case 's':
			res  = _string_mkpad ( false, value, precision, width, pad_char, true, pad_left, false )
			break;
	}

	return res;
}

function _string_mkpad ( is_num, v, prec, width, pad_char, trunc, pad_left, show_sign )
{
	var sign = '';

	if ( is_num )
	{
		v = parseInt ( v );
		if ( v < 0 ) sign = '-';
		else if ( show_sign ) sign = '+';

		v = Math.abs ( v );
	}

	v = String ( v );

	if ( ! width && ! prec ) return v;

	var len, t, i;

	if ( is_num )
	{
		len = prec - v.length;
		if ( len > 0 ) for ( t = 0; t < len; t ++ ) v = "0" + v;
	}

	v = sign + v;

	len = width - v.length;
	if ( len > 0 )
	{
		for ( t = 0; t < len; t ++ )
			v = ( pad_left ? v + pad_char : pad_char + v );
	}

	if ( ! is_num && prec )
	{
		return v.slice ( 0, prec );
	}

	return  v;
}
