function Templating(){};

Templating.from_cache=true;

Templating.parseTemplate=parseTemplate;

function TemplateTank(){
	var _templates=null
	var _cache={};
    //var _parsing_cache;
    var _this=this;

	$.each(_templates_,function(i,n){
		n=unescape(n);
		
		if(Templating.from_cache) cache_template(i,n);
	});
	
	// return false;
    function pull_templates(data){
      var _tmps=[];
        var d=$("<div>"+data+"</div>");
        get_comment_templates(d[0])
        data=data.replace(/<!--[\;\:\.\,\$\?\!\#\/\\\ 0-9a-z\r\n\t\_\<\>\[\%\]\{\}\=\"\'\-\+\)\(\*\&\^]{1,}--\>/gi,'')
        return data;
    };

    this.parse_template=function(template){
		
        return parse(template);
    };

    function get_comment_templates(elm){
        var d=scanElm(elm);
        $.each(d,function(i,n){
            var y=n.match(/[a-z0-9\_]{1,}/i)[0];
            var u=n.replace(y,'');
            y=$.trim(y);
           cache_template(y,u);
        });
    };

    this.get_template=function(name,callback){
        try{
            callback(_cache[name]);
        }catch(e){
            //console.log("TEMPLATE : > Does not exist");
        };
    };

    this.get_template_from_URI=function(uri,callback){
        if(!_templates){
			_templates={};
        }

        if(_cache[uri]!=null){
            callback(_cache[uri]);
        }else{
        	now = new Date();
            $.get("/template/ejs/"+uri+".ejs?"+now.toString(),{},function(data){
                data=pull_templates(data);
                cache_template(uri,data);
                callback(_cache[uri]);
            });
        }
    };

    function parse(template){
        var _string=sanatise(template);
        var _del="[]";
        var _left_caret=0;
        var _right_caret=0;
        var _code="";

		while(_right_caret<_string.length){

            var tag_left_caret=_string.indexOf("[%",_right_caret);

            if (tag_left_caret != -1) {
                add_code("output+=\""+_string.substring(_right_caret,tag_left_caret)+"\";");

                var tag_right_caret = _string.indexOf("%]",tag_left_caret);
                var _adder=0;
                var _c="";

                if(_string.substr(tag_left_caret,3)=="[%="){
                    _c="output+="+_string.substring(tag_left_caret+3,tag_right_caret)+";";
                    _adder=2;
                }else{
                    _c=_string.substring(tag_left_caret+2,tag_right_caret);
                    _adder=2;
                }

                add_code(_c);
                _right_caret=tag_left_caret+(tag_right_caret-tag_left_caret)+_adder;
            }else{
                add_code("output+=\""+_string.substr(_right_caret,_string.length-1)+"\";");
                _right_caret=_string.length;
            }
        };


        var _code2="(function(){var output='';"+_code+";return output;})();";
        _code=_code2;
        return _code;

        function add_code(string){
            _code+=string;//+"\n";
        };
    };

    function sanatise(string){
		var _string=String(string);
        _string=_string.replace(/\"/gi,'\\"');	//	Replace quotes with \" to prevent eval breaking
		_string=_string.replace(/[\n\t\r]/gi,'');	//	Replace all tabs and newlines
		return _string;
	};
    
    function cache_template(key,value){
        try{
			_cache[key]=parse(value);
        }catch(e){
		}
    };
};

TemplateTank=new TemplateTank;

function scanElm(elm){
	var rc = [];
	for(var c = 0; c < elm.childNodes.length; c++) {
		var child = elm.childNodes[c];
		if (child.nodeType == 8){
			rc.push(child.nodeValue);
		}
	};
	return rc;
};


function parseTemplate(options){
    var _data=options.data;
    var _view=options.view || {};

    with(_view){
        with(_data){
            try{
                return eval(options.template);
            }catch(e){
                // console.log(">>"+e+"\n\n"+options.template);
				// console.log("TEMPLATE ERROR in "+options.template+" > ",e,_view,_data);
            }
        };
    };
};


$.fn.x = function(n) {
     var result = null;
     this.each(function() {
         var o = this;
         if (n === undefined) {
             var x = 0;
             if (o.offsetParent) {
                 while (o.offsetParent) {
                     x += o.offsetLeft;
                     o = o.offsetParent;
                 }
             }
             if (result === null) {
                 result = x;
             } else {
                 result = Math.min(result, x);
             }
         } else {
             o.style.left = n + 'px';
         }
     });
     return result;
};

$.fn.y = function(n) {
     var result = null;
     this.each(function() {
         var o = this;
         if (n === undefined) {
             var y = 0;
             if (o.offsetParent) {
                 while (o.offsetParent) {
                     y += o.offsetTop;
                     o = o.offsetParent;
                 }
             }
             if (result === null) {
                 result = y;
             } else {
                 result = Math.min(result, y);
             }
         } else {
             o.style.top = n + 'px';
         }
     });
     return result;
};
