// ==UserScript==
// @name           FlickrReferrersDecode
// @version        0.9
// @namespace      http://tsuyuguchi.com/
// @description    decode search words in flickr stats
// @include        http://www.flickr.com/photos/*
// ==/UserScript==

/*
 * Change History
version 0.9
	- add kanpeki.inucara.net, technorati.jp and http://summize.com
version 0.8
	- add search.hp.netscape.com
version 0.7
	- user RexExp for check pathname
version 0.6
	- add http://flickr.com/photos/tags/...
version 0.5
	- changed applied url from .../stats/ref/.. to ../stats/
	- show favicon in .../stats/
	- show bigger image when mouseover in .../stats/
version 0.4
	- enable to show favicon.ico
version 0.3
	- add srd.yahoo.co.jp, r.hatena.ne.jp
version 0.2
	- configurable decode parameter
version 0.1
	- initial version
*/
(function(){

/*---- Configuration -------------------------------------------------*/
var target = [
    { "url" : "http://image-search.yahoo.co.jp",
      "param" : "p=([^&]+)" },
    { "url" : "http://technorati.jp",
      "param" : ".jp(/.*)" },
    { "url" : "http://srd.yahoo.co.jp",
      "param" : "q=([^/]*)" },
    { "url" : "r.hatena.ne.jp",
      "param" : "/keyword/(.*)" },
    { "url" : "http://flickr.com",
      "param" : "/photos(/tags/.*)" },
    { "url" : "search.hp.netscape.com",
      "param" : "query=([^&]+)" },
    { "url" : "search.naver.com",
      "param" : "query=([^&]+)" },
    { "url" : "http://kanpeki.inucara.net/",
      "param" : "search/(.*)" },
    { "url" : "http://technorati.jp",
      "param" : "/photos(/tag/.*)" },
    { "url" : "http://summize.com",
      "param" : "q=([^&]+)" }
];

/*-------------------------------------------------------------------*/

/* ref: http://www.webtoolkit.info/javascript-url-decode-encode.html */
var Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

var decode_parameter = function( nodes  /* nodes retrieved by xpath */ ){
	var nodes_length = nodes.snapshotLength;
	for (var i = 0; i < nodes_length; i++)
	{
	    var ref = nodes.snapshotItem(i);
	    var href = ref.getAttribute("href");
	    
	    var target_length = target.length;
	    for( var j = 0; j < target_length; j++ ){
	        if( href.indexOf( target[j].url ) != -1 ){
	            var regexp = new RegExp( target[j].param );
	            if( href.match( regexp ) ){
	                ref.innerHTML = Url.decode( RegExp.$1.replace( /\+/g , ' ' ) );
	            }
	            break;
	        }
	    }
	}
}

var show_favicon = function( node ){
	var nodes_length = nodes.snapshotLength;
	for (var i = 0; i < nodes_length; i++)
	{
	    var img = nodes.snapshotItem(i);
	    var src = img.getAttribute("src");
	    if( src != "http://l.yimg.com/www.flickr.com/images/spaceball.gif" ){
	    	continue;
	    }
	    /* this onerror works to put back spacer when no favicon */
	    img.setAttribute("onerror", "this.src='http://l.yimg.com/www.flickr.com/images/spaceball.gif'");
	    img.setAttribute("src", "http://" + img.getAttribute("alt") + "/favicon.ico" );
	}
}

/*
var show_all_sizes_button = function(){
	var zoom_button = document.getElementById("photo_gne_button_zoom");
	if( zoom_button )
		return;
	// maybe video page
	var button_bar = document.getElementById("button_bar");
	var a = document.createElement('a');
	a.setAttribute("alt",'All sizes');
 	a.setAttribute("style","width: 47px; cursor: pointer;");
 	a.setAttribute("onmouseover","this.class='sprite-zoom_color'");
 	a.setAttribute("onmouseout","this.class='sprite-zoom_grey'");
 	a.setAttribute("onclick",'this.blur(); return true;');
 	a.setAttribute("class",'sprite-zoom_grey');
 	a.setAttribute("id",'photo_gne_button_zoom');
 	a.setAttribute("href",pathname+'sizes/o/');
 	a.innerHTML = "&nbsp;";
	button_bar.appendChild(a);
}
*/

var set_mouseover = function( node ){
	var nodes_length = nodes.snapshotLength;
	for (var i = 0; i < nodes_length; i++)
	{
		var img = nodes.snapshotItem(i);
		img.setAttribute("onmouseover", "this.width=75;this.height=75;");
		img.setAttribute("onmouseout",  "this.width=25;this.height=25;");
	}
}

var pathname = document.location.pathname;
var stats_top_regexp = new RegExp("^/photos/[^/]+/stats/$");
var stats_domain_detail_regexp = new RegExp("^/photos/[^/]+/stats/refs/[^/]+/[^/]+/$");
var stats_periodic_regexp = new RegExp("^/photos/[^/]+/stats/refs/[^/]+/$");
/*
if( pathname.match( new RegExp("^/photos/[^/]+/[0-9]+/$") )){
	show_all_sizes_button();
	return;
	
}
*/
if( pathname.match( stats_top_regexp ) ){
	var nodes = document.evaluate('//td[@class="dicon"]/img',
	                              document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	show_favicon( nodes );

	var nodes = document.evaluate('//img[@class="pc_img"]',
	                              document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	set_mouseover( nodes );

	return;
}

if( pathname.match( stats_domain_detail_regexp ) ){

	var nodes = document.evaluate('//div[@id="refs"]/table/tbody/tr/td[2]/a',
	                               document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	decode_parameter( nodes );
	return;
}


if( pathname.match( stats_periodic_regexp ) ){
	var nodes = document.evaluate('//div[@id="refs"]/table/thead/tr/th[3]',
	                               document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var node = nodes.snapshotItem(0);
	var button = document.createElement("input");
	button.setAttribute("type","button");
	button.setAttribute("value","decode");
	node.appendChild(button);
	button.addEventListener("click", function(){
		var nodes = document.evaluate('//div[@id="refs"]/table/tbody/tr/td[3]/div/div/ul/li/a',
		                               document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		decode_parameter( nodes );
	}, false);

	
	nodes = document.evaluate('//td[@class="icon"]/img',
	                              document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	show_favicon( nodes );

	return;
}


})();
