// ///// <DATETIME>
Ext.CP.Utils.getLocalTimeZone = function() {
	var d = new Date();
	var tz = d.getTimezoneOffset();
	return (-tz / 60);
}
Ext.CP.Utils.DMY2Unixtime = function(str) {
	var p = / +/;
	var date_part = '';
	var time_part = '';
	var date_parts = null;
	var time_parts = null;
	var parts = str.split(p);
	date_part = parts[0];
	var humDate = null;

	if (parts.length > 1)
		time_part = parts[1];

	p = /[\-\/]/;
	date_parts = date_part.split(p);

	if (time_part != '') {
		p = /[:]+/;
		time_parts = time_part.split(p);
	}

	if (time_part != '') {

		humDate = new Date(date_parts[2], date_parts[1] - 1, date_parts[0], time_parts[0], time_parts[1], time_parts[2]);
	}
	else {
		humDate = new Date(date_parts[2], date_parts[1] - 1, date_parts[0]);
	}

	return (humDate.getTime() / 1000.0);
}
Ext.CP.Utils.DMY2YMD = function(str) {
	var p = / +/;
	var date_part = '';
	var time_part = '';
	var date_parts = null;
	var time_parts = null;
	var parts = str.split(p);
	date_part = parts[0];
	if (parts.length > 1)
		time_part = parts[1];
	p = /[\-\/]/;
	date_parts = date_part.split(p);

	return Ext.CP.Utils.trim(date_parts[2] + '-' + date_parts[1] + '-' + date_parts[0] + ' ' + time_part);
}
Ext.CP.Utils.unixtime2DMY = function(ut, f) {
	// fix ugly time
	if (ut < 1000) {
		return '--';
	}
	var theDate = new Date(ut * 1000);
	var dd = theDate.getDate();
	if (dd < 10) {
		dd = '0' + dd;
	}
	var day = theDate.getDay();
	if (day < 10) {
		day = '0' + day;
	}
	var mm = theDate.getMonth() + 1;
	if (mm < 10) {
		mm = '0' + mm;
	}
	var yy = theDate.getFullYear();
	var h = theDate.getHours();
	if (h < 10) {
		h = '0' + h;
	}
	var m = theDate.getMinutes();
	if (m < 10) {
		m = '0' + m;
	}
	var s = theDate.getSeconds();
	if (s < 10) {
		s = '0' + s;
	}
	if (f) {
		var weekday = new Array(7);
		weekday[0] = "Sun";
		weekday[1] = "Mon";
		weekday[2] = "Tue";
		weekday[3] = "Wed";
		weekday[4] = "Thu";
		weekday[5] = "Fri";
		weekday[6] = "Sat";

		return weekday[day] + ' ' + dd + '/' + mm;
	}

	if (h != 0 || m != 0 || s != 0)
		return dd + '-' + mm + '-' + yy + ' ' + h + ':' + m + ':' + s;
	else
		return dd + '-' + mm + '-' + yy;
}
Ext.CP.Utils.time = function(milisec) {
	var date = new Date();
	var unixtime = null;
	if (milisec)
		unixtime = date.getTime();
	else
		unixtime = Math.round(date.getTime() / 1000);
	return unixtime;
}

// ///// <STRING>
Ext.CP.Utils.trim = function(str) {
	str = str.replace(/^\s+/, '');
	str = str.replace(/\s+$/, '');
	return str;
}
// // Cookies
Ext.CP.Utils.setCookie = function(name, value, seconds) {
	if (typeof(seconds) != 'undefined') {
		var date = new Date();
		date.setTime(date.getTime() + (seconds * 1000));
		var expires = "; expires=" + date.toGMTString();
	}
	else {
		var expires = "";
	}
	document.cookie = name + "=" + value + expires + "; path=/";
}
Ext.CP.Utils.clearCookie = function(name) {
	Ext.CP.Utils.setCookie(name, '', -1);
}
Ext.CP.Utils.getCookie = function(name) {
	name = name + "=";
	var carray = document.cookie.split(';');

	for (var i = 0; i < carray.length; i++) {
		var c = carray[i];
		while (c.charAt(0) == ' ')
			c = c.substring(1, c.length);
		if (c.indexOf(name) == 0)
			return c.substring(name.length, c.length);
	}

	return null;
}

