// By Andreas Haller (http://ahax.de)

// Insert Tumblr posts (rendered using mustache.js)
jQuery.fn.tumblrPosts = function(blogUrl, options) {
  var o = $.extend(jQuery.fn.tumblrPosts.defaults, options);
	if(!blogUrl) throw "tumblrPosts: No blogUrl specified!";
	var self = $(this);
	var probe;
	
	var render = function(data) {
	  try {
      var rendered = $.mustache(o.template, o.view(data));
	    if(probe) {
	      // update new elements
        $(probe).after(rendered).remove();
	    } else {
	      // append and save new elements
        probe = self.append(rendered).map(function() { return this.lastChild; });
	    }
    } catch(err) {
      o.error.call(this, err);
    }
	};
		
	// render cached data if we have everything we need
	var useCache = o.useCache && ("localStorage" in window) && (typeof JSON != "undefined") && ("stringify" in JSON);	
	if(useCache) {
	  var key = "tumblrPosts-"+blogUrl;
	  var cached = window.localStorage.getItem(key);
	  if(cached) {
	    try{	      
	      var data = JSON.parse(cached);
        render(data);
	    }catch(err){
	      o.error.call(this, err);
	    }
    }
	}  
  
  o.beforeLoad.call(this); 
  // Get Tumblr data and render
  $.getScript(blogUrl+"/api/read/json?num="+o.number, function(){
    // Tumblr data loaded / executed. var tumblr_api_read got defined by the reponse
    render(tumblr_api_read);
    // update cache
    if(useCache) window.localStorage.setItem(key, JSON.stringify(tumblr_api_read));
    o.afterLoad.call(self);
  });
  
	// FIXME should this return self of the new element?
  return self;
};

jQuery.fn.tumblrPosts.defaults = {
    number: 3,
    useCache: true,
    beforeLoad: function() {},
    afterLoad: function() {},
    error: function(err) {},
    // The (Mustache) template
    // FIXME How do proper multiline strings in js?
    template: '<ul>{{#posts}}<li><a href="{{url}}">{{title}}</a></li>{{/posts}}</ul>',
    // Should return an Object for the view
    // data is the data from the Tumblr API
    view: function(data) {  
      var stripTags = function(str) {
      	return str.replace(/\<\/?[^>]+>/gi, ' '); // This line is stolen from http://stilldesigning.com/dotstring/jquery.string.1.0.js
      };
      // TODO trunkate is broken with entities like &nbsp; 
      var trunkate = function(t) {
      	return $(t).filter(":first").text().match(/^.{0,55}/)[0].trim();
      };
      var getTitle = function(p) {
         switch(p.type){
           case "link":
             return p["link-text"];
           case "regular":
             return p["regular-title"] || trunkate(p["regular-body"]);
           case "audio":
             return "Audio: " + trunkate(p["audio-caption"]);
           case "video":
             return "Video: " + trunkate(p["video-caption"]);
           case "photo":
             return "Photo: " + trunkate(p["photo-caption"]);
           case "quote":
             return stripTags(p["quote-text"]);
         }
         return p.type;
      };
      // prepare posts, so they all have a title attibute
      for(var i in data.posts) {
        var post = data.posts[i];
        post.title =  getTitle(post) || "Post";
      }
      return data;
    }
};
