(function(window) {

	var iTim = window.iTim || {};

	iTim.Json = {
		serialize : function(obj) {
			return window.JSON.stringify(obj);
		},
		unserialize : function(str) {
			return window.JSON.parse(str);
		}
	};

	iTim.debug = iTim.debug === undefined ? true : iTim.debug;
	iTim.log = function(o) {
		if (this.debug && window.console)
			console.log.apply(console, arguments);
		return arguments[arguments.length - 1];
	};

	iTim.each = function(obj, fn) {
		if (obj.length) {
			for ( var i = 0, length = obj.length; i < length; ++i) {
				fn.call(obj[i], i, obj);
			}
		} else {
			for ( var i in obj)
				if (obj.hasOwnProperty(i)) {
					fn.call(obj[i], i, obj);
				}
		}
	};

	iTim.extend = function(obj) {
		for ( var i = 1, length = arguments.length; i < length; ++i) {
			for ( var p in arguments[i]) {
				obj[p] = arguments[i][p];
			}
		}
		return obj;
	};

	iTim.ns = function(ns, root, obj) {
		root = root || window;
		iTim.each(ns.split('.'), function() {
			root = root[this] = root[this] || {};
		});
		if (obj) {
			this.extend(root, obj);
		}
		return root;
	};

	iTim.regexTrimRemove = /^\s+|\s+$/g;
	iTim.regexTrimCondense = /\s+/g;
	iTim.trim = function(s) {
		s = (s || '').replace(this.regexTrimRemove, '');
		s = s.replace(this.regexTrimCondense, ' ');
		return s;
	};

	iTim.object = function(obj) {
		var F = function() {};
		F.prototype = obj;
		return new F();
	};

	iTim.regexPlaceholder = /(\\?)\{(\d+)\}/g;
	iTim.format = function(template) {
		var args = arguments;
		return template.replace(this.regexPlaceholder, function(match, escapeStart, name) {
			if (escapeStart) {
				return match;
			}
			return args[++name];
		});
	};

	iTim.bind = function(fn, scope) {
		return function() {
			return fn.apply(scope, arguments);
		};
	};

	window.iTim = iTim;

})(this.window);

