// ==UserScript==
// @name           nicoSBM.user.js
// @namespace      http://furyu.tea-nifty.com/
// @description    nicoSBM ver.0.02f
// @include        http://*
// ==/UserScript==

if (typeof unsafeWindow!='undefined') {
	var	__orgWindow__=window;
	window=unsafeWindow;
	document=window.document;
}
(function(){
try {if (window!=top||(window.opener&&window.opener.location.href==window.location.href)) return}catch(e){};
var	w=window,d=document;

// === Options
var	mqMax=20;
var	mqFontPixelMin=16;
var	mqFontPixelMax=32;
var	mqStrLengthMax=100;
var	mqTopOffset=100;
var	mqDelay=70;
var	mqStepMin=6;
var	mqStepMax=10;
var	mqFontFamily='"Hiragino Kaku Gothic Pro", "MS PGothic", Osaka, sans-serif';
var	mqColors=[
	'darkorange'
,	'darkgreen'
,	'brown'
,	'purple'
,	'navy'
,	'lime'
,	'deeppink'
];
var	mqTotalColor='red';
var	mqImageIcon=true;
var	mqShowId=true;
var	mqRetry=3;

// ===
var	debug=false;
var	cmtEntries=[];

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

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	getClientWidth=(function(){
	if (typeof w.innerWidth!='undefined') {
		return function() {return w.innerWidth};
	}
	else if (d.all) {
		if (d.compatMode=='CSS1Compat') {
			return function() {return d.documentElement.clientWidth};
		}
		else {
			return function() {return d.body.clientWidth};
		}
	}
	else {
		return function() {return 0};
	}
})();	//	end of getClientWidth()

var	getClientHeight=(function(){
	if (typeof w.innerHeight!='undefined') {
		return function() {return w.innerHeight};
	}
	else if (d.all) {
		if (d.compatMode=='CSS1Compat') {
			return function() {return d.documentElement.clientHeight};
		}
		else {
			return function() {return d.body.clientHeight};
		}
	}
	else {
		return function() {return 0};
	}
})();	//	end of getClientHeight()

var	marqs=[];

var	tid=null;
var	getFontPixel=function(textLen){
	var	fontPixel=mqFontPixelMin;
	if (mqFontPixelMin<mqFontPixelMax) {
		var	fontColorNum=0,chkLen=0;
		var	lenStep=~~(mqStrLengthMax/(mqFontPixelMax-mqFontPixelMin))*4;
		for (fontPixel=mqFontPixelMax;mqFontPixelMin<fontPixel;fontPixel-=4,chkLen+=lenStep,fontColorNum++) {
			if (textLen<chkLen+lenStep) break;
		}
	}
	return fontPixel;
};

var	startScroll=function(){
	var	scrollStep=function(){
		for (var ci=0,len=marqs.length; ci<len; ci++) {
			var	params=marqs[ci].__params__;
			var	marqinner=params.marqinner;
			var	style=marqinner.style;
			var	left=style.left.replace(/[^\d\-]/g,'');
			left-=params.step;
			if (left<-params.width) {
				left=params.width-1;
				params.step=(mqStepMin+~~((mqStepMax-mqStepMin+1)*Math.random()));
				if (!params.istotal) {
					style.color=mqColors[~~(mqColors.length*Math.random())];
					if (0<cmtEntries.length) {
						var	oldentry=params.entry,entry=cmtEntries.shift();
						while (marqinner.firstChild) marqinner.removeChild(marqinner.firstChild);
						var	text=entry.content,hid=entry.id,fontPixel=getFontPixel(text.length);
						if (mqImageIcon) {
							var	img=new Image();
							img.src='http://www.hatena.ne.jp/users/'+hid.slice(0,2)+'/'+hid+'/profile.gif';
							img.title=img.alt='id:'+hid;
							img.width=img.height=fontPixel;
							marqinner.appendChild(img);
						}
						if (!mqImageIcon||mqShowId) {
							text='[id:'+hid+']'+text;
						}
						style.fontSize=fontPixel+'px';
						marqinner.appendChild(d.createTextNode(text));
						params.entry=entry;
						cmtEntries[cmtEntries.length]=oldentry;
					}
				}
			}
			style.left=left+'px';
		}
	}
	tid=setInterval(scrollStep,mqDelay);
};

var	stopScroll=function(){
	if (tid) {
		clearInterval(tid);
		tid=null;
	}
	for (var ci=0,len=marqs.length; ci<len; ci++) {
		marqs[ci].parentNode.removeChild(marqs[ci]);
	}
};

var	tops=[];
(function(){
var	setno=[];
var	maxTop=getClientHeight()-mqFontPixelMax*2-mqTopOffset;
var	topcnt=0,topstep=~~(maxTop/(mqMax+1)),curtop=0;
for (;;) {
	if (topstep<1) topstep=1;
	for (curtop=0; curtop<maxTop; curtop+=topstep) {
		if (!setno[curtop]||topstep==1) {
			tops[tops.length]=curtop;
			setno[curtop]=true;
			if (mqMax+1<=tops.length) break;
		}
	}
	if (curtop<maxTop) break;
}
})();

var	createMarquee=function(entry){
	var	hid=entry.id,text=entry.content,link=entry.link;
	
	var	textLen=text.length;
	if (!textLen||textLen<=0) return;
	var	width=getClientWidth();
	var	topno=~~(tops.length*Math.random()),top=tops[topno]+mqTopOffset;
	tops.splice(topno,1);
	
	if (width<=0||top<=0) return;
	var	startleft=~~(width*Math.random()+width);
	var	marq=d.createElement('div');
	var	style=marq.style;
	style.zIndex=1000000;
	style.width='100%';
	style.backgroundColor='transparent';
	style.top=top+'px';
	style.left=0;
	style.position='absolute';
	style.padding=0;
	style.overflow='hidden';

	var	marqinner=d.createElement('div');
	var	style=marqinner.style;
	style.position='relative';
	style.left=startleft+'px';
	style.fontWeight='normal';
	style.lineHeight='120%';
	var	fontPixel=getFontPixel(textLen);
	style.fontSize=fontPixel+'px';
	var	istotal=(hid===null);
	style.color=(istotal)?mqTotalColor:mqColors[~~(mqColors.length*Math.random())];
	style.width='100%';
	style.margin=0;
	style.padding=0;
	style.fontFamily=mqFontFamily;
	style.fontWeight='bolder';
	style.cursor='pointer';
	style.textAlign='left';
	if (mqImageIcon) {
		var	img=new Image();
		if (istotal) {
			img.src='http://b.hatena.ne.jp/images/bookmark.gif';
			img.title=img.alt='total';
		}
		else {
			img.src='http://www.hatena.ne.jp/users/'+hid.slice(0,2)+'/'+hid+'/profile.gif';
			img.title=img.alt='id:'+hid;
			img.width=img.height=fontPixel;
		}
		marqinner.appendChild(img);
	}
	if (!mqImageIcon||mqShowId) {
		text=((istotal)?'[total]':'[id:'+hid+']')+text;
	}
	marqinner.appendChild(d.createTextNode(text));
	marqinner.unselectable='on'; // IE only
	
	marq.appendChild(marqinner);
	marq.__params__={
		marqinner	:	marqinner
	,	step		:	(mqStepMin+~~((mqStepMax-mqStepMin+1)*Math.random()))
	,	width		:	width
	,	istotal		:	istotal
	,	entry		:	entry
	};
	setEventHandler(marq,'click',function(e){
		if (!e) e=w.event;
		if (!e||!e.shiftKey) stopScroll();
	});
	setEventHandler(marqinner,'click',function(e){
		if (!e) e=w.event;
		if (e&&e.shiftKey) w.open(link,'_blank');
	});
	setEventHandler(marqinner,'mousemove',function(e){
		try {w.getSelection().removeAllRanges()}catch(e){}
		return false;
	});
	d.body.appendChild(marq);
	marqs[marqs.length]=marq;
	return marq;
};

var	baseURL='http://b.hatena.ne.jp/entry/',baseRSS=baseURL+'rss/',targetURL=w.location.href;

w.nicoSBMCallback=function(result){
	if (result&&0<result.count) {
		var	entries=result.value.items,tmpEntries=[];
		for (var ci=0,len=entries.length; ci<len; ci++) {
			var	entry=entries[ci], content=stripTags(entry.content);
			if (0<content.replace(/(\s|[\r\n])/mg,'').length) {
				tmpEntries[tmpEntries.length]={
					id		:	entry.title
				,	content	:	content
				,	link	:	entry.link
				};
			}
		}
		while (0<tmpEntries.length){
			var	num=~~(tmpEntries.length*Math.random()),entry=tmpEntries[num];
			cmtEntries[cmtEntries.length]=entry;
			tmpEntries.splice(num,1);
		}
		var	total=cmtEntries.length,mqcnt=0;
		if (mqTotalColor&&0<total) {
			new createMarquee({
				id		:	null
			,	content	:	total+' comment'+((total==1)?'':'s')
			,	link	:	baseURL+targetURL
			});
		}
		while (0<cmtEntries.length&&(mqMax<=0||mqcnt<mqMax)) {
			var	entry=cmtEntries.shift();
			new createMarquee(entry);
			mqcnt++;
		}
		startScroll();
	}
};

(function(){
	var	s=d.createElement('script');
	s.type='text/javascript';
	s.src='http://pipes.yahoo.com/furyu/hbcmt?_render=json&_callback=nicoSBMCallback&_run=1&url='+encodeURIComponent(targetURL);
	d.body.insertBefore(s,d.body.lastChild);
//	d.body.appendChild(s);
})();

})();

