/**
 * This processes an anotated jquery template. It will automatically retrieve the feed and combine it with the
 * feed while doing some sanity checking and forces you to consider error handling.
 * example $('#myTemplate').processFeed()
 * author:jkoberstein
 * options
 *   onlyProcessScripts:	if false it will not check that the template is in a script tag of type text/x-jquery-tmpl
 *   preprocessFeed: a function to call to allow preprocessing of the json feed.
 *   data: the url to the feed that will be used to fill in the template (overrides the script attribute data)
 *   
 * script attributes
 *   type:  set this to text/x-jquery-tmpl for happiness
 *   replaces: the elements that we are going to update with this template
 *   data: the url to the feed that will be used to fill in the template
 *   error: the div to show if there is an error loading the template
 */
(function( $ ){
	loadingDivIdNumber = 1;
	$.fn.processFeed = function( options ) {
		var settings = {
			'onlyProcessScripts'    : true,
			'preprocessFeed'        : null,
			'postLoad'              : null,
			'data'                  : null,
			'json'                  : null
		};
		if ( options ) {
			$.extend( settings, options );
		}
		log = function (msg,exception) {
			if (typeof(console) == 'object'){
				var now = new Date();
				if (typeof(console.info) == 'function') {
					msg = '[' + now.toLocaleString() + '] '+msg+'; Exception:' + exception.message;
					console.info(msg);
				}
				if(exception && exception.stack && typeof(console.error) == 'function') {
					console.log(exception.stack);
				}
			}
		}
		this.each(function() {
			var template = $(this);
			if(settings.onlyProcessScripts){
				if(!template.is("script")){
					log('Template error:not in script tag');
					return;
				}
				if('text/x-jquery-tmpl'!=template.attr("type")){
					log('Template error:type is not text/x-jquery-tmpl');
					return;
				}
			}
			replacesStr = settings.replaces||template.attr("replaces");
			if(!replacesStr){
				log('Template error:missing replaces attribute');
				return;
			}
			var replaces=$(replacesStr);
			if(replaces.length<=0){
				log('Template error:selector "'+template.attr("replaces")+'" returned no elements');
				return;
			}
			var dataFeed=template.attr("data");
			if(settings.data){
				dataFeed = settings.data;
			}
			if(!dataFeed && !settings.json){
				log('Template error:missing data attribute');
				return;
			}
			if(!template.attr("error")){
				log('Template error:missing error attribute');
				return;
			}
			var errorDiv=$(template.attr("error"));
			if(errorDiv.length<=0){
				log('Template error:selector "'+template.attr("error")+'" returned no elements');
				return;
			}
			if(!template.attr('loading')){
				var loadingId = 'pogoFeedLoading-'+loadingDivIdNumber;
				loadingDivIdNumber = loadingDivIdNumber+1;
				template.attr('loading','#'+loadingId);
				if(!$(template.attr('loading')).length){
					$('body').append($('<div id="'+loadingId+'" style="display:none;"></div>'));
					$(template.attr('loading')).html(replaces.html());
				}
			} else {
				replaces.html($(template.attr('loading')).html());
			}
			
			showError = function(msg,exception){
				log(msg,exception);
				replaces.html(errorDiv.html());
				$('<!-- '+msg+' -->').prependTo(replaces);
			}
			renderTemplate = function(json) {
				if((typeof settings.preprocessFeed) === 'function'){
					try {
						settings.preprocessFeed(json);
					} catch (err) {
						showError("Template error:preprocess failed",err);
						return;
					}
				}
				try {
					replaces.empty();
					template.tmpl(json).appendTo(replaces);
					replaces.show();
				}
				catch (err) {
					showError("Template error:unexpected",err);
				}
				if((typeof settings.postLoad) === 'function'){
					try {
						settings.postLoad(true);
					} catch (err) {
						showError("Template error:postLoad failed",err);
						return;
					}
				}
			}
			if(settings.json){
				renderTemplate(settings.json);
			} else {
				$.ajax({
					url: dataFeed,
					dataType:'json',
					success: renderTemplate,
					error: function(jqXHR, status, err) {
						showError("Template error:unable to retrieve json feed. status:"+status,err);
					}
				});
			}
		});
		return this;
	};
})( jQuery );
