/*
 * ########											- number up to 8 digits long
 * @@@@@@@@											- zero filled number 8 digits long
 * ###,###,###										- number with thousands seperator
 * ###,###,###.##									- number with thousands seperator with forced decimal place
 * [$]###,###,###.@@								- currency, thousands seperator, forced decimal place & fixed precision
 * [$]###,###,###<.##>								
 * [$]###,###,###<.@@>
 * [$]###,###,###<.@@>[ / week]
 * {\(@@\)} ####-####
 * #### ### ###
 * +@@ # ####-####
 * +@@ # ####-####|{\(@@\)} ####-####
 * +@@ # ####-####|#### ### ###|{\(@@\)} ####-####
 * #### ### ###|{\(@@\)|## #} ####-####
 * (,\e4)(#\r3)										- number with recurring 3 digits with commas every 4 places
 * (,\e4)(@\n10)									- zero filled number 10 digits long with commas every 4 places
 * [$](,\e4)(#\r3)<.@@>[ / week]					- currency format
 *
 */

String.prototype.fix		= fix;
String.prototype.process	= process;
String.prototype.numberFix	= numberFix;


//
//
//
//
function matchObj( slots, matched, result )
{
	this.slots		= slots;
	this.matched	= matched;
	this.result		= result;
}

//
//
//
//
function fix( format )
{
	var	section = new Array;


	if ( format.match( /[^\|]\|/ ) )
	{
		var	pos	= 0;

		for( var i = 0; i < format.length; i++ )
		{
			var	chr = format.substring( i, i + 1 );

			if ( chr == "|" || i == format.length - 1 )
			{
				if ( i == format.length - 1 )
					i++;

				arr = this.process( this, format.substring( pos, i ) );
				section.push( new matchObj( arr[0], arr[1], arr[2] ) );
				pos = i + 1;
			}
		}

		maximum	= 0;
		current	= -1;

		for( var i = section.length - 1; i >= 0; i-- )
			if ( section[i].matched >= maximum )
				if ( current != -1 )
				{
					if ( section[current].slots - section[current].matched >= section[i].slots - section[i].matched )
					{
						maximum = section[i].matched;
						current = i;
					}
				}
				else
				{
					maximum = section[i].matched;
					current = i;
				}

		return section[current].result;
	}
	else
	{
		tmp = this.process( this, format );
		return tmp[2];
	}
}

//
//
//
//
function process( source, format )
{
	var	bracket_square	= false,
		bracket_round	= false,
		bracket_curly	= false,
		zero_continue	= false,
		no_decimal		= false,
		matched			= 0,
		slots			= 0,
		pos				= 0,
		fill			= "                    ",
		str				= "";

	// remove everything from the source string except for digits and decimal points
	source = (source.replace( /[^\d\.]/, "" )).replace( /\.+/, "." );

	// check for decimal point in source and none in format
	if ( source.match( /\./ ) && ! format.match( /\./ ) )
		source = source.replace( /\..*/, "" );

	// fix up decimal places
	if ( format.match( /\./ ) )
	{
		tmp1 = format.match( /\.([#@]+)/ );
		tmp2 = String( source.numberFix( source, tmp1[1].length ) );
		tmp3 = tmp2.match( /\.(\d+)/ );

		if ( tmp3 )
		{
			source = tmp2 + fill.substring( 0, tmp1[1].length - tmp3[1].length );
			zero_continue = true;
		}
		else
		{
			source = source.replace( /\..*/, "" );
			source = source + "." + fill.substring( 0, tmp1[1].length );
			no_decimal = true;
		}
	}

	pos = source.length - 1;

	for( var i = format.length - 1; i >= 0; i-- )
	{
		cmp = format.substring( i, i + 1 );
		chr = source.substring( pos, pos + 1 );
		c	= null;

		switch( cmp )
		{
			case "\\":
				break;

			case "#":
				if ( chr )
				{
					if ( chr == " " )
						pos--;
					else
					{
						c = chr;
						pos--;
						matched++;
						no_decimal = false;
					}
				}
				slots++;
				break;

			case "@":
				if ( chr )
				{
					if ( chr == " " )
						c = "0";
					else
						c = chr;

					pos--;
					zero_continue = true;
					no_decimal = false;
					matched++;
				}
				else
				{
					if ( ! zero_continue )
					{
						slots++;
						break;
					}

					matched++;
					c = "0";
				}
				slots++;
				break;

			case "}":
				if ( chr )
					bracket_curly = true;
				break;

			case "{":
				bracket_curly = false;
				break;

			case "]":
				bracket_square = true;
				break;

			case "[":
				bracket_square = false;
				break;

			case ".":
				if ( ! no_decimal )
					c = ".";

				pos--;
				break;

			default:
				if ( chr || bracket_curly || bracket_square )
				{
					c = cmp;

					if ( chr == cmp && chr != " " )
					{
						pos--;
						matched++;
					}
				}
				break;
		}

		if ( c )
			str = c + str;
	}

	return new Array( slots, matched, str );
}

//
// number fix method
//
//
function numberFix( num, places )
{
	cordec = Math.pow( 10, places );
	return Math.round( parseFloat( num ) * cordec ) / cordec;
}

