/**
 * Outputtable object representation data type
 * @param string template - template to parse
 */
jFly = function ( template ) {
	this.myTemplate = template;
	this.myParent = null;	
	this.noVariable = String.fromCharCode(2);
}

// Setting prototype
mixin(jFly.prototype, {
	// Subtemplate parsers array
	parsers: [],
	parsers_num: 0,
	
	/**
	 * Setting template function
	 * @param string template - new template
	 */
	template: function ( template )	{
		this.myTemplate = template;
		return this;
	},
	
	/**
	 * Adding templates parser function
	 * @param cAITemplateParser parser - templates parser
	 */
	addParser: function ( parser )
	{
		jFly.prototype.parsers[jFly.prototype.parsers_num++] = parser;
	},
	
	/**
	 * Parsing template function
	 */
	parse: function () {
		// Founding parser
		for (i in this.parsers)
			if (this.parsers[i].check(this.myTemplate))
				return this.parsers[i].parse(this, this.parsers[i].template(this.myTemplate));
		
		// Replacing all first level subtemplates
		var string = new cAIParser(this.myTemplate);
		while (true)
		{
			// Getting subtemplate
			var subtemplate = string.firstSubtemplate();
			if (subtemplate == false)
				break;
			
			// Parsing template
			replace = new jFly(subtemplate);
			replace.myParent = this;
			replace = replace.parse();
			
			// Replacing template
			string.replaceTemplates("{" + subtemplate + "}", replace);
		}
		
		return string.myString;
	},
	
	/**
	 * Releasing object function
	 */
	release: function ()
	{
		return this.parse().split(this.noVariable).join("");
	},
	
	/**
	 * Converting object to string function
	 */
	toString: function ()
	{
		return this.release();
	},
	
	/**
	 * Setting variable function
	 * @param string name - variable name
	 * @param string value - variable value
	 */
	set: function ( name, value )
	{
		this[name] = value;
		return this;
	},
	
	/**
	 * Setting all object fields as variables function
	 * @param string obj - object to add
	 */
	setObject: function ( obj )
	{
		for (var i in obj)
			this.set(i, obj[i]);
	},
	
	/**
	 * Getting variable value function
	 * @param string name - variable name
	 */
	get: function ( name ) {
		// Founding variable in this object
		if (this[name])
			return this[name];
		
		// Founding variable in parent object	
		if (this.myParent != null)
			return this.myParent.get(name);
			
		// Variable not found
		return this.noVariable;
	}
});

