// ==UserScript==
// @name           hbcReply.user.js
// @namespace      http://furyu.tea-nifty.com/
// @description    Reply to a comment of Hatena::Bookmark ver.0.01
// @include        http://b.hatena.ne.jp/*
// @include        http://h.hatena.ne.jp/keyword/hbcreply*
// ==/UserScript==

(function(){

var	usePreview=true;

var	oWindow=window;
if (typeof unsafeWindow!='undefined') {
	window=unsafeWindow;
	document=window.document;
}
var	w=window,d=document;
var	AutoPagerize=w.AutoPagerlike||oWindow.AutoPagerize;

var	getCookie=function(name){
	var	value=null;
	for (;;) {
		var	key=name+'=';
		var	curCookie=d.cookie;
		var	keyStart=curCookie.indexOf(key);
		if (keyStart<0) break;
		var	valStart=keyStart+key.length;
		var	valEnd=curCookie.indexOf(';',valStart);
		if (valEnd<0) valEnd=curCookie.length;
		value=decodeURIComponent(curCookie.substring(valStart,valEnd));
		break;
	}
	return value ;
}	//	end of getCookie()

var	setCookie=function(name,value,expires){
	d.cookie=[
		name + '=' + encodeURIComponent(value)
	,	'expires=' + expires.toGMTString()
	,	'domain=hatena.ne.jp'
	,	'path=/'
	].join(';');
	return	getCookie(name);
}	//	end of setCookie()

var	delCookie=function(name){
    if(getCookie(name)){
    	var	expires=new Date;
    	expires.setFullYear(expires.getFullYear()-1);
		setCookie(name,'',expires);
	}
}	//	end of delCookie()

var	setCookiePerm=function(name,value){
	var	expires = new Date();
	expires.setFullYear(expires.getFullYear()+100);
	return setCookie(name,value,expires);
}	//	end of setCookiePerm()

var	getElementsByTagAndClassName=function(tagName,className,parent) {
	if (!parent) parent=d;
	var children=parent.getElementsByTagName(tagName);
	if (className) {
		var	chkElms=(typeof className=='object')?className:className.split(' ');
		var	flgElms=[];
		for (var ci=0,len=chkElms.length; ci<len; ci++) flgElms[chkElms[ci]]=true;
		var elements=[];
		for (var ci=0,leni=children.length; ci<leni; ci++) {
			var child=children[ci];
			var cname=child.className;
			if (!cname) continue;
			var cnameElms = cname.split(' ');
			for (var cj=0,lenj=cnameElms.length; cj<lenj; cj++) {
				if (flgElms[cnameElms[cj]]) {
					elements.push(child);
					break;
				}
			}
		}
		return elements;
	}
	else {
		return children;
	}
}	//	end of getElementsByTagAndClassName()

var	setEventHandler=(function(){
	if (w.attachEvent) {
		return function(obj,evt,handler){obj.attachEvent('on'+evt,handler)};
	}
	else if (w.addEventListener) {
		return function(obj,evt,handler){obj.addEventListener(evt,handler,false)};
	}
	else {
		return function(obj,evt,handler){var org=obj['on'+evt];obj['on'+evt]=function(){if(typeof org=='function')org();handler()}};
	}
})();	//	end of setEventHandler()

var	addScript=(function(){
	var	head=d.getElementsByTagName('head')[0]
	return function(src){
		var	s=d.createElement('script');
		s.type='text/javascript';
		s.src=src;
		head.appendChild(s);
	}
})();	//	end of addScript()

var	stripTags=function(txt){return txt.replace(/<\/?[^>]+>/gi,'')};

if (usePreview) {
	var	google=w.google, googleReady=false;
	if (!google||typeof google.setOnLoadCallback!='function') {
		addScript('http://www.google.com/jsapi?key=ABQIAAAAZhtXQqOU3tLkBz367jyy1hTsag5b2eY9jP4MFmD4bZUXXJ0w_xQfIhwHFBQQR0y3zV_c-Y5a6mniiA');
	}
}
var	hhBase='http://h.hatena.ne.jp/',hhkBase=hhBase+'keyword/',hhrBase=hhBase+'target.rss?word=';
var	replyHtml='<img src="http://h.hatena.ne.jp/images/icon-reply.gif" border="0" \/> Reply';

var	is1st=true;

var	makeButton=function(hid,comment,keyword,srclink){
	keyword=encodeURIComponent(keyword);
	var	url=hhkBase+keyword;
	var	button=d.createElement('span'),style=button.style;
	style.color='#b36b85';
	style.cursor='pointer';
	style.fontSize='80%';
	button.title='Reply to id:'+hid;
	button.innerHTML=replyHtml;
	setEventHandler(button,'click',function(e){
		setCookiePerm('hbcr',stripTags(comment.innerHTML));
		setCookiePerm('hbct',srclink.innerHTML);
		setCookiePerm('hbcu',srclink.href);
		w.open(url,'_blank');
	});
	comment.parentNode.appendChild(button);
	(function(){
		if (!usePreview) return;
		if (!googleReady) {
			setTimeout(arguments.callee,100);
			return;
		}
		var	addPreviewButton=function(e){
			var	google=w.google;
			var	feedURL=hhrBase+keyword+'&_u='+~~(new Date().getTime()/3600000);
			var	feed=new google.feeds.Feed(feedURL);
			feed.setNumEntries(250);
			feed.load(
				function(result){
					var	links=[];
					if (!result.error) {
						var	entries=result.feed.entries,cmtEntries=[];
						for (var ci=0,len=entries.length; ci<len; ci++) {
							var	entry=entries[ci];
							var	rid=entry.author, url=entry.link;
							var	date=new Date(entry.publishedDate);
							cmtEntries[cmtEntries.length]=[
								(len-ci)+'. <a href="'+url+'">'+rid+'<\/a> '+date.toLocaleString()
							,	entry.content.replace(/^.*?reply.to:.*?<br[^>]*>/mi,'')
							].join('<br />');
						}
						var	block=d.createElement('blockquote'),style=block.style;
						style.border='3px double orange';
						style.background='lightyellow';
						style.padding='2px';
						style.display='none';
						style.color='navy';
						block.innerHTML=cmtEntries.join('<hr \/>');
						comment.parentNode.appendChild(block);
						var	showicon=new Image();
						showicon.title='show replies';
						showicon.src='http://d.hatena.ne.jp/images/icon-quickpager.gif';
						showicon.border=0;
						comment.parentNode.appendChild(showicon);
						setEventHandler(showicon,'mouseover',function(e){
							showicon.style.display='none';
							block.style.display='block';
						});
					}
				}
			);
		};
//		setEventHandler(button,'mouseover',addPreviewButton);
		addPreviewButton();
	})();
};	//	end of makeButton()

var	addButtonsToUserlist=function(curURL,userlist,doc){
	if (!doc) doc=d;
	if (!userlist) userlist=doc.getElementById('bookmarked_user');
	if (!userlist) return false;
	var	items=userlist.getElementsByTagName('li');
	var	checkItem=function(item){
		var	srcinfo=getElementsByTagAndClassName('span','title',doc)[0];
		if (!srcinfo) return false;
		var	srclink=srcinfo.getElementsByTagName('a')[0];
		if (!srclink) return false;
		if (!item.id||!item.id.match(/bookmark-user-(.+)$/)) return false;
		var	hid=RegExp.$1;
		var	comment=getElementsByTagAndClassName('span','comment',item)[0];
		if (!comment) return false;
		var	links=item.getElementsByTagName('a'),keyword='';
		var	re=new RegExp('/'+hid+'/(\\d+#bookmark-\\d+)$','');
		for (var cj=0,lenj=links.length; cj<lenj; cj++) {
			if (links[cj].href.match(re)) {
				keyword='hbcreply '+hid+' '+RegExp.$1;
				break;
			}
		}
		if (!keyword) return false;
		makeButton(hid,comment,keyword,srclink);
	};
	for (var ci=0,leni=items.length; ci<leni; ci++) checkItem(items[ci]);
	return true;
};	//	end of addButtonsToUserlist()

var	addButtonsToBMlist=function(curURL,doc){
	if (!doc) doc=d;
	if (!curURL.match(/^http:\/\/b\.hatena\.ne\.jp\/([^\/]+)/)) return false;
	var	hid=RegExp.$1;
	var	items=(doc.className=='bookmarklist')?[doc]:getElementsByTagAndClassName('dl','bookmarklist',doc);
	if (items.length<=0) return false;
	var	checkItem=function(item){
		var	srclink=getElementsByTagAndClassName('a','bookmark',item)[0];
		if (!srclink) return false;
		if (!item.id||!item.id.match(/(bookmark-.+)$/)) return false;
		var	key=RegExp.$1;
		var	date=getElementsByTagAndClassName('dd','timestamp',item)[0];
		if (!date) return false;
		var	comment=getElementsByTagAndClassName('span','comment',item)[0];
		if (!comment) return false;
		var	keyword='hbcreply '+hid+' '+date.innerHTML.replace(/[^\d]/g,'')+'#'+key;
		makeButton(hid,comment,keyword,srclink);
	};
	for (var ci=0,leni=items.length; ci<leni; ci++) checkItem(items[ci]);
	return true;
};	//	end of addButtonsToUserlist()

var	prepareComment=function(curURL){
	if (!curURL.match(/http:\/\/h\.hatena\.ne\.jp\/keyword\/hbcreply(.+)$/)) return false;
	var	items=decodeURIComponent(RegExp.$1).replace(/^\s+/,'').split(' ');
	if (items.length!=2) return false;
	var	form=getElementsByTagAndClassName('form','entry-form',d)[0];
	if (!form) return false;
	var	textarea=form.getElementsByTagName('textarea')[0];
	if (!textarea) return false;
	var	tgtURL='http://b.hatena.ne.jp/'+items.join('/');
	setTimeout(function(){
		var	text=getCookie('hbcr');
		var	srctitle=getCookie('hbct')||'';
		var	srcurl=getCookie('hbcu')|| '';
		var	Hatena=w.Hatena;
		var	hid=(Hatena&&Hatena.Visitor&&Hatena.Visitor.name)?Hatena.Visitor.name:'';
		delCookie('hbcr');
		delCookie('hbct');
		delCookie('hbcu');
		
		textarea.focus();
		
		var	values=[];
		values[values.length]='id:'+items[0];
		if (hid!=items[0]) values[values.length]='id:'+hid;
		if (srcurl) {
			values[values.length]='title: '+srctitle;
			values[values.length]='url: '+srcurl;
			values[values.length]='bookmark: http://b.hatena.ne.jp/entry/'+srcurl.replace(/#/g,function(s){return encodeURIComponent(s)});
		}
		values[values.length]='reply to: '+tgtURL;
		values[values.length]=' ';
		if (text) {
			textarea.style.height='240px';
			values[values.length]='| '+text;
			values[values.length]=' ';
		}
		values[values.length]='';
		textarea.value=values.join('\n');
		
	},0);
	return true;
};	//	end of prepareComment()

var	curURL=w.location.href;
addButtonsToUserlist(curURL);
prepareComment(curURL);
if (addButtonsToBMlist(curURL)&&AutoPagerize) {
	var	addFilter=(AutoPagerize.addElementFilter)?AutoPagerize.addElementFilter:AutoPagerize.addFilter;
	addFilter(function(nodes,url,siteinfo){
		if (!url&&0<nodes.length) {
			var	p=nodes[0].previousSibling;
			if (!p) return;
			var	link=p.getElementsByTagName('a')[0];
			if (!link) return;
			url=link.href;
		}
		for (var ci=0,len=nodes.length; ci<len; ci++) {
				addButtonsToBMlist(url,nodes[ci]);
		}
	});
}

(function(){
if (!usePreview) return;
var	google=w.google;
if (!google||typeof google.setOnLoadCallback!='function') {
	setTimeout(arguments.callee,100);
	return;
}
google.load('feeds','1', {callback:function(){
	googleReady=true;
}});
})();

})();

