var cTemplate = {

	parse: function(sTemplate, oData) {
		for(var i in oData) {
			if(typeof oData[i] == "array" || typeof oData[i] == "object") {
				// explode template in three parts (before block, block and after block)
				var sBlock = this.getBlock(sTemplate, i);
				if(sBlock == null) continue;
				// recurse with only parsing the block for each item in array or object
				var sReplace = "";
				for(var j in oData[i]) {
					sReplace += this.parse(sBlock, oData[i][j]);
				}
				// replace block by generated content
				sTemplate = this.replaceBlock(sTemplate, i, sReplace);
			}
			else if(typeof oData[i] == "boolean") {
				var sBlock = this.getBlock(sTemplate, i);
				if(sBlock == null) continue;
				// recurse with only parsing the block for each item in array or object
				if(!oData[i]) {
					sBlock = "";
				}
				// replace block by generated content
				sTemplate = this.replaceBlock(sTemplate, i, sBlock);
			}
			else {
				sTemplate = this.replaceItem(sTemplate, i, oData[i]);
			}
		}
		return sTemplate;
	}

	,getBlock:	function(sTemplate, sBlockName) {
		var sRegExp = '{{'+sBlockName+':}}([\\s\\S]*){{:'+sBlockName+'}}';
		var oRegExp = new RegExp(sRegExp, "g");
		var aMatches = oRegExp.exec(sTemplate);
		if(aMatches == null) {
			return null;
		}
		return aMatches[1];
	}

	,replaceBlock:	function(sTemplate, sBlockName, sReplace) {
		var sRegExp = '{{'+sBlockName+':}}([\\s\\S]*){{:'+sBlockName+'}}';
		if (typeof sReplace != 'string' && typeof sReplace != 'number') {
			sReplace = '';
		}
		var sNewTemplate = sTemplate.replace(new RegExp(sRegExp, "g"), sReplace);
		return sNewTemplate;
	}

	,replaceItem:	function(sTemplate, sItemName, sReplace) {
		var sRegExp = '{{'+sItemName+'}}';
		if (typeof sReplace != 'string' && typeof sReplace != 'number') {
			sReplace = '';
		}
		var sNewTemplate = sTemplate.replace(new RegExp(sRegExp, "g"), sReplace);
		return sNewTemplate;
	}

};
