// ==UserScript==
// @name           hbFilter.user.js
// @namespace      http://furyu.tea-nifty.com/
// @description    HatenaBookmark::Filter ver.0.02b1
// @include        http://www.google*/search?*
// ==/UserScript==

(function(){
// === Options
var	limitWidth=36;
var	loadTimeOut=10000;

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

var	imgs=d.getElementsByTagName('img');
for (var ci=0,len=imgs.length; ci<len; ci++) {
	if (imgs[ci].src.match(/^http:\/\/b\.hatena\.ne\.jp\/entry\/image\//)) return;
}

// ===
function	getCookie(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()

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

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

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	getElementsByTagAndClassName=(function(){
	var	splitClassName=function(className){
		return className.replace(/\s+/g,' ').replace(/(^\s|\s$)/g,'').split(' ');
	};
	return function(tagName,className,doc) {
		if (!doc) doc=d;
		var children=doc.getElementsByTagName(tagName);
		if (className) {
			var	chkElms=(typeof className=='string')?splitClassName(className):className;
			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=splitClassName(cname);
				for (var cj=0,lenj=cnameElms.length; cj<lenj; cj++) {
					if (flgElms[cnameElms[cj]]) {
						elements[elements.length]=child;
						break;
					}
				}
			}
			return elements;
		}
		else {
			return children;
		}
	};
})();	//	end of getElementsByTagAndClassName()

var	statStrs={OFF:'<span class="hbfilter-status">[HB::Filter <span style="color:red;">OFF</span>]</a>'};
statStrs.ON=statStrs.OFF.replace(/red/,'blue').replace(/OFF/,'ON');
statStrs.loading=statStrs.OFF.replace(/OFF/,'loading...');

var	statusChange=(function(){
	var	work=d.createElement('div');
	return function(outer,innerHTML){
		work.innerHTML=innerHTML;
		while (outer.firstChild) outer.removeChild(outer.firstChild);
		while (work.firstChild) outer.appendChild(work.firstChild);
	};
})();

//var	sd=d.getElementById('sd');
var	sd=d.getElementById('prs');

if (!sd) return;
sd.appendChild(d.createTextNode(' '));
var infoStyle=sd.currentStyle||d.defaultView.getComputedStyle(sd,'');

var	hideEntries=[];
var	cntTarget=0;
var	cntComplete=0;
var	flgFilter=(getCookie('hbFilter')=='0')?false:true;

var	switchToOns=[],switchToOffs=[];

var	changeSwitchStyles=function(flg){
	var	ston=(flg=='ON')?'none':'inline';
	var	stoff=(flg=='ON')?'inline':'none';
	for (var ci=0,len=switchToOns.length; ci<len; ci++) {
		switchToOns[ci].style.display=ston;
		switchToOffs[ci].style.display=stoff;
	}
};
var	createSwitch=function(parent){
	//var	base=d.createElement('span');
	var	base=d.createElement('div');
	base.className='hbfilter-container';
	var	anchor='_hbFilter'+switchToOns.length;
	base.innerHTML='<a id="'+anchor+'"></a>';
	if (parent!=sd) {
		base.style.padding='0 16px';
		base.style.fontSize=infoStyle.fontSize;
		base.style.fontFamily=infoStyle.fontFamily;
		base.style.fontWeight=infoStyle.fontWeight;
		base.style.display='inline';
	}
	var	hbFilter=function(flg) {
		var	value=(flg)?'none':'block';
		for (var ci=0,len=hideEntries.length; ci<len; ci++) hideEntries[ci].style.display=value;
	}
	var	switchToOn=d.createElement('span');
	switchToOn.unselectable='on'; // IE only
	var	style=switchToOn.style;
	style.cursor='pointer';
	style.display='inline';
	statusChange(switchToOn,statStrs.loading);
	switchToOn.title='';
	switchToOn.__initcomp__=false;
	var	filterOn=function(){
		if (cntComplete<cntTarget) return;
		flgFilter=true;
		changeSwitchStyles('ON');
		hbFilter(true);
		setCookiePerm('hbFilter','1');
		w.location.hash=anchor;
	};
	setEventHandler(switchToOn,'click',filterOn);
	
	var	switchToOff=d.createElement('span');
	switchToOff.unselectable='on'; // IE only
	var	style=switchToOff.style;
	style.cursor='pointer';
	style.display='none';
	//switchToOff.innerHTML=statStrs.ON;
	statusChange(switchToOff,statStrs.ON);
	switchToOff.title='click to toggle';
	var	filterOff=function(){
		if (cntComplete<cntTarget) return;
		flgFilter=false;
		changeSwitchStyles('OFF');
		hbFilter(false);
		setCookiePerm('hbFilter','0');
		w.location.hash=anchor;
	};
	setEventHandler(switchToOff,'click',filterOff);
	
	base.appendChild(switchToOn);
	base.appendChild(switchToOff);
	setEventHandler(base,'mousemove',function(){
		try {w.getSelection().removeAllRanges()}catch(e){}
		return false;
	});
	if (parent==sd) {
		sd.parentNode.insertBefore(base,sd.nextSibling);
	}
	else {
		parent.appendChild(base);
	}
	switchToOffs[switchToOffs.length]=switchToOff;
	switchToOns[switchToOns.length]=switchToOn;
};

createSwitch(sd);

var	doCount=function(){
	if (++cntComplete<cntTarget) return;
	for (var ci=0,len=switchToOns.length; ci<len; ci++) {
		if (!switchToOns[ci].__initcomp__) {
			switchToOns[ci].title='click to toggle';
			//switchToOns[ci].innerHTML=statStrs.OFF;
			statusChange(switchToOns[ci],statStrs.OFF);
			switchToOns[ci].__initcomp__=true;
		}
	}
	changeSwitchStyles((flgFilter?'ON':'OFF'));
};
var	errSpan=d.createElement('span');
errSpan.innerHTML='&nbsp;(error)';
with (errSpan.style) {
	color='red';
	display='none';
	textDecoration='none';
	fontSize='smaller';
}
var	hbCheck=function(elm){
	var	srclink=getElementsByTagAndClassName('a','l',elm)[0];
	if (!srclink) {
		doCount();
		return;
	}
	var	url=srclink.href.replace(/#/g,function(s){return encodeURIComponent(s)});
	if (url.match(/^http:\/\/[^\/]*\.google\..*?\/url.*?[?&]q=([^?&]*)/)) {
		url=decodeURIComponent(RegExp.$1);
	}
	var	link=d.createElement('a');
	link.href='http://b.hatena.ne.jp/entry/'+url;
	var	img=new Image();
	img.border='0';
	img.style.margin='0 6px';
	img.src='http://b.hatena.ne.jp/entry/image/'+url;
	link.appendChild(img);
	var	err=errSpan.cloneNode(true);
	link.appendChild(err);
	if (srclink.nextSibling) {
		srclink.parentNode.insertBefore(link,srclink.nextSibling);
	}
	else {
		srclink.parentNode.appendChild(link);
	}
	img._loaded_=false;
	var	tid=setTimeout(function(){
		if (!img._loaded_) {
			img.style.display='none';
//			hideEntries[hideEntries.length]=elm;
//			if (flgFilter) elm.style.display='none';
			err.style.display='inline';
			img._loaded_=true;
			doCount();
		}
		tid=null;
	},loadTimeOut);
	setEventHandler(img,'load',function(){
		if (tid) clearTimeout(tid);
		if (img.width<limitWidth) {
			hideEntries[hideEntries.length]=elm;
			if (flgFilter) elm.style.display='none';
		}
		img.style.display='inline';
		err.style.display='none';
		img._loaded_=true;
		doCount();
	});
	setEventHandler(img,'error',function(){
		if (tid) clearTimeout(tid);
		img.style.display='none';
//		hideEntries[hideEntries.length]=elm;
//		if (flgFilter) elm.style.display='none';
		err.style.display='inline';
		img._loaded_=true;
		doCount();
	});
};

var	checkHeaders=function(doc){
/*
//	var	elms=getElementsByTagAndClassName('div','g',doc);
//	if (elms.length<=0) elms=[doc];
//	cntTarget+=elms.length;
//	for (var ci=0,len=elms.length; ci<len; ci++) {
//		hbCheck(elms[ci]);
//	}
*/
	var	elms1=getElementsByTagAndClassName('div','g',doc);
	var	elms2=getElementsByTagAndClassName('li','g',doc);
	var	sum=elms1.length+elms2.length;
	if (sum<=0) {
		elms1=[doc];
		sum=elms1.length;
	}
	cntTarget+=sum;
	for (var ci=0,len=elms1.length; ci<len; ci++) hbCheck(elms1[ci]);
	for (var ci=0,len=elms2.length; ci<len; ci++) hbCheck(elms2[ci]);
};

checkHeaders(d);

var	AutoPagerize=w.AutoPagerlike||oWindow.AutoPagerize;
if (AutoPagerize) {
	var	addFilter=(AutoPagerize.addElementFilter)?AutoPagerize.addElementFilter:AutoPagerize.addFilter;
	addFilter(function(nodes,url,siteinfo){
		var	topElm=null,topNum=0;
		for (var ci=0,len=nodes.length; ci<len; ci++) {
			var	node=nodes[ci];
			if (!node._hbFiltered_) {
				topNum=ci;
				topElm=node;
				break;
			}
		}
		if (!topElm) return;
		var	chk=topElm.previousSibling;
		while (chk) {
			var	link=getElementsByTagAndClassName('a','autopagerize_link',chk)[0];
			if (link) {
				createSwitch(link.parentNode);
				break;
			}
			chk=chk.previousSibling;
		}
		for (var ci=topNum,len=nodes.length; ci<len; ci++) {
			var	node=nodes[ci];
			node._hbFiltered_=true;
			checkHeaders(node);
		}
	});
}

})();

