// ==UserScript==
// @name           dATweets
// @namespace      Zikes
// @description    Adds functionality to Twitter boxes on dA
// @include        http://*deviantart.com*
// ==/UserScript==

// Get elements by xpath
function $x(xpath,root){
	var got=document.evaluate(xpath,root||document,null,null,null), result=[];
	while(next=got.iterateNext()) result.push(next);
	return result;
}

function get(url,cb){GM_xmlhttpRequest({method:"GET", url:url, headers:{'User-Agent':'Firefox / GreaseMonkey / dATweets'}, onload:function(xhr){cb(xhr.responseText)}})}
function post(url,data,cb){GM_xmlhttpRequest({method:"POST",url:url,headers:{'User-Agent':'Firefox / GreaseMonkey / dATweets', 'Content-type':'application/x-www-form-urlencoded'},data:encodeURI(data),onload:function(xhr){cb(xhr.responseText)}})}

function linkify(str) {
	return str.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
		return m.link(m);
	}).replace(/\@([^ ]*)/g,function(_, name){
		return "@<a href='http://twitter.com/"+name+"'>"+name+"</a>"
	});
}
function prettyDate(time){
	var date = new Date((time || "").replace(/-/g,"/").replace(/(.)[TZ]/g,"\1 "));
	diff = (((new Date()).getTime() - date.getTime()) / 1000);
	day_diff = Math.floor(diff / 86400);

	if(isNaN(day_diff) || day_diff<0) {
		return;
	}

	return day_diff == 0 && (
		diff < 60 && "just now" ||
		diff < 120 && "1 minute ago" ||
		diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
		diff < 7200 && "1 hour ago" ||
		diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
		day_diff == 1 && "Yesterday" ||
		day_diff < 7 && day_diff + " days ago" ||
		day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
		Math.ceil( day_diff / 30 ) + " months ago";
}


function getNext(startNode, node){
	node=(node || '').toLowerCase();
	var tmpNode=startNode.nextSibling;
	do{
		if(tmpNode.nodeType==1){
			if(node=='' || tmpNode.nodeName.toLowerCase()==node){
				return tmpNode;
			}else{
				return getNext(tmpNode, node);
			}
		}
	}while(tmpNode=startNode.nextSibling);
	return startNode;
}

function getCurrentPageUser(){
	var user=link_box.firstChild.href.match(/http\:\/\/twitter\.com\/(.*)/i)[1];
	getCurrentPageUser=function(){return user};
	return user;
}

function FollowButton_Click(evt){
	evt.stopPropagation();
	evt.preventDefault();
	var cuser=getCurrentPageUser();
	if(this.getAttribute('following')=='true'){
		if(confirm('Are you sure you wish to stop following '+cuser+'?')){
			post('http://twitter.com/friendships/destroy/'+cuser+'.json',{},function(results){
				GM_log(results);
				var user=eval('('+results+')');
				if(user.error){
					alert(user.error);
					return;
				}
				if(user.screen_name.toLowerCase()==cuser.toLowerCase()){
					// Successful un-follow
					follow_link.setAttribute('following','false');
					follow_link.innerHTML='Follow '+cuser;
				}
			})
		}
	}else{
		post('http://twitter.com/friendships/create/'+cuser+'.json?follow=true',{},function(results){
			var user=eval('('+results+')');
			if(user.error){
				alert(user.error);
				return;
			}
			if(user.screen_name.toLowerCase()==cuser.toLowerCase()){
				// Successful follow
				follow_link.setAttribute('following','true');
				follow_link.innerHTML='You are following '+cuser;
			}
		});
	}
}

function UpdateButton_Click(evt){
	var txt=$x('//textarea[@id="dAt_update"]')[0];
	post('http://twitter.com/statuses/update.json','status='+txt.value,function(results){
		if(results.error){
			alert(results.error);
			return;
		}
		if(username.toLowerCase()==getCurrentPageUser().toLowerCase()) updateTimeline();
		alert('Update successful!');
		txt.value='';
	})
}

function updateTimeline(){
	var count=$x('//div[starts-with(@id,"twitter")]//li').length;
	get('http://twitter.com/users/show/'+getCurrentPageUser()+'.json?count='+count,function(results){
		var results=eval('('+results+')');
		if(results.error){
			alert('Error fetching updated timeline: '+results.error);
			return;
		}
		if(results.protected){
			$x('//div[starts-with(@id,"twitter")]/ul')[0].innerHTML='<li class="f">This person has protected their updates.</li>';
		}else{
			get('http://twitter.com/status/user_timeline/'+getCurrentPageUser()+'.json?count='+count,function(timeline){
				timeline=eval('('+timeline+')');
				var out=[]
				timeline.forEach(function(item,idx){
					var ruser=item.in_reply_to_screen_name;
					var rid=item.in_reply_to_status_id;
					out.push("<li class='f"+(idx % 2==0 ? ' a' : '')+"'><span class='created_at' style='float: right; position: relative; opacity: 0.6; font-size: 8.25pt; margin-left: 8px; text-align: right;'>"+item.source+", "+prettyDate(item.created_at).link("http://twitter.com/"+item.user.screen_name+'/status/'+item.id)+"</strong>"+(rid ? "<br />"+("in reply to "+ruser).link('http://twitter.com/'+ruser+'/status/'+rid) : '')+"</span>"+linkify(item.text)+"<br style='clear:both;' /></li>");
				});
				$x('//div[starts-with(@id,"twitter")]/ul')[0].innerHTML=out.join('');
			});
		}
		
	});
}
GM_registerMenuCommand('Update Timeline',updateTimeline);

function followBox(){
	if(username.toLowerCase()==getCurrentPageUser().toLowerCase()) return;
	follow_link=document.createElement('a');
		follow_link.href='#';
		follow_link.className='a';
		follow_link.addEventListener('click',FollowButton_Click,true)
	var div=document.createElement('div');
		div.className='pp c';
		div.appendChild(follow_link);
	tb_listing.parentNode.appendChild(div);
		
	get('http://twitter.com/friendships/exists.json?user_a='+username+'&user_b='+getCurrentPageUser(),function(results){
		GM_log('Following?: '+results);
		var results=eval('('+results+')');
		if(results.error){
			alert(results.error);
			return;
		}
		if(results){
			follow_link.appendChild(document.createTextNode('You are following '+getCurrentPageUser()));
			follow_link.setAttribute('following','true');
		}else{
			follow_link.appendChild(document.createTextNode('Follow '+getCurrentPageUser()));
			follow_link.setAttribute('following','false');
		}
	});
}

function updateReplyBox(){
	var div_update=document.createElement('div');
		div_update.style.padding='4px 12px 26px 39px';
	
	var txt_update=document.createElement('textarea');
		txt_update.id='dAt_update';
		txt_update.rows='2'; txt_update.cols='30';
		txt_update.style.width='100%';
		if(getCurrentPageUser().toLowerCase()!==username.toLowerCase()){
			txt_update.value='@'+getCurrentPageUser()+' ';
		}
	
	var btn_update=document.createElement('button');
		btn_update.innerHTML='Update';
		btn_update.style.cssFloat='right';
	
	div_update.appendChild(txt_update);
	div_update.appendChild(btn_update);
	
	tb_listing.insertBefore(div_update, tb_listing.firstChild);
	
	btn_update.addEventListener('click',UpdateButton_Click,true);
}

function initialize(){
	if(tb_listing.length>0){
		tb_listing=tb_listing[0];
		status_list=$x('//ul',tb_listing)[0];
		if(!status_list){
			interval=window.setInterval(function(){
				status_list=$x('//ul',tb_listing)[0];
				if(status_list){
					window.clearInterval(interval);
				}
			});
		}
		link_box=getNext(tb_listing);
		followBox();
		updateReplyBox();
		updateTimeline();
	}else{
		// No Twitter Box on this page
		return;
	}
}

var tb_listing=$x('//div[starts-with(@id,"twitter")]');
var link_box;
var follow_link;
var status_list;
var interval;

var username=GM_getValue('username','');

if(username==''){
	get('http://twitter.com/statuses/user_timeline.json?count=1',function(results){
		var results=eval('('+results+')');
		if(results instanceof Array){
			username=results[0].user.screen_name;
			GM_setValue('username',username);
			initialize();
		}else if(results.error){
			alert(results.error);
		}
	});
}else{
	initialize();
}
