var MultiBookmarkCommentReader = {
    prefix: 'hatenaBookmarkCommentReader',
    blockId: 'block',
    infoId: 'info',
    fieldPrefix: 'field',
    messageNoBookmarks: 'This page has not been bookmarked yet.',
    messageNoComments: 'This page has not had bookmark comments yet.',
    messageNoHatenaInfo: 'This page has not been bookmarked on Hatena Bookmark yet.',
    create: function(){
        var tag = arguments[0];
        var attrs = arguments[1] || {};

        var element = document.createElement(tag);
        var element_style = element.style;

        for( var key in attrs ){
            if ( key == 'style' ) {
                var attrs_style = attrs.style;
                for ( styleKey in attrs_style ){
                    element_style[styleKey] = attrs_style[styleKey];
                }
            }
            else {
                element[key] = attrs[key];
            }
        }

        if( arguments.length > 2 ){
            for( var i = 2; i < arguments.length; i++ ){
                if( typeof arguments[i] == 'object' ) {
                    element.appendChild( arguments[i] );
                }
                else if( typeof arguments[i] == 'string' ) {
                    element.appendChild( document.createTextNode( arguments[i] ) );
                }
            }
        }

        return element;
    },
    textNode: function(){
        var result = '';
        for ( var i = 0; i < arguments.length; i++ ) result += arguments[i];
        return document.createTextNode( result );
    },
    retrieve: function( id ){
        return document.getElementById(id);
    },
    search: function( tagname ){
        return document.getElementsByTagName(tagname);
    },
    joinPrefix: function(){
        var result = '';
        for ( var i = 0; i < arguments.length; i++ ){
            if ( result != '' ) result += '-';
            result += arguments[i];
        }
        return result;
        // return arguments.join('-');
    },
    addPrefix: function( id ){
        return this.joinPrefix( this.prefix, id );
    },
    main: function(){
        var HBCRElement = this.retrieve( this.joinPrefix( this.prefix, this.blockId ) );
        if( HBCRElement )
            this.clean(HBCRElement);
        else
            this.prepare();
    },
    request: function( id, uri ){
        var script = document.createElement('script');
        script.src = uri;
        script.type = 'text/javascript';
        script.charset = 'utf-8';
        script.id = this.prefix + '-' + id;

        this.search('body')[0].appendChild(script);
    },
    clean: function(){
        var element = arguments[0] || this.retrieve( this.joinPrefix( this.prefix, this.blockId ) );
        if ( element ) element.parentNode.removeChild( element );
    },
    cleanRequest: function( id ){
        var script = this.retrieve(this.prefix + '-' + id );
        if ( script ) this.clean(script);
    },
    prepare: function(){
        var block = this.prepareBlock();
        this.setInfoTo(block);
        this.setHatenaTo(block);

        // and something...
    },
    prepareBlock: function(){
        var block = this.create(
            'div',
            {
                id: this.joinPrefix( this.prefix, this.blockId ),
                style: {
                    color: 'black',
                    backgroundColor: 'white',
                    fontSize: 'smaller',
                    textAlign: 'left',
                    padding: '0.5em 1em',
                    margin: '0em 1em 1em 0em',
                    zIndex: '10000',
                    position: 'absolute',
                    top: '1em',
                    left: '1em',
                    border: '1px solid #666666',
                    opacity: '0.9',
                    filter: 'Alpha(opacity=90)' // for Win IE
                }
            }
        );
        this.search('body')[0].appendChild(block);
        return block;
    },
    prepareField: function( id ){
        return this.create(
            'div',
            {
                id: this.joinPrefix( this.prefix, this.fieldPrefix, id ),
                style: {
                    padding: '0.5em 1em',
                    clear: 'right',
                    borderWidth: '1px 0px 0px 0px',
                    borderStyle: 'solid',
                    borderColor: '#999999'
                }
            }
        );
    },
    setInfoTo: function( block ){
        block.appendChild(this.create('div',{id:this.joinPrefix(this.prefix,this.infoId)},'loading...'));
        return block;
    },
    setHatenaTo: function( block ){
        block.appendChild(this.prepareHatenaField('hatena'));
        var uri = 'http://b.hatena.ne.jp/entry/json/'
            + '?url=' + encodeURIComponent(location.href)
            + '&callback=MultiBookmarkCommentReader.hatenaCallback';
        this.request('hatena',uri);
    },

    // for Hatena Bookmark
    prepareHatenaField: function( id ){
        var field = this.prepareField( id );
        field.appendChild(
            this.create(
                'div',
                {
                    id: this.joinPrefix(this.prefix,this.fieldPrefix,id,'title'),
                    style:{margin:'0em',padding:'0em'}
                },
                this.create('span',{style:{fontWeight:'bold'}},'Hatena Bookmark')
            ));
        return field;
    },
    hatenaCallback: function( json ){
        this.cleanRequest('hatena');

        if ( json != null ) {
            var hatena = this.formatHatena( json );
            this.fillinInfo( hatena );
            this.fillinField( 'hatena', hatena );
        }
        else {
            this.fillinInfo();
            this.fillinField(
                'hatena',
                this.messageNoBookmarks
            );
        }
    },
    formatHatena: function( json ){
        return json;
    },


    fillinInfo: function(){
        var json = arguments[0] || '';
        var info = this.retrieve( this.joinPrefix(this.prefix,this.infoId) );
        info.innerHTML = '';

        if ( json ) {
            info.appendChild(
                this.create(
                    'img',
                    {
                        src: json.screenshot,
                        title: json.title,
                        alt: json.title,
                        width: 120,
                        height: 90,
                        style: {
                            border: '1px solid #999999',
                            margin: '0em 0em 1em 1em',
                            // styleFloat: 'right', // for Win IE
                            cssFloat: 'right'
                        },
                        onclick: function(){MultiBookmarkCommentReader.clean();}
                    }
                )
            );
            info.appendChild(
                this.create('div',{},this.create('span',{style:{fontSize:'larger',fontWeight:'bold'}},json.title))
            );
        }
        else {
            info.innerHTML = this.messageNoHatenaInfo;
        }
    },
    fillinField: function( id, json ){
        var field = this.retrieve( this.joinPrefix( this.prefix, this.fieldPrefix, id ) );

        var message = this.retrieve(this.joinPrefix( this.prefix, this.fieldPrefix, id, 'message'));
        if ( message ) message.parentNode.removeChild(message);

        if ( typeof json != 'object' ) {
            field.appendChild(this.textNode(json));
        }
        else if ( json.bookmarks.length == 0 ) {
            field.appendChild(this.textNode(this.messageNoBookmarks));
        }
        else {
            var ul = null;
            var unorderedList = function(field){
                var element = MultiBookmarkCommentReader.create(
                    'ul',
                    {
                        style: {
                            margin: '0em',
                            padding: '0em 1em',
                            crear: 'right',
                            listStyleType: 'none'
                        }
                    }
                );
                field.appendChild(element);
                unorderedList = function(){ return element; };
                return element;
            }

            // change title
            var title = this.retrieve(this.joinPrefix( this.prefix, this.fieldPrefix, id, 'title'));
            var users = this.create(
                'span',
                { id: this.joinPrefix( this.prefix, this.fieldPrefix, id, 'users') },
                json.bookmarks.length + ( json.bookmarks.length > 1 ? ' users' : ' user' )
            );
            title.appendChild(
                this.create(
                    'span',
                    {style:{padding: '0em 1em', fontSize: 'smaller'}},
                    users,
                    ' - ',
                    this.create(
                        'a',
                        { href: json.entry_url },
                        'entry page'
                    )
                )
            );

            // set comments
            var count = 0;
            for ( var i = 0; i < json.bookmarks.length; i++ ) {
                var bookmark = json.bookmarks[i];

                if ( bookmark.comment != '' ) {
                    count++;

                    ul = unorderedList(field);
                    bookmark.timestamp.match(/^(\d{4})\/(\d{2})\/(\d{2})/);
                    var ymd = RegExp.$1 + RegExp.$2 + RegExp.$3;

                    bookmark.user.match(/^(.{2})/);
                    var usericon = 'http://www.hatena.ne.jp/users/'
                        + RegExp.$1 + '/' + bookmark.user + '/profile_s.gif';

                    var li = this.create(
                        'li', {},
                        this.create(
                            'img',
                            {
                                src: usericon,
                                alt: '',
                                title: '',
                                style:{ verticalAlign: 'middle' }
                            }
                        ),
                        ' ',
                        this.create(
                            'a',
                            {
                                href: 'http://b.hatena.ne.jp/' + bookmark.user + '/' + ymd,
                                title: bookmark.user + ' - ' + bookmark.timestamp
                            },
                            bookmark.user
                        )
                    );
                    ul.appendChild(li);

                    if ( bookmark.tags.length ) {
                        li.appendChild(this.textNode(' '));
                        for ( var j = 0; j < bookmark.tags.length; j++ ){
                            if ( j > 0 ) li.appendChild(this.textNode(', '));
                            li.appendChild(
                                this.create(
                                    'a',
                                    {
                                        href: 'http://b.hatena.ne.jp/' + bookmark.user + '/' + bookmark.tags[j] + '/',
                                        style: {
                                            fontSize: 'smaller'
                                        }
                                    },
                                    bookmark.tags[j]
                                )
                            );
                        }
                    }

                    if ( bookmark.comment ) {
                        li.appendChild(this.textNode(' ',bookmark.comment));
                    }
                }
            }
            if ( count > 0 ) users.innerHTML = count + ' / ' + users.innerHTML;

            if ( ul == null ) field.appendChild(this.textNodethis.messageNoComments);
        }
    }
};

MultiBookmarkCommentReader.main();