Ext.CP.Utils.md5 = function(string) {

	function _RotateLeft(lValue, iShiftBits) {
		return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
	}

	function _AddUnsigned(lX, lY) {
		var lX4, lY4, lX8, lY8, lResult;
		lX8 = (lX & 0x80000000);
		lY8 = (lY & 0x80000000);
		lX4 = (lX & 0x40000000);
		lY4 = (lY & 0x40000000);
		lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
		if (lX4 & lY4) {
			return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
		}
		if (lX4 | lY4) {
			if (lResult & 0x40000000) {
				return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
			}
			else {
				return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
			}
		}
		else {
			return (lResult ^ lX8 ^ lY8);
		}
	}

	function _F(x, y, z) {
		return (x & y) | ((~x) & z);
	}
	function _G(x, y, z) {
		return (x & z) | (y & (~z));
	}
	function _H(x, y, z) {
		return (x ^ y ^ z);
	}
	function _I(x, y, z) {
		return (y ^ (x | (~z)));
	}

	function _FF(a, b, c, d, x, s, ac) {
		a = _AddUnsigned(a, _AddUnsigned(_AddUnsigned(_F(b, c, d), x), ac));
		return _AddUnsigned(_RotateLeft(a, s), b);
	};

	function _GG(a, b, c, d, x, s, ac) {
		a = _AddUnsigned(a, _AddUnsigned(_AddUnsigned(_G(b, c, d), x), ac));
		return _AddUnsigned(_RotateLeft(a, s), b);
	};

	function _HH(a, b, c, d, x, s, ac) {
		a = _AddUnsigned(a, _AddUnsigned(_AddUnsigned(_H(b, c, d), x), ac));
		return _AddUnsigned(_RotateLeft(a, s), b);
	};

	function _II(a, b, c, d, x, s, ac) {
		a = _AddUnsigned(a, _AddUnsigned(_AddUnsigned(_I(b, c, d), x), ac));
		return _AddUnsigned(_RotateLeft(a, s), b);
	};

	function _ConvertToWordArray(string) {
		var lWordCount;
		var lMessageLength = string.length;
		var lNumberOfWords_temp1 = lMessageLength + 8;
		var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
		var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
		var lWordArray = Array(lNumberOfWords - 1);
		var lBytePosition = 0;
		var lByteCount = 0;
		while (lByteCount < lMessageLength) {
			lWordCount = (lByteCount - (lByteCount % 4)) / 4;
			lBytePosition = (lByteCount % 4) * 8;
			lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
			lByteCount++;
		}
		lWordCount = (lByteCount - (lByteCount % 4)) / 4;
		lBytePosition = (lByteCount % 4) * 8;
		lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
		lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
		lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
		return lWordArray;
	};

	function _WordToHex(lValue) {
		var _WordToHexValue = "", _WordToHexValue_temp = "", lByte, lCount;
		for (lCount = 0; lCount <= 3; lCount++) {
			lByte = (lValue >>> (lCount * 8)) & 255;
			_WordToHexValue_temp = "0" + lByte.toString(16);
			_WordToHexValue = _WordToHexValue + _WordToHexValue_temp.substr(_WordToHexValue_temp.length - 2, 2);
		}
		return _WordToHexValue;
	};

	function _Utf8Encode(string) {
		string = string.replace(/\r\n/g, "\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if ((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	};

	var x = Array();
	var k, AA, BB, CC, DD, a, b, c, d;
	var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
	var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
	var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
	var S41 = 6, S42 = 10, S43 = 15, S44 = 21;

	string = _Utf8Encode(string);
	x = _ConvertToWordArray(string);
	a = 0x67452301;
	b = 0xEFCDAB89;
	c = 0x98BADCFE;
	d = 0x10325476;

	for (k = 0; k < x.length; k += 16) {
		AA = a;
		BB = b;
		CC = c;
		DD = d;
		a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
		d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
		c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
		b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
		a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
		d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
		c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
		b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
		a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
		d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
		c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
		b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
		a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
		d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
		c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
		b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
		a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
		d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
		c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
		b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
		a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
		d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
		c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
		b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
		a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
		d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
		c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
		b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
		a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
		d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
		c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
		b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
		a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
		d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
		c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
		b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
		a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
		d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
		c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
		b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
		a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
		d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
		c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
		b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
		a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
		d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
		c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
		b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
		a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
		d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
		c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
		b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
		a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
		d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
		c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
		b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
		a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
		d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
		c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
		b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
		a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
		d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
		c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
		b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
		a = _AddUnsigned(a, AA);
		b = _AddUnsigned(b, BB);
		c = _AddUnsigned(c, CC);
		d = _AddUnsigned(d, DD);
	}

	var temp = _WordToHex(a) + _WordToHex(b) + _WordToHex(c) + _WordToHex(d);

	return temp.toLowerCase();
};
// // .encode/.decode
Ext.CP.Utils.base64 = function() {
	var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

	function _utf8_encode(string) {
		string = string.replace(/\r\n/g, "\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if ((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	}
	function _utf8_decode(utftext) {
		var string = "";
		var i = 0;
		var c = 0;
		var c1 = 0;
		var c2 = 0;

		while (i < utftext.length) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if ((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i + 1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i + 1);
				var c3 = utftext.charCodeAt(i + 2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

	return {
		// public method for encoding
		encode: function(input) {
			var output = "";
			var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
			var i = 0;

			input = _utf8_encode(input);

			while (i < input.length) {

				chr1 = input.charCodeAt(i++);
				chr2 = input.charCodeAt(i++);
				chr3 = input.charCodeAt(i++);

				enc1 = chr1 >> 2;
				enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
				enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
				enc4 = chr3 & 63;

				if (isNaN(chr2)) {
					enc3 = enc4 = 64;
				}
				else if (isNaN(chr3)) {
					enc4 = 64;
				}

				output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

			}

			return output;
		},
		// public method for decoding
		decode: function(input) {
			var output = "";
			var chr1, chr2, chr3;
			var enc1, enc2, enc3, enc4;
			var i = 0;

			input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

			while (i < input.length) {

				enc1 = this._keyStr.indexOf(input.charAt(i++));
				enc2 = this._keyStr.indexOf(input.charAt(i++));
				enc3 = this._keyStr.indexOf(input.charAt(i++));
				enc4 = this._keyStr.indexOf(input.charAt(i++));

				chr1 = (enc1 << 2) | (enc2 >> 4);
				chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
				chr3 = ((enc3 & 3) << 6) | enc4;

				output = output + String.fromCharCode(chr1);

				if (enc3 != 64) {
					output = output + String.fromCharCode(chr2);
				}
				if (enc4 != 64) {
					output = output + String.fromCharCode(chr3);
				}

			}

			output = _utf8_decode(output);

			return output;

		}
	}
}();

// Formats a number with grouped thousands  
// 
// version: 1009.820
// discuss at: http://phpjs.org/functions/number_format    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// +     bugfix by: Michael White (http://getsprink.com)
// +     bugfix by: Benjamin Lupton
// +     bugfix by: Allan Jensen (http://www.winternet.no)    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// +     bugfix by: Howard Yeend
// +    revised by: Luke Smith (http://lucassmith.name)
// +     bugfix by: Diogo Resende
// +     bugfix by: Rival    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
// +   improved by: davook
// +   improved by: Brett Zamir (http://brett-zamir.me)
// +      input by: Jay Klehr
// +   improved by: Brett Zamir (http://brett-zamir.me)    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
// +     bugfix by: Brett Zamir (http://brett-zamir.me)
// +   improved by: Theriault
// +      input by: Amirouche
// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)    // *     example 1: number_format(1234.56);
// *     returns 1: '1,235'
// *     example 2: number_format(1234.56, 2, ',', ' ');
// *     returns 2: '1 234,56'
// *     example 3: number_format(1234.5678, 2, '.', '');    // *     returns 3: '1234.57'
// *     example 4: number_format(67, 2, ',', '.');
// *     returns 4: '67,00'
// *     example 5: number_format(1000);
// *     returns 5: '1,000'    // *     example 6: number_format(67.311, 2);
// *     returns 6: '67.31'
// *     example 7: number_format(1000.55, 1);
// *     returns 7: '1,000.6'
// *     example 8: number_format(67000, 5, ',', '.');    // *     returns 8: '67.000,00000'
// *     example 9: number_format(0.9, 0);
// *     returns 9: '1'
// *    example 10: number_format('1.20', 2);
// *    returns 10: '1.20'    // *    example 11: number_format('1.20', 4);
// *    returns 11: '1.2000'
// *    example 12: number_format('1.2000', 3);
// *    returns 12: '1.200'
// *    example 13: number_format('1 000,50', 2, '.', ' ');    // *    returns 13: '100 050.00'
Ext.CP.Utils.formatMoney = function(num, c, d, t, sign)// as (num,2,'.',"'")
{
	// Alias with old method
	number = num;
	decimals = c;
	dec_point = t;
	thousands_sep = d;

	number = (number + '').replace(',', '').replace(' ', '');
	var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, s = '', toFixedFix = function(n, prec) {
		var k = Math.pow(10, prec);
		return '' + Math.round(n * k) / k;
	};
	// Fix for IE parseFloat(0.55).toFixed(0) = 0;
	s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
	if (s[0].length > 3) {
		s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
	}
	if ((s[1] || '').length < prec) {
		s[1] = s[1] || '';
		s[1] += new Array(prec - s[1].length + 1).join('0');
	}
	return s.join(dec) + (sign ? ' ' + sign : ($CFG.money_sign ? ' ' + $CFG.money_sign : ''));
}
Ext.CP.Utils.isEmail = function(txt) {
	return /[a-zA-Z0-9_&]+([a-zA-Z0-9\-\.&~\$]+)*@([a-zA-Z0-9\-_]+\.)+[a-zA-Z]+/.test(txt);
}
Ext.CP.Utils.isPhone = function(txt) {
	return /[\d\s\(\)]{7,}/.test(txt);
}
Ext.CP.Utils.isURL = function(txt) {
	return /(http(s)?:\/\/)?([a-zA-Z0-9_\-]+\.)+[a-zA-Z]{2,4}([\/\?].*)?/.test(txt);
}

Ext.CP.Utils.parseQueryString = function(_1) {
	var _2 = {};
	if (_1 == undefined) {
		_1 = location.search ? location.search : "";
	}
	if (_1.charAt(0) == "?") {
		_1 = _1.substring(1);
	}
	_1 = _1.replace("+", " ");
	var _3 = _1.split(/[&;]/g);
	for (var i = 0; i < _3.length; i++) {
		var _5 = _3[i].split("=");
		var _6 = decodeURIComponent(_5[0]);
		var _7 = decodeURIComponent(_5[1]);
		if (!_2[_6]) {
			_2[_6] = [];
		}
		_2[_6].push((_5.length == 1) ? "" : _7);
	}
	return _2;
}
Ext.CP.Utils.urlChangeQueryParams = function(cfg) {

	var url = null;
	if (cfg.url)
		url = cfg.url;
	else
		url = location.href;

	var anchor = url.match(/#.+$/);
	if (anchor && anchor[0]) {
		anchor = anchor[0];
		url = url.replace(/#.+$/, "");
	}
	else
		anchor = "";

	var part = url.split(/\?/);

	if (part.length == 1)
		return url + "?" + Ext.urlEncode(cfg.params) + anchor;
	else {
		var queries = Ext.urlDecode(part[1]);
		for (var i in cfg.params) {
			queries[i] = cfg.params[i];
		}
		return part[0] + "?" + Ext.urlEncode(queries) + anchor;
	}

}

/*
 * %%->% ; %s ; %n.mf ( %.2f || % 3.2f ) format Ext.CP.Utils.sprintf ("Decimal
 * %+05d, Float %07.2f, String '%-10.4s', Hexadecimal %05X", 123, 123.056,
 * 'abcdefg', -123123)
 */
Ext.CP.Utils.sprintf = function() {

	function _convert(match, nosign) {
		if (nosign) {
			match.sign = '';
		}
		else {
			match.sign = match.negative ? '-' : match.sign;
		}
		var l = match.min - match.argument.length + 1 - match.sign.length;
		var pad = new Array(l < 0 ? 0 : l).join(match.pad);
		if (!match.left) {
			if (match.pad == "0" || nosign) {
				return match.sign + pad + match.argument;
			}
			else {
				return pad + match.sign + match.argument;
			}
		}
		else {
			if (match.pad == "0" || nosign) {
				return match.sign + match.argument + pad.replace(/0/g, ' ');
			}
			else {
				return match.sign + match.argument + pad;
			}
		}
	}

	if (typeof arguments == "undefined") {
		return null;
	}
	if (arguments.length < 1) {
		return null;
	}
	if (typeof arguments[0] != "string") {
		return null;
	}
	if (typeof RegExp == "undefined") {
		return null;
	}

	var string = arguments[0];
	var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
	var matches = new Array();
	var strings = new Array();
	var convCount = 0;
	var stringPosStart = 0;
	var stringPosEnd = 0;
	var matchPosEnd = 0;
	var newString = '';
	var match = null;

	while (match = exp.exec(string)) {
		if (match[9]) {
			convCount += 1;
		}

		stringPosStart = matchPosEnd;
		stringPosEnd = exp.lastIndex - match[0].length;
		strings[strings.length] = string.substring(stringPosStart, stringPosEnd);

		matchPosEnd = exp.lastIndex;
		matches[matches.length] = {
			match: match[0],
			left: match[3] ? true : false,
			sign: match[4] || '',
			pad: match[5] || ' ',
			min: match[6] || 0,
			precision: match[8],
			code: match[9] || '%',
			negative: parseInt(arguments[convCount]) < 0 ? true : false,
			argument: String(arguments[convCount])
		};
	}
	strings[strings.length] = string.substring(matchPosEnd);

	if (matches.length == 0) {
		return string;
	}
	if ((arguments.length - 1) < convCount) {
		return null;
	}

	var code = null;
	var match = null;
	var i = null;
	var substitution = null;

	for (i = 0; i < matches.length; i++) {

		if (matches[i].code == '%') {
			substitution = '%'
		}
		else if (matches[i].code == 'b') {
			matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
			substitution = _convert(matches[i], true);
		}
		else if (matches[i].code == 'c') {
			matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
			substitution = _convert(matches[i], true);
		}
		else if (matches[i].code == 'd') {
			matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
			substitution = _convert(matches[i]);
		}
		else if (matches[i].code == 'f') {
			matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
			substitution = _convert(matches[i]);
		}
		else if (matches[i].code == 'o') {
			matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
			substitution = _convert(matches[i]);
		}
		else if (matches[i].code == 's') {
			matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
			substitution = _convert(matches[i], true);
		}
		else if (matches[i].code == 'x') {
			matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
			substitution = _convert(matches[i]);
		}
		else if (matches[i].code == 'X') {
			matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
			substitution = _convert(matches[i]).toUpperCase();
		}
		else {
			substitution = matches[i].match;
		}

		newString += strings[i];
		newString += substitution;

	}
	newString += strings[i];

	return newString;

}
