/**
  *  String extension methods.
  *
  *  Copyright (c) 2008 Roman Zaharenkov
  *  Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
  *  and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  *
  *  	CSharp like string format. Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
  *	
  *	Example:
  *		String.format('Format {0} example with {1} arguments.', ['string', 2]);		
  *	
  *  	CSharp like string builder. This class represents a string-like object whose value is a mutable sequence of characters.
  *
  *	 Example:
  *		style = new StringBuilder();
  *		style.appendFormat('width:{0}px;', [this.settings.width]);				
  *		style.appendFormat('margin-left:-{0}px;', [this.settings.width / 2]);
  *		style.appendFormat('top:{0}px;', [this.settings.top]);
  *		style.appendFormat('left:{0};', ['50%']);
  *		return style.toString();	
  */
	
/**	
  * 	Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
  * 	Paramaters:
  *		template - A composite format string.
  *	     args - An Object array containing zero or more objects to format. 
  */	
String.format = function(template, args) {

	result = template;
	
	for (i in args) {      
		result = result.replace(new RegExp('\\{' + i + '\\}', 'gm'), args[i]);
	}

	return result;
};

/**	
  * 	Replaces each format item in a specified String with the text equivalent of a corresponding object's value.
  * 	Paramaters:
  *		template - A composite format string.
  *	     args - An Object array containing zero or more objects to format. 
  */	
String.prototype.format = function(args) {    

	result = this;
	
	for (i in args) {      
		result = result.replace(new RegExp('\\{' + i + '\\}', 'gm'), args[i]);
	}

	return result;
};

/**	
  *  	CSharp like string builder. This class represents a string-like object whose value is a mutable sequence of characters.
  */
StringBuilder = function(value) {
	this.strings = new Array();
	this.append(value);
};

StringBuilder.prototype = {
	
	/**
	*   Appends the string representation of a specified object to the end of this instance.
	* 	Paramaters:
	*		value - The object to append. 
	*/	
	append : function (value) {
		if (value) { 
			this.strings.push(value); 
		}
	},	
	
	/**
	*	Appends a formatted string, which contains zero or more format specifications, to this instance. Each format specification is replaced by the string representation of a corresponding object argument.
	* 	Paramaters:
	*		template - A composite format string.
	*	     args - An Object array containing zero or more objects to format. 
	*/
	appendFormat : function (template, args) {
		this.append(String.format(template, args));
	},

	/**
	*	Clears the instance.
	*/
	clear : function () {
		this.strings.length = 0;
	},
	
	/**
	*	 Converts the value of a StringBuilder to a String.
	*/
	toString : function () {
		return this.strings.join('');
	}
};

/**
  *  Function extension methods.
  *
  *  Copyright (c) 2008 Roman Zaharenkov
  *  Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
  *  and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  *
  *  Provides methods for delegates and callback creation.
  */	
	
Function.createDelegate = function(instance, instanceMethod) {
	return function() {
		instanceMethod.apply(instance, arguments);
	}
}

Function.createCallback = function(instanceMethod, context) {
	return function() {
		var argcount = arguments.length;
		if (argcount > 0) {
			var args = new Array(argcount + 1);
			for (var i = 0; i < l; i++) {
				args[i] = arguments[i];
			}
			args[l] = context;
			return method.apply(this, args);
		}
		return method.call(this, context);	
	}
}