/*
 * @name jWhale
 * @desc a socialwhale groups plugin for jQuery
 *
 * @author Kostas Theodorou - http://socialwhale.com
 * @mailto thek27@gmail.com
 * @version 0.0.1  (27/1/2010)
 */
 
/*
 * @type jQuery
 * @cat Plugins/jwhale
 * @requires jQuery v1.3.2+ (tested on version 1.4)
 *
 * Licensed under the GPL License:
 * http://www.gnu.org/licenses/gpl.html
 *
 * No guarantees, warranties, or promises of any kind
 *
 */

;(function($){
  
	/*
	 * Usage:
   * 
   * $(selector).jwhale(socialwhale_group_id);
   * $(selector).jwhale(socialwhale_group_id,{option1: value, option2: value});
	 */

  jQuery.fn.jwhale = function(id, options) {  

		var defaults = {
			rows: 5,
			cmd: 'both' // published, newest, both
		};
    
		var options = $.extend(defaults, options);  
		var obj = $(this);
		obj.addClass('jwhale');
		obj.html('<img src="img/logo.png"><br/><img src="img/loader.gif">');

		var xhr=null;
		var since_id = 0;
		var logged=null;

		var api_url='http://socialwhale.com/';

		xhr = $.getJSON(timeline_url(), function(data) {
			if (data && !data.error && data.length) {

				obj.html('<div class="top"></div><ol id="jwhale_updates" class="updates"></ol><div class="bottom"></div>');
				$.each(data, function(i, item) {
					if (logged==null) {
						logged=(item.voted!=null);
						formpost();
					}
					if (i<options.rows) {
						$("#jwhale_updates li.last").removeClass('last');
						$("#jwhale_updates").append(show(item,false));
						$('#jwhale_twit_'+item.id).addClass('last');
						trigger(item);
						if (!obj.children('.top').html() && item.groups[id]) {
							obj.children('.top').html('<label>'+item.groups[id].name+'</label>'+
								'<div class="refresh_off" title="refresh"></div><span class="commands">'+
								'<input '+(options.cmd=='newest'||options.cmd=='both'?'checked="checked" ':'')+'type="checkbox" value="newest" /> Newest '+
								'<input '+(options.cmd=='published'||options.cmd=='both'?'checked="checked" ':'')+'type="checkbox" value="published" /> Published </span>');
						}
					}
					if (item.id>since_id) since_id=item.id;
				});

				var checks=obj.children('.top').children('.commands').children('input');
				checks.click(function() {

					ajax_abort();
					refresh_on();
					
					var cmd='';
					checks.each(function() {
						if ($(this).attr('checked')) {
							if (cmd) cmd='both'; else cmd=$(this).val();
						}
					});
					if (cmd && options.cmd!=cmd) {
						since_id=0;
						options.cmd=cmd;
						$("#jwhale_updates").slideUp(100).empty();
						setTimeout(function() {
							$("#jwhale_updates").show();
							xhr = $.getJSON(timeline_url(), function(data) {
								$("#jwhale_updates").show();
								if (data && !data.error && data.length) {
									$.each(data, function(i, item) {
										if (i<options.rows) {
											$("#jwhale_updates li.last").removeClass('last');
											$("#jwhale_updates").append(show(item,false));
											$('#jwhale_twit_'+item.id).addClass('last');
											trigger(item);
										}
										if (item.id>since_id) since_id=item.id;
									});
								}
								else if (data.error) {
									alert(data.error);
								}
								refresh_off();
							});
						},100);	
					}
					else {
						refresh_off();
					}
				});

				obj.children('.top').children('.refresh_off').click(function() {
					refresh_timeline();
				});
			}
			else if (data.error) {
				obj.html('<img src="img/logo.png"><br/><div id="jwhale_error">'+data.error+'</div>');
			}
			else {
				obj.html('<img src="img/logo.png"><br/><div id="jwhale_error">Empty group</div>');
			}
		});

		function timeline_url() {
			var url=api_url+'groups_api/timeline/'+options.cmd+'/'+id+'.json?'+(since_id>0?'&since_id='+since_id+'&':'')+'callback=?';
			//window.console.log(url);
			return url;
		}

		function refresh_timeline() {
			ajax_abort();
			refresh_on();
			xhr = $.getJSON(timeline_url(), function(data) {
				if (data && !data.error && data.length) {
					data=data.reverse();
					$.each(data, function(i, item) {
						$("#jwhale_updates").prepend(show(item,true));
						trigger(item);
					});
				}
				else if (data.error) {
				}
				refresh_off();
			});
		}

		function ajax_abort() {
			if (xhr!=null) {
				refresh_off();
				xhr.abort();
				xhr=null;
			}
		}

		function refresh_on() {
			obj.children('.top').children('div').addClass('refresh_on').removeClass('refresh_off');
		}

		function refresh_off() {
			obj.children('.top').children('div').addClass('refresh_off').removeClass('refresh_on');
		}

		function formpost() {
			if (logged) {
				obj.children('.bottom').html('<form>'+
					'<fieldset>'+
						'<input type="hidden" id="jwhale_in_reply_to_status_id" />'+
						'<div class="title_bar">'+
							'<div id="jwhale_lbl_doing"><label for="jwhale_status">Post to group</label></div>'+
							'<span id="jwhale_status_count">140</span>'+
						'</div>'+
						'<div class="info_bar">'+
							'<textarea id="jwhale_status" rows="2" cols="61"></textarea>'+
						'</div>'+
						'<div class="info_bar">'+
							'<div id="jwhale_profile" class="profile"><img src="img/refresh_on.gif"></div>'+
							'<button id="jwhale_status_submit_btn" type="button" disabled="disabled">update</button>'+
							'<div id="jwhale_form_loader" class="form_loader"></div>'+
						'</div>'+
					'</fieldset>'+
				'</form>');

				$.getJSON(api_url+'account/verify_credentials.json?callback=?', function(data) {
					$('#jwhale_profile').empty();
					if (data && !data.error) {
						$('#jwhale_profile').html('<img style="width:24px;height:24px;" src="'+data.profile_image_url+'"/> <span>'+data.name+' ('+data.screen_name+')</span>');
					}
					else if (data.error) {
					}
				});

				$('#jwhale_status_submit_btn').click(function() { 
					if ($('#jwhale_status').val()) {

						$('#jwhale_form_loader').html('<img src="img/refresh_on.gif"><iframe id="jwhale_post" style="width:0px;height:0px;border:0px;" src="about:blank"></iframe>');
						ajax_abort();

						$('body', $('iframe#jwhale_post').contents()).html(
							'<form style="display:none" id="jwhale_form" action="'+api_url+'statuses/update.json" method="POST">'+
							'<input type="hidden" name="auto_follow" value="1"/>'+
							'<input type="hidden" name="groups_ids" value="'+id+'"/>'+
							'<input type="hidden" name="in_reply_to_status_id" value="'+$('#jwhale_in_reply_to_status_id').val()+'"/>'+
							'<textarea name="status">'+$('#jwhale_status').val()+'</textarea>'+
							'</form>'
						);

						$('iframe#jwhale_post').load(function() {
							$('#jwhale_form_loader').fadeOut(200,function() { $('#jwhale_form_loader').empty(); } );
							$('#jwhale_status').val('');
							update_form();
							refresh_timeline();
				    });

						$('form#jwhale_form',$('iframe#jwhale_post').contents()).submit();
					}
					return false;
			  });

				$('#jwhale_status').keyup(function() {
					update_form();
				});
			}
			else {
				obj.children('.bottom').html('<iframe style="width:180px;height:22px;border:0px;" src="http://socialwhale.com/oauth?return='+escape(document.location.href)+'"></iframe>');
			}
		}

		function update_form() {
			var l=$('#jwhale_status').val().length;
			$('#jwhale_status_count').text(140-l);
			if (l) {
				$('#jwhale_status_submit_btn').removeAttr('disabled');
			}
			else {
				$('#jwhale_in_reply_to_status_id').val('');
				$('#jwhale_lbl_doing label').html('Post to group');
				$('#jwhale_status_submit_btn').attr('disabled','disabled');
			}
		}

		function trigger(item) {

			if ($('#jwhale_twit_'+item.id).attr('rel')>0) {
				$('#jwhale_twit_'+item.id).children('.votes').height($('#jwhale_twit_'+item.id).height()-2).addClass('opened');
			}

			$('#jwhale_twit_'+item.id)
			.mouseover(function() {
				$(this).children('.votes').height($(this).height()-2);
				if ($(this).attr('rel')>0) $(this).children('.votes').removeClass('opened');
				$(this).children('.votes').show();
				$(this).children('.actions').children('a').css('visibility','visible');				
			})
			.mouseout(function(){
				if ($(this).attr('rel')>0) $(this).children('.votes').addClass('opened'); else $(this).children('.votes').hide();
				$(this).children('.actions').children('a').css('visibility','hidden');
			})
			.slideDown();

			var vote=$('#jwhale_twit_'+item.id).children('.votes');
			vote.mouseover(function() {
				$(this).height($(this).parent().height()-2);
				if ($(this).parent().attr('rel')>0) $(this).removeClass('opened');
				$(this).show();
				$(this).parent().children('.actions').children('a').css('visibility','visible');				
			})
			.mouseout(function(){
				if ($(this).parent().attr('rel')>0) $(this).addClass('opened'); else $(this).hide();
				$(this).parent().children('.actions').children('a').css('visibility','hidden');
			});

			if (logged) {
				if (vote.attr('rel')) {
					vote.addClass('do-vote').attr('title','vote this update').bind('click',function () {
						$.getJSON(api_url+'groups_api/vote.json?tweetID='+vote.attr('rel')+'&callback=?',function(data) {
							if (data && !data.error && data.voted) {
								vote.removeClass('do-vote').attr('title','you have already voted this update').unbind('click');
								vote.children('.vote_no').html(data.votes);
								$('#jwhale_twit_'+item.id).attr('rel',data.votes);
							}
						});
						return false;
					});
				}
				else {
					vote.attr('title','you have already voted this update');
				}
			}
			else {
				vote.attr('title','you must login first and then vote');
			}

			$('#jwhale_twit_'+item.id+' .actions .reply').click(function() {
				if ($('#jwhale_status').is(':visible')) {
					var v=$(this).attr('rel').split('|');
					var t='@'+v[0]+' ';
					$("#jwhale_in_reply_to_status_id").val(v[1]);
					$("#jwhale_lbl_doing label").html('Reply to '+v[0]);
					$('#jwhale_status').val(t).focus();
					$("#jwhale_status_count").text(140-t.length);
					$("#jwhale_status_submit_btn").removeAttr("disabled");
				}
				return false;
			});

			$('#jwhale_twit_'+item.id+' .status_body .status_time .conversation').click(function() {
				if (!$('#jwhale_twit_reply_'+item.id).is(':visible')) {
					$('#jwhale_twit_'+item.id).after('<li id="jwhale_twit_reply_'+item.id+'" class="blank">'+
						'<img src="img/refresh_on.gif"/><ol class="reply-updates"></ol></li>');
					$.getJSON(api_url+'statuses/conversation.json?id='+item.in_reply_to_status_id+'&callback=?', function(data) {
						if (data && !data.error) {
							$.each(data, function(i, reply_item) {
								if (reply_item) {
									$('#jwhale_twit_reply_'+item.id+' ol').append(show_tiny(reply_item,item.id));
									$('#jwhale_reply_in_'+reply_item.id)
									.mouseover(function() {
										$(this).children('.actions').children('a').css('visibility','visible');				
									})
									.mouseout(function(){
										$(this).children('.actions').children('a').css('visibility','hidden');
									})
									.slideDown();
								}
							});
						}
						else {
							$('#jwhale_twit_reply_'+item.id).remove();
						}
						$('#jwhale_twit_reply_'+item.id+' img:first').remove();
					});
				}
				else {
					$('#jwhale_twit_reply_'+item.id).slideUp('fast',function() { $('#jwhale_twit_reply_'+status_id).remove(); } );
				}
				return false;
			});
		}

		function show(item,new_item) {

			var s='<li style="display:none" id="jwhale_twit_'+item.id+'" class="twit'+(new_item ? ' new' : '')+'" rel="'+item.votes+'">';
			s+='<span class="status_img"><a href="http://twitter.com/'+item.user.screen_name+'" title="'+item.user.name+'">';
			s+='<img src="' + item.user.profile_image_url + '" alt="" class="status_img"/></a></span>';

			s+='<span class="status_body"><span class="status_name">';
			if (item.user.protected) s+='<img src="img/lock.gif" alt="" title="protected update"/> ';
			s+='<a href="http://twitter.com/'+item.user.screen_name+'" title="'+item.user.screen_name+'">';
			s+=item.user.screen_name + '</a> </span>';
			s+='<span class="status_text">'+status_text(item) + '</span>';

			s+='<span class="status_time">'+relative_time(item.created_at)+' from ' + item.source;
			if (item.in_reply_to_user_id) {
				s+=' <a class="user'+(item.in_reply_to_status_id ? ' conversation' : '')+'"';
				s+=' title="'+item.in_reply_to_screen_name+'" href="http://twitter.com/'+item.in_reply_to_screen_name+'">in reply to '+item.in_reply_to_screen_name+'</a>';
			}
			s+='</span>'; // status_time

			s+='</span>'; // status_body

			s+='<a '+(item.voted?'':'rel="'+ item.id +'" ')+'class="votes"><span class="vote_no">'+item.votes+'</span>';
			s+='<span class="vote_text">VOTES</span></a>';

			s+='<span class="actions">';
			s+='<a rel="'+item.user.screen_name+'|'+item.id+'" title="reply to ' + item.user.screen_name + '" class="reply" ';
			s+='href="http://socialwhale.com/home?status=@' + item.user.screen_name + '%20&in_reply_to_item.id=' + item.id + '&in_reply_to=' + item.user.screen_name + '">  </a>';
			s+='</span>';

			s+='</li>';

			return s;
		}

		function show_tiny(item,status_id) {

			var s='<li style="display:none" id="jwhale_reply_in_'+item.id+'" class="twit'+(item.id==status_id?' same':'')+'">';
			s+='<span class="status_img"><a href="http://twitter.com/'+item.user.screen_name+'" title="'+item.user.name+'">';
			s+='<img src="' + item.user.profile_image_url + '" alt="" class="status_img"/></a></span>';

			s+='<span class="status_body"><span class="status_name">';
			if (item.user.protected) s+='<img src="img/lock.gif" alt="" title="protected update"/> ';
			s+='<a href="http://twitter.com/'+item.user.screen_name+'" title="'+item.user.screen_name+'">';
			s+=item.user.screen_name + '</a> </span>';
			s+='<span class="status_text">'+status_text(item) + '</span>';

			s+='<span class="status_time">'+relative_time(item.created_at)+' from ' + item.source;
			if (item.in_reply_to_user_id) {
				s+=' <a class="user" title="'+item.in_reply_to_screen_name+'" href="http://twitter.com/'+item.in_reply_to_screen_name+'">in reply to '+item.in_reply_to_screen_name+'</a>';
			}
			s+='</span>'; // status_time

			s+='</span>'; // status_body

			s+='<span class="actions">';
			s+='<a rel="'+item.user.screen_name+'|'+item.id+'" title="reply to ' + item.user.screen_name + '" class="reply" ';
			s+='href="http://socialwhale.com/home?status=@' + item.user.screen_name + '%20&in_reply_to_item.id=' + item.id + '&in_reply_to=' + item.user.screen_name + '">  </a>';
			s+='</span>';

			s+='</li>';

			return s;
		}

		function status_text(item) {

			var txt = item.textParsed;
			if (!txt) txt=item.text.replace(/http:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%~&\?\/.=]+/g, function(m) { 
				return '<a href="'+m+' target="_blank">'+m+'</a>';
			});

			txt=' '+txt; // hack whitespace char
			txt=txt.replace(/\swww\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%~&\?\/.=]+/g, function(m) {
				return ' <a href="http://'+m.substr(1)+'" target="_blank">'+m.substr(1)+'</a>';
			});
			txt=txt.substr(1); // remove hack


			txt = txt.replace(/(^|[^\w])(@[\d\w\-]+)/g, function(d, m1, m2) {
				return m1 + '@<a class="user" title="' + m2.substr(1) + '" href="http://twitter.com/' + m2.substr(1) + '">' + m2.substr(1) + '</a>';
	  	});

			txt = txt.replace(/(^|\s)(#[\d\w\-]+)/g, function(d, m1, m2) {
				if (m1.indexOf('href')==0) {
					return m1 + m2;
				}
				else {
					return m1 + '#<a class="hashtag" title="' + m2.substr(1) + '" href="'+m2+'">' + m2.substr(1) + '</a>';
				}
		  });

			return txt;
		}

		function relative_time(time_value) {
			var values = time_value.split(" ");
		  time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
		  var parsed_date = Date.parse(time_value);
		  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
		  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
		  delta = delta + (relative_to.getTimezoneOffset() * 60);
		  if (delta < 60) {
		    return 'less than a minute ago';
		  } else if(delta < 120) {
		    return 'a minute ago';
		  } else if(delta < (45*60)) {
		    return (parseInt(delta / 60)).toString() + ' minutes ago';
		  } else if(delta < (90*60)) {
		    return 'an hour ago';
		  } else if(delta < (24*60*60)) {
		    return '' + (parseInt(delta / 3600)).toString() + ' hours ago';
		  } else if(delta < (48*60*60)) {
		    return '1 day ago';
		  } else {
		    return (parseInt(delta / 86400)).toString() + ' days ago';
		  }
		}

	}
  
})(jQuery);