// ==UserScript==
// @name        del.icio.us meets Hatena Bookmark
// @namespace   http://ma.la/
// @include     http://del.icio.us*
// @version     1.0.2
// ==/UserScript==

// http://la.ma.la/blog/diary_200512131313.htm

/*
required:
 Firefox1.5 and Greasemonkey0.6.4
original:
 http://d.hatena.ne.jp/m4i/20051213/1134425307
*/


(function(){

    Function.prototype.bind = function(object) {
        var __method = this;
        return function() {
            return __method.apply(object, arguments);
        };
    };
    var style = document.createElement('style');
    style.setAttribute('type', 'text/css');
    style.innerHTML
        =  '.hotter'
        +  '{'
        +  '	color: #ff6666 !important;'
        +  '	background-color: #fff0f0;'
        +  '	font-weight: bold;'
        +  '	font-style: normal;'
        +  '}'
        +  '.hottest'
        +  '{'
        +  '	color: red !important;'
        +  '	background-color: #ffcccc;'
        +  '	font-weight: bold;'
        +  '	font-style: normal;'
        +  '}';
    document.getElementsByTagName('head')[0].appendChild(style);


    function XMLRPC() {
        this.calls  = [];
        this.called = 0;
        this.chunk  = 0;
    }
    XMLRPC.prototype = {
        proxy: function(endPoint)
        {
            this.endPoint = endPoint;
            return this;
        },
        call: function(method, params)
        {
            this.parts = this.chunk ? Math.ceil(params.length / this.chunk) : 1;
            for (var i = 0; i < this.parts; i++) {
                var call =
                    <methodCall>
                        <methodName>{method}</methodName>
                        <params></params>
                    </methodCall>
                ;
                var param = this.chunk ?
                    params.slice(this.chunk * i, this.chunk * (i + 1)) : params;
                for (var j = 0; j < param.length; j++) {
                    call..params.appendChild(
                        <param><value><string>{param[j]}</string></value></param>
                    );
                }
                this.calls.push(call);
            }
            return this;
        },
        result: function(callback)
        {
            this.callback = callback;
            for (var i = 0; i < this.parts; i++) {
                GM_xmlhttpRequest({
                    method: 'post',
                    url: this.endPoint,
                    data: this.calls[i].toString(),
                    onload: this._loadHandler.bind(this)
                });
            }
            return this;
        },
        setChunk: function(chunk)
        {
            this.chunk = chunk;
            return this;
        },
        _loadHandler: function(res)
        {
            var response = new XML(res.responseText.replace(/^<\?xml.*?\?>/, ''));
            if (this.response) {
                this.response..struct.appendChild(response..member);
            } else {
                this.response = response;
            }
            if (++this.called == this.parts) {
                this.callback(this.response);
            }
        }
    };

    var entryURI = 'http://b.hatena.ne.jp/entry/';
    var endPoint = 'http://b.hatena.ne.jp/xmlrpc';


// for del.icio.us/url/
	if(location.href.indexOf("del.icio.us/url/") != -1){
	    var uris = [];
	    var hrefs = document.evaluate(
	        '//h4[@class="nomb"]/a/@href', document, null,
	        XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
	    var href = hrefs.iterateNext()
	    if(!href) return;
	    var uri = href.nodeValue;
	    uris.push(uri);
	    new XMLRPC()
	        .setChunk(50)
	        .proxy(endPoint)
	        .call('bookmark.getCount', uris)
	        .result(function(response) {
	            var res = {};
	            for each (var member in response..member) {
	                res[member.name] = member..int
	            }
	            var ul = document.evaluate(
	                '//h4[contains(@class,"smaller")]', document, null,
	                XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
	            var users = res[uri];
	            var a = document.createElement('a');
	            var li = document.createElement('small');
	            li.appendChild(document.createTextNode(" "));
	            a.setAttribute('href', entryURI + uri.replace(/#/, '%23'));
	            a.setAttribute('class', users >= 10 ? 'hottest'
	                                  : users >=  5 ? 'hotter'
	                                                : 'hot');
	            a.appendChild(document.createTextNode(
	                "?B : " + users + ((users >= 1) ? " users" : " user")
	            ));
	            li.appendChild(a);
	            li.appendChild(document.createTextNode(" "));
	            ul.appendChild(li);
	        });
		return;
	}

// for bookmarks,inbox

    var item_expr = '//ol[@class="posts"]/li[@class="post"]';
    var uris = [];
    var hrefs = document.evaluate(
        item_expr + '/h4[@class="desc"]/a/@href', document, null,
        XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    var href;
    while (href = hrefs.iterateNext()) {
        uris.push(href.nodeValue);
    }

// alert(uris);
// return;

    new XMLRPC()
        .setChunk(50)
        .proxy(endPoint)
        .call('bookmark.getCount', uris)
        .result(function(response) {
            var items = document.evaluate(
                item_expr, document, null,
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
            var res = {};
            for each (var member in response..member) {
                res[member.name] = member..int
            }
            for (var i = 0; i < items.snapshotLength; i++) {
                var uri = document.evaluate(
                    './h4[@class="desc"]/a/@href', items.snapshotItem(i), null,
                    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.nodeValue;
                var ul = document.evaluate(
                    './div[@class="meta"]', items.snapshotItem(i), null,
                    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                var users = res[uri];
                var a = document.createElement('a');
                var li = document.createElement('small');
                a.setAttribute('href', entryURI + uri.replace(/#/, '%23'));
                a.setAttribute('class', users >= 10 ? 'hottest'
                                      : users >=  5 ? 'hotter'
                                                    : 'hot');
                a.appendChild(document.createTextNode(
	                (users >= 1) ? "B:" + users + "" : ""
                ));
                li.appendChild(a);
                li.appendChild(document.createTextNode(" "));
                ul.insertBefore(li,ul.firstChild);
            }
        });

})();

