// ==UserScript==
// @name           Hide the tag
// @namespace      http://fg-180.katamayu.net/userscripts
// @include        http://b.hatena.ne.jp/*
// ==/UserScript==


(function () {
    unsafeWindow.Object.extend(Array.prototype, unsafeWindow.Array.prototype);
    var $A = unsafeWindow.$A;
    var $ = unsafeWindow.$;
    var Class = unsafeWindow.Class;

    var IgnoredTags = Class.create();

    IgnoredTags.prototype = {
        initialize: function () {
            this.tags = GM_getValue('tags', '').split('[').map(function (tag) { return decodeURIComponent(tag); });
        },
        save: function () {
            GM_setValue('tags', this.tags.map(function (it) { return encodeURIComponent(it); }).join('['));
        },
        clear: function () {
            this.tags = [];
            this.save();
        },
        add: function (tag) {
            this.tags.push(tag);
            this.save();
        },
        delete: function (tag) {
            this.tags = this.tags.without(tag);
            this.save();
        },
        include: function (tag) {
            return this.tags.include(tag);
        }
    };

    var relatedTaglist = document.getElementById('related-taglist');
    var ignoredTags = new IgnoredTags();

    if (!relatedTaglist) {
        ignoredTags.clear();
    } else {
        function redrawBookmark() {
            var comments = $A(document.getElementsByTagName('dd')).select(function (dl) { return dl.className == 'comment'; });

            comments.each(function (comment) {
                var tags = $A(comment.getElementsByTagName('a')).map(function (a) { return a.innerHTML; });

                if (tags.any(function (tag) { return ignoredTags.include(tag); })) {
                    comment.parentNode.style.display = "none";
                } else {
                    comment.parentNode.style.display = "block";
                }
            });
        }

        var SwitchLink = function (tagLink, ignoredTags) {
             var tagName = tagLink.innerHTML;
             var sw = document.createElement('a');
             sw.href = "#";
             var onclick;

             this.show = function () {
                 if (onclick == showTag) {
                     sw.innerHTML = '-';
                     onclick = hideTag;
                 }
             }

             function hideTag() {
                 ignoredTags.add(tagName);
                 sw.innerHTML = '+';
                 onclick = showTag;
             }

             function showTag() {
                 ignoredTags.delete(tagName);
                 sw.innerHTML = '-';
                 onclick = hideTag;
             }
            
             if (ignoredTags.include(tagLink.innerHTML)) { 
                sw.innerHTML = '+';
                onclick = showTag;
             } else {
                sw.innerHTML = '-';
                onclick = hideTag;
             }

             sw.addEventListener('click', function () { 
                     onclick(); 
                     redrawBookmark();
                     }, true);

             tagLink.parentNode.appendChild(sw);
        };
        
        var switchLinks = [];

        redrawBookmark();

        var reset = document.createElement('a');
        reset.innerHTML = 'show all';
        reset.addEventListener('click', function () {
                ignoredTags.clear(); 
                redrawBookmark(); 
                switchLinks.each(function (sl) { sl.show(); });
                return false; 
                }, true);
        var div = document.createElement('div');
        div.style.textAlign = 'center';
        div.appendChild(reset);
        relatedTaglist.parentNode.insertBefore(div, relatedTaglist);

        $A(relatedTaglist.getElementsByTagName('a')).each(function (a) {
            switchLinks.push(new SwitchLink(a, ignoredTags));
            a.addEventListener('click', function () { ignoredTags.delete(a.innerHTML); }, true);
        });

        $A($('taglist').getElementsByTagName('a')).each(function (a) {
            a.addEventListener('click', function () { ignoredTags.clear(); }, true);
        });
    }

})();
