// Hatena Black Star user script
// for
//   Firefox3.0(Greasemonkey)
// by Hamachiya2. (http://d.hatena.ne.jp/Hamachiya2/20090904/HatenaBlackStar)

// 2008-07-05
// 2009-09-04

// ==UserScript==
// @name           Hatena Black Star
// @namespace      http://hamachiya.com/
// @description    Hatena Black Star
// @include        http://b.hatena.ne.jp/entry/*
// @version        0.5f
// ==/UserScript==

/*@cc_on _d=document;eval('var document=_d')@*/


location.href = 'javascript:(' + function() { (function (win) {


var hbsAddButton = 'http://img.f.hatena.ne.jp/images/fotolife/H/Hamachiya2/20090904/20090904022349.gif';

var hbs = function(ev) {

/* Hatena.Star.AddButton */
win.Hatena.Star.AddButton = new win.Ten.Class({
    base: [win.Hatena.Star.Button],
    initialize: function(entry,container) {
        this.entry = entry;
        this.lastPosition = null;
        this.selectedText = null;
        this.showSelectedColorTimerId = null;
        this.hideSelectedColorTimerId = null;

/* AddButton ha kokokara ... */
		var jkonStar = !win.Ten.DOM.hasClassName(container, 'BlackStarContainer');

		var src = hbsAddButton;
		if (jkonStar) {
			src = win.Hatena.Star.Button.getImgSrc(this.constructor,container);

		}
/* kokomade kakikae tai dake nandayo ... */

        var img = win.Hatena.Star.Button.createButton({
            src: src,
            tabIndex: 0,
            alt: 'Add Star',
            title: 'Add Star'
        });
        img.className = 'hatena-star-add-button';
        new win.Ten.Observer(img,'onclick',this,'addStar');
        new win.Ten.Observer(img,'onclick',this,'hideColorPallet');
        new win.Ten.Observer(img,'onkeyup',this,'handleKeyUp');
//        new win.Ten.Observer(img,'onmouseover',this,'showSelectedColor');

/* AddButton ha kokokara ... */
		if (jkonStar) {
	        new win.Ten.Observer(img,'onmouseover',this,'showColorPalletDelay');
		}

        new win.Ten.Observer(img,'onmouseover',this,'copySelectedText');
        new win.Ten.Observer(img,'onmouseout',this,'clearSelectedColorTimer');
/* kokomade kakikae tai dake nandayo ... */


//        new win.Ten.Observer(img,'onmouseout',this,'hideSelectedColor');
//        new win.Ten.Observer(img,'onmouseout',this,'hideSelectedColor');
        this.img = img;
        return img;
    },
    ImgSrcSelector: '.hatena-star-add-button-image',
    ImgSrc: win.Hatena.Star.BaseURL + 'images/add.gif'
},{
    handleKeyUp: function(e) {
        if (!e.isKey('enter')) return;
        this.addStar(e);
    },
    clearSelectedColorTimer : function() {
        try{ clearTimeout(this.showSelectedColorTimerId); }catch(e){};
        try{ clearTimeout(this.hideSelectedColorTimerId); }catch(e){};
    },
    showSelectedColor : function(e) {
        var self = this;
        this.clearSelectedColorTimer();
        this.showSelectedColorTimerId = setTimeout(function(){
            //if (!self.pallet || (self.pallet && self.pallet.isColorPallet()) ) self._showSelectedColor();
            self._showSelectedColor();
        },300);
    },
    _showSelectedColor : function(e) {
        if (this.pallet) {
        } else {
            this.pallet = new win.Hatena.Star.Pallet();
        }
        if (this.pallet.isNowLoading) return;
        var pos = win.Ten.Geometry.getElementPosition(this.img);
        if (win.Ten.Browser.isFirefox || win.Ten.Browser.isOpera) {
            pos.y += 15;
            pos.x += 2;
        } else {
            pos.y += 13;
        }
        this.pallet.showSelectedColor(pos, this);
    },
    hideColorPallet : function(e) {
        try {
            this.pallet.hide();
        } catch(e) {}
    },
    hideSelectedColor : function(e) {
        var self = this;
        this.clearSelectedColorTimer();
        this.hideSelectedColorTimerId = setTimeout(function(){
            if (self.pallet.isSelectedColor) {
                //if (!self.pallet || (self.pallet && self.pallet.isSelectedColor()) ) self._showSelectedColor();
                self.pallet.hide();
            }
        },2000);
    },
    showColorPalletDelay : function(e) {
        var self = this;
        this.clearSelectedColorTimer();
        this.showSelectedColorTimerId = setTimeout(function(){
            //if (!self.pallet || (self.pallet && self.pallet.isColorPallet()) ) self._showSelectedColor();
            self.showColorPallet();
        },800);
    },
    showColorPallet : function(e) {
        this.clearSelectedColorTimer();
        if (!this.pallet) this.pallet = new win.Hatena.Star.Pallet();
        var pos = win.Ten.Geometry.getElementPosition(this.img);
        if (win.Ten.Browser.isFirefox || win.Ten.Browser.isOpera) {
            pos.y += 15;
            pos.x += 2;
        } else {
            pos.y += 13;
        }
        this.pallet.showPallet(pos, this);
    },
    copySelectedText: function(e) {
        this.selectedText = win.Ten.DOM.getSelectedText().substr(0,200);
    },
    addStar: function(e) {
        this.clearSelectedColorTimer();
        this.color = (this.color) ? this.color : 'yellow';
        this.entry.addTemporaryStar({color: this.color});
        this.lastPosition = e.mousePosition();
        var quote = this.selectedText;
        var uri = win.Hatena.Star.BaseURL + 'star.add.json?uri=' + encodeURIComponent(this.entry.uri) +
            '&title=' + encodeURIComponent(this.entry.title) +
            '&quote=' + encodeURIComponent(quote) +
            '&location=' + encodeURIComponent(document.location.href);
        if (win.Hatena.Star.Token) {
            uri += '&token=' + win.Hatena.Star.Token;
        }
        if (win.Hatena.Visitor) {
            if (win.Hatena.Visitor.RKS) {
                uri += '&rks=' + win.Hatena.Visitor.RKS;
            }
            if (win.Hatena.Visitor.sessionParams) {
                var params = win.Hatena.Visitor.sessionParams;
                for (var key in params) {
                    uri += '&' + key + '=' + encodeURIComponent(params[key]);
                }
            }
        }
        new win.Ten.JSONP(uri, this, 'receiveResult');
    },
    receiveResult: function(args) {
        this.entry.removeTemporaryStar();
        var name = args ? args.name : null;
        var color = args ? args.color : '';
        var pos = this.lastPosition;
        pos = (pos) ? pos : win.Ten.Geometry.getElementPosition(this.img);
        pos.x -= 10;
        pos.y += 25;
        if (name) {
            this.entry.addStar({
                color: color,
                name: name,
                quote: args.quote
            });
            //alert('Succeeded in Adding Star ' + args);
        } else if (args.is_guest && args.html) {
            var win = new win.Hatena.LoginWindow();
            win.addLoginForm(args.html);
            win.show(pos);
        } else if (args.errors) {
            var scroll = win.Ten.Geometry.getScroll();
            var scr = new win.Hatena.Star.AlertScreen();
            var alert = args.errors[0];
            scr.showAlert(alert, pos);
        }
    }
}); // win.Hatena.Star.AddButton




win.Hatena.Star.EntryLoader.getStarEntries = function() {
	var c = win.Hatena.Star.EntryLoader;
	var entries = c.entries;
	if (!entries.length) return;
	var endpoint = 'entries.simple.json?';
	var url = win.Hatena.Star.BaseURL + endpoint;

	// normal loading
	for (var i = 0; i < entries.length; i++) {
	    if (url.length > win.Ten.JSONP.MaxBytes) {
			new win.Ten.JSONP(url, c, 'receiveStarEntries');
			url = win.Hatena.Star.BaseURL + endpoint;
	    }
	    url += 'uri=' + encodeURIComponent(entries[i].uri) + '&';
	}
	new win.Ten.JSONP(url, c, 'receiveStarEntries');
} // win.Hatena.Star.EntryLoader.getStarEntries




HatenaBlackStar = {
    loadStar: function(cssSelector, parentNode) {
        var elements;
        try {
            elements = win.Ten.Selector.getElementsBySelector(cssSelector, parentNode || document.body);
        } catch(e) {};
        if (!elements) return;
        HatenaBlackStar.loadElements( elements );
    },
    loadElements: function(elements) {
        var entries = [];
        for (var i = 0;  i < elements.length; i++) {
            var element = elements[i];
            var entry = new HatenaBlackStar.createCommentEntry(element)
            if (!(entry && entry.uri)) {
                entry = new HatenaBlackStar.createArticleEntry(element);
            }
            if (entry && entry.uri)
                entries.push(entry);
        }
        if (entries.length)
            win.Hatena.Bookmark.Star.addEntries(entries);
    },
    addEntries: function(entries) {
        var c = win.Hatena.Star.EntryLoader;
        var entries_org = c.entries;
        c.entries = null;
        c.entries = [];
        if (entries && typeof(entries.length) == 'number') {
            for (var i = 0; i < entries.length; i++) {
                var e = new win.Hatena.Star.Entry(entries[i]);
                e.showButtons();
                c.entries.push(e);
            }
        }
        c.getStarEntries();
        if (entries_org) {
            c.entries.push(entries_org);
            c.entries = win.Ten.Array.flatten(c.entries);
        }
    },
    createArticleEntry: function(el) {
        var entry = {};
        var a = el.getElementsByTagName('a')[0];
        if (!a) return;
    
        entry.uri = a.href;
        var title = win.Ten.DOM.scrapeText(el);
        entry.title = title;
    
        HatenaBlackStar.addStarElement(entry, el);
        return entry;
    },
    createCommentEntry: function(el) {
        // コメントの li に対する Entry の作成
        var entry = {};
        var a = win.Ten.DOM.getElementsByTagAndClassName('a', 'username', el)[0];
        if (!a) return null;
        var pathname = a.pathname.replace(/^\//, '');
        entry.uri = 'http://b.hatena.ne.jp/' + pathname + a.hash;

		if (entry.uri.indexOf('#') == -1) {
			entry.uri = entry.uri + '#_HatenaBlackStar';
		} else {
			entry.uri = entry.uri + '_HatenaBlackStar';
		}


        var title = '';
        var tags = win.Ten.DOM.getElementsByTagAndClassName('a', 'user-tag', el);
        for (var i = 0; i < tags.length; i++) {
            title += '[' + win.Ten.DOM.scrapeText(tags[i]) + ']';
        }
        var comments = win.Ten.DOM.getElementsByTagAndClassName('span', 'comment', el)[0];
        if (comments) {
            title += win.Ten.DOM.scrapeText(comments);
        }
        if (!title) {
            title =  win.Ten.DOM.scrapeText(a) + 'のブックマーク';
        }
        entry.title = title;

        HatenaBlackStar.addStarElement(entry, el);
        return entry;
    },
    addStarElement: function(entry, el) {
        entry.comment_container = win.Hatena.Star.EntryLoader.createCommentContainer();
        entry.star_container = win.Hatena.Star.EntryLoader.createStarContainer();

		entry.star_container.className = 'hatena-star-star-container BlackStarContainer';


        entry.comment_container.style.display = 'none';
        el.appendChild(entry.comment_container);
        el.appendChild(entry.star_container);

/*
		setTimeout(function() {
			var aa = win.Ten.DOM.getElementsByTagAndClassName('img', 'hatena-star-add-button', entry.star_container);
			aa[0].src = 'http://img.f.hatena.ne.jp/images/fotolife/H/Hamachiya2/20090904/20090904022349.gif';
		}, 100);
*/

    },
    createByEntryTitle: function() {
        if (document.getElementById('entry_star_count')) {
            var li = document.getElementById('entry_star_count');
            var h2 = win.Ten.DOM.getElementsByTagAndClassName('h2', 'entrytitle', document)[0];
            var entries = [];
            if(li && h2) {
                var a = h2.getElementsByTagName('a')[0];

				var u;

				if (a.href.indexOf('#') == -1) {
					u = a.href + '#_HatenaBlackStar';
				} else {
					u = a.href + '_HatenaBlackStar';
				}

                var entry = {
                    title: win.Ten.DOM.scrapeText(h2),
                    uri: u
                };
                HatenaBlackStar.addStarElement(entry, li);
                entries.push(entry);
                HatenaBlackStar.addEntries(entries);
            }
        }
    }
} // End of HatenaBlackStar





function addCSS(css){
	// addCSS by id:os0x (0xFF)
	// http://d.hatena.ne.jp/os0x/20090126/1232953502

	var sheet, self = arguments.callee;
	if (document.createStyleSheet) { // for IE
		sheet = document.createStyleSheet();
		sheet.cssText = css;
		return sheet;
	} else if (!self.__style || !self.__root) {
		sheet = document.createElement('style');
		sheet.type = 'text/css';
		self.__style = sheet;
		self.__root = document.getElementsByTagName('head')[0] || document.documentElement;
	}
	sheet = self.__style.cloneNode(false);
	sheet.textContent = css;
	return self.__root.appendChild(sheet).sheet;
} // addCSS



function addHbcStyle() {
	var starStyle =
		  " .BlackStarContainer a:before { content: '★'; }"
		+ " .BlackStarContainer a .hatena-star-star { filter: alpha(opacity=00); -moz-opacity: 0.00; opacity: 0.00; position: absolute; top: 0; left: 0; }";

	if (win.Ten.Browser.isIE) {
		starStyle =
		  " .BlackStarContainer a .hatena-star-star { filter: Xray(); }"
	}

	addCSS(
		  " .BlackStarContainer { margin-left: 6px; }"
		+ " .BlackStarContainer .hatena-star-add-button { }"
		+ " .BlackStarContainer a { text-decoration: none ! important;color: #444 ! important; font-size: 10px; position: relative; }"
		+ " .BlackStarContainer .hatena-star-inner-count { color: #555 ! important; }"
		+ starStyle
	);
} // addHbcStyle


	HatenaBlackStar.createByEntryTitle();
	HatenaBlackStar.loadStar('ul#bookmarked_user li', document.body);
	addHbcStyle();
}; // End of hbs




var win = this.unsafeWindow || this.contentWindow || this;

var hbsTimerCount = 0;
var hbsTimerTryMax = 20;
var hbsTimerInterval = 500;
var hbsTimer = null;


function startHatenaBlackStar() {
	if (typeof(win.Ten) == 'undefined' || typeof(win.Hatena) == 'undefined') {
		if (++hbsTimerCount > hbsTimerTryMax) {
			clearTimeout(hbsTimer);
		} else {
			hbsTimer = setTimeout(startHatenaBlackStar, hbsTimerInterval);
		}
		return;

	} else {
		clearTimeout(hbsTimer);
		hbs();
	}
}




(function() {
	if (typeof(addEventListener) == 'function') {
		addEventListener('load', startHatenaBlackStar, false);
	} else {
		attachEvent('onload', startHatenaBlackStar);
	}
})();


})(window); }.toString() + ')()';
