/*
---

name: "Types.String"

description: "Contains string-manipulation methods like repeat, substitute, replaceAll and begins."

license:
	- "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
	- "[MIT License](http://opensource.org/licenses/mit-license.php)"

requires:
	- Core

provides: Types.String

...
*/

new function () {

var UID = Date.now();

atom.string = {
	/**
	 * @returns {string} - unique for session value in 36-radix
	 */
	uniqueID: function () {
		return (UID++).toString(36);
	},
	/**
	 * escape all html unsafe characters - & ' " < >
	 * @param {string} string
	 * @returns {string}
	 */
	safeHtml: function (string) {
		return this.replaceAll(string, /[<'&">]/g, {
			'&'  : '&amp;',
			'\'' : '&#039;',
			'\"' : '&quot;',
			'<'  : '&lt;',
			'>'  : '&gt;'
		});
	},
	/**
	 * repeat string `times` times
	 * @param {string} string
	 * @param {int} times
	 * @returns {string}
	 */
	repeat: function(string, times) {
		return new Array(times + 1).join(string);
	},
	/**
	 * @param {string} string
	 * @param {Object} object
	 * @param {RegExp} [regexp=null]
	 * @returns {string}
	 */
	substitute: function(string, object, regexp){
		return string.replace(regexp || /\\?\{([^{}]+)\}/g, function(match, name){
			return (match[0] == '\\') ? match.slice(1) : (object[name] == null ? '' : object[name]);
		});
	},
	/**
	 * @param {string} string
	 * @param {Object|RegExp|string} find
	 * @param {Object|string} [replace=null]
	 * @returns {String}
	 */
	replaceAll: function (string, find, replace) {
		if (toString.call(find) == '[object RegExp]') {
			return string.replace(find, function (symb) { return replace[symb]; });
		} else if (typeof find == 'object') {
			for (var i in find) string = this.replaceAll(string, i, find[i]);
			return string;
		}
		return string.split(find).join(replace);
	},
	/**
	 * Checks if string contains such substring
	 * @param {string} string
	 * @param {string} substr
	 */
	contains: function (string, substr) {
		return string ? string.indexOf( substr ) >= 0 : false;
	},
	/**
	 * Checks if string begins with such substring
	 * @param {string} string
	 * @param {string} substring
	 * @param {boolean} [caseInsensitive=false]
	 * @returns {boolean}
	 */
	begins: function (string, substring, caseInsensitive) {
		if (!string) return false;
		return (!caseInsensitive) ? substring == string.substr(0, substring.length) :
			substring.toLowerCase() == string.substr(0, substring.length).toLowerCase();
	},
	/**
	 * Checks if string ends with such substring
	 * @param {string} string
	 * @param {string} substring
	 * @param {boolean} [caseInsensitive=false]
	 * @returns {boolean}
	 */
	ends: function (string, substring, caseInsensitive) {
		if (!string) return false;
		return (!caseInsensitive) ? substring == string.substr(string.length - substring.length) :
			substring.toLowerCase() == string.substr(string.length - substring.length).toLowerCase();
	},
	/**
	 * Uppercase first character
	 * @param {string} string
	 * @returns {string}
	 */
	ucfirst : function (string) {
		return string ? string[0].toUpperCase() + string.substr(1) : '';
	},
	/**
	 * Lowercase first character
	 * @param {string} string
	 * @returns {string}
	 */
	lcfirst : function (string) {
		return string ? string[0].toLowerCase() + string.substr(1) : '';
	}
};

}();