//<![CDATA[

/*
	name : friendfeed
	file : jquery.friendfeed.js
	author : gregory tomlinson
	site: http://gregorytomlinson.com/
	///////////////////////////
	///////////////////////////		
	dependencies : jQuery 1.3.2
	///////////////////////////
	///////////////////////////
	
	The MIT License
	Copyright (c) 2009 Gregory Tomlinson
	http://www.opensource.org/licenses/mit-license.php	

  Contains extensions Copyright (c) 2009 mobalean (http://www.mobalean.com/)

*/

(function($) {

  $.fn.friendfeed = function( user, options ) {
	
    /* declare INSTANCE specific variables and settings */
    /* extend the defaults to include all user specified options */
    var defaults = $.extend( true, $.friendfeed.defaults, options );
		
    var	success = function( jo ) {
      if( !jo || !jo.entries ) {
        return false;
      }
				
      // provide 'this' as the target container
      $.friendfeed.render( this, jo.entries, defaults );
    },
    callback = $.friendfeed.delegate( success, this );
	
    /* connect to the remote data source: friendfeed */
    $.friendfeed.connector( defaults.url+user, defaults.params, callback );
		
    return this; /* jQuery default behavior, return container */
  };

  $.friendfeed = {
	
    dates : {
      // time in milliseconds
      "5days" : 432000000,
      "2days" : 172800000,
      "1day" : 86400000,
      "1hour" : 1440000,
      "1min" : 60000,
      months : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
      days : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
      previousDay : "yesterday"
    },
				
    log : function( str ) {
      if( !this.defaults.debug ) {
        return;
      }
      try {
        console.log( str );
      } catch(e){}
    },
    connector : function( src, params, callback ) {
      var str = $.param(params);
      $.ajax({
        dataType: 'jsonp',
        data : str,
        jsonp: 'callback',
        url : src,
        success: callback
      });
    },
    formatDate : function( time, diff ) {
      var d = this.dates, date = new Date( time ), response="";
      if( diff >= d["5days"] ) {
			
        response = d.months[date.getMonth()] + " " +date.getDate() + ", " + date.getFullYear(); /* Jan 1, 1970 */
      } else if( diff >= d["2days"] ) {
				
        response = d.days[ date.getDay() ]; /* Tuesday */
      } else if( diff >= d["1day"] ) {
			
        response = d.previousDay; /* yesterday */
      } else if( diff >= d["1hour"] ) {
        var tag = ( diff <= (d["1hour"]*2) ) ?  " hour ago" : " hours ago";
        response = Math.ceil( diff / 1000 / 60 / 60 ) + tag; /* N hours ago */
      } else if( diff >= d["1min"] ) {
        var tag = ( diff < (d["1min"]*2) ) ?  " min ago" : " mins ago";
        response = Math.ceil( diff / 1000 / 60 ) + tag; /* N mins ago */
      } else {

        response = "now";
      }
			
      //this.log( response );
			
      return response;

    },
    parseDate : function( time_string ) {
      //2009-09-18T13:39:17Z
      //this.log( time_string );
      time_string=time_string.slice(0, -1);
      var d = time_string.split("T"), time = d.pop().split(":"),
      date=d.pop().split("-"),
      now = (new Date()).getTime(),
      // have to adjust the months to start at 0
      then = Date.UTC( date[0], date[1]-1, date[2], time[0], time[1], time[2] ),
      diff = (now - then);

      return this.formatDate( then, diff ) + " ";
    },
    render : function( container, items, defaults ) {
      var css = defaults.css, bx = $('<div style="display:none" />').addClass( css.bx );
      this.log( 'Render Elements' );
      for(var i=0; i<items.length; i++) {
        //this.log( items[i] );
        var d = $('<div />').addClass( css.item ).appendTo( bx ), subD = $('<div />').addClass( css.meta ).appendTo( d );
        
        var b = $('<p />').html( items[i].body );
        b.prependTo( d );

        $("a[rel*=nofollow]", b).each(function(){ $.friendfeed.processLink(this) });
        b.longurlplease({
          lengthenShortUrl: function(aTag, longurl) {
            aTag.href = longurl;
            if (longurl.length > 25)
              aTag.innerHTML = longurl.substring(0,22) + '...';
            else
              aTag.innerHTML = longurl;
            $.friendfeed.processLink(aTag);
          }
        });

        $('<span />').addClass( css.time ).html( this.parseDate( items[i].date ) ).appendTo( subD );
				
        if( items[i].via ) {
          $('<span />').html('via ').appendTo(subD);
          $('<a />').attr('href', items[i].via.url).html( items[i].via.name ).appendTo( subD );
        }
				
        $('<a />').attr('href', items[i].url).addClass( css.comment_link ).html( 'Add Comment' ).appendTo( subD );
				
        this.renderComment( items[i].comments, css, d, items[i].url );
      }
      bx.appendTo( container ).slideDown(1000);
    },

    preview_handlers : {
      'twitngo.com' : function(url, body) {
        var img_id = url.segment(1);
        if(img_id) {
          $.friendfeed.add_preview(body, url.attr("source"), 'http://d.twitngo.com/photos/'+img_id+'_s');
        }
      },
      'twitpic.com' : function(url, body) {
        var img_id = url.segment(0);
        if(img_id) {
          $.friendfeed.add_preview(body, url.attr("source"), 'http://twitpic.com/show/thumb/'+img_id);
        }
      },
      'yfrog.com' : function(url, body) {
        $.friendfeed.add_preview(body, url.attr("source"), url.attr("source")+'.th.jpg');
      },
      'ow.ly' : function(url, body) {
        var img_id = url.attr("path").match("/i/([^/]*)$");
        if(img_id) {
          $.friendfeed.add_preview(body, url.attr("source"), 'http://static.ow.ly/photos/thumb/'+img_id[1]+'.jpg');
        }
      },
      'www.youtube.com' : function(url, body) {
        var video_id = url.param('v');
        if(video_id) {
          $.friendfeed.add_preview(body, url.attr("source"), 'http://img.youtube.com/vi/'+video_id+'/1.jpg');
        }
      },
      'www.flickr.com' : function(url, body) {
        var photo_id = url.attr("path").match("/photos/[^/]+/([^/]+)/$");
        if(photo_id) {
          success = function( photos ) {
            if(photos.stat == 'ok') $.friendfeed.add_preview(body, photos.sizes.size[2].url, photos.sizes.size[1].source);
          };
          $.friendfeed.fetch_flickr_preview(photo_id[1], $.friendfeed.delegate( success, body ));
        }
      }
    },

    /* @private */
    add_preview : function(body, href, preview_src) {
      $('<a />').attr('href', href).html( $('<img />').attr('src', preview_src) ).insertAfter(body);
    },

    /* @private */
    processLink : function( link ) {
      var url = $.url.setUrl($(link).attr("href"));
      var handler = $.friendfeed.preview_handlers[url.attr("host")];
      if (handler) handler(url, $(link).parent());
    },

    /* @private */
    fetch_flickr_preview : function(photo_id, callback) {
      $.ajax({
        dataType: 'jsonp',
        data : {
          "api_key" : "4295ed0b9c79c49085e8484f8d88c078",
          "photo_id": photo_id
        },
        jsonp: 'callback',
        url : 'http://api.flickr.com/services/rest/?method=flickr.photos.getSizes&format=json&jsoncallback=?',
        success: callback
      });
    },

    /* @private */
    renderComment : function( comments, css, el, link ) {
      if( !comments || comments.length <= 0 ) {
        return false;
      }

      for( var i=0; i<comments.length; i++ ) {
        var from = ( comments[i].from ) ? " -" + comments[i].from.name : "",
        p = $('<p />').addClass( css.comment ).appendTo( el );

        if( comments[i].placeholder ) {
          $('<a />').attr('href', link).html( comments[i].body ).appendTo( p );
        } else {
          p.html( comments[i].body + from );
        }
      }

      return true;			
    },
		
    delegate : function( func, scope ) {
      // fix scope to point where I say it
      var fn = func;
      return function() {
        fn.apply( scope, arguments );
      }
    }
  }

  /* define defaults for override */
  $.friendfeed.defaults = {
    url : 'http://friendfeed-api.com/v2/feed/',
    params : {
      format : 'json',
      locale:'en',
      /* start : 0, */  // 0 is the default
      num : 10,
      maxcomments : 3
    },
    css : {
      bx : 'ff_box',
      item : 'ff_item',
      meta : 'ff_meta',
      time : 'ff_time',
      comment_link : 'comment_outlink',
      comment : 'ff_comment'
			
    }
  };

})(jQuery);

//]]>

