/* tinplate.js - tiny templates for javascript
   Copyright (c) 2008 Niall McCarroll  
   Distributed under the MIT/X11 License (http://www.mccarroll.net/snippets/license.txt)
 
   functionality: 
       apply a template to data to generate output text
       can supply an optional stringizer function to convert data values to string
  
    usage:
        
        var t = new tinplate();
        var s = t.process(format,data[,stringizer]);
*/

function tinplate() {
	this.matched = 0;
}

tinplate.prototype.format = function(fmt,val,stringizer) {
	var pos = fmt.indexOf("$");
	if (pos == -1) { return fmt; }
	if (fmt.charAt(pos+1) == "$") { 
		return fmt.slice(0,pos+1) + this.format(fmt.slice(pos+2),val,stringizer); 
	}
	if (fmt.charAt(pos+1) == "(") { 
		var rp = fmt.slice(pos+1).indexOf(")");
		if (rp != -1) {
			var name = fmt.slice(pos+2,pos+1+rp);
			this.matched += 1;
			var value = '';
			if (name in val) {
				value = stringizer(val[name]);
            }
			return fmt.slice(0,pos)+value+this.format(fmt.slice(pos+2+rp),val,stringizer);
		}
	}
	this.matched += 1;
	return fmt.slice(0,pos)+stringizer(val)+this.format(fmt.slice(pos+1),val,stringizer);
}


tinplate.prototype.process = function(format,data,stringizer) {
	if (stringizer == undefined) { stringizer = String; }
	if (typeof(format)=="function") return format(data);
	if (typeof(format)=="string") return this.format(format,data,stringizer);
	if (format.foreach) {
		this.matched += 1
		var f,d,txt='';
		for(d in data) {
			for(f in format.foreach) {
				txt += this.process(format.foreach[f],data[d],stringizer);
			}
		}
		return txt;
	} else {
		var d = 0;
		var txt = '';
		for(f in format) {
			var m1 = this.matched;
			txt += this.process(format[f],data[d],stringizer);
			if (this.matched > m1) {
				d += 1;
			}
		}
		return txt;
	}
}


