(function(){
    if(typeof(window.ClipComments) == 'undefined'){
        ClipComments = window.ClipComments = function(){
            ClipComments.prototype.initialize.apply(this,arguments);
        }
    }
    ClipComments.prototype = {
        initialize: function(){
            var object = arguments[0] || {};
            this.unique_id = new Date().getTime();
            this.target_id = "target_id_" + this.unique_id;
            this.url = object["url"] || location.href;
            this.css = object["css"];
            this.type = object["type"];
            this.setTarget();
        },
        setTarget: function(){
            document.write("<div id='"+this.target_id+"'></div>");
        },
        getTargetElement: function(){
            return document.getElementById(this.target_id);
        },
        load: function(){
            var _this = this;
            var cb = "cb" + this.unique_id;
            eval(cb + "=function(){ _this.handler.apply(_this,arguments) }");
            var url = "http://clip.livedoor.com/api/json/comments?link="+this.url+"&callback="+cb;
            var script  = document.createElement('script');
            script.type = 'text/javascript';
            script.charset = 'UTF-8';
            script.src  = url;
            script.id   = this.unique_id;
            document.getElementsByTagName('head')[0].appendChild(script);
        },
        handler: function(data){
            var style = this.styleSet(this.type);
            style.setData(data);
            style.addCSS();
            var header = style.createHeader();
            var comments = style.createComments();
            comments.insertBefore(header,comments.firstChild);
            this.getTargetElement().appendChild(comments);
        },
        styleSet: function(){
            switch (this.type){
                case "simple":
                    return new ClipComments.SimpleStyle();
                case "balloon":
                    return new ClipComments.BalloonStyle();
            }
        }
    }
    ClipComments.Style = function(){
        this.base_url = "http://clip.livedoor.com";
    }
    ClipComments.Style.prototype = {
        setData: function(data){
            this.data = data;
            this.comments = this.data.Comments || [];
            this.title = this.data.title;
            this.link = this.data.link;
            this.clip_href = this.base_url
                           + "/clip/add?"
                           + this.toQuery({link:this.link,title:this.title,jump:"myclip"});
        },
        addCSS: function(stylesheet){
            var link = this.setAttr(document.createElement('link'),{
                href: stylesheet || this.css,
                rel: 'stylesheet',
                type: 'text/css'
            });
            document.getElementsByTagName('head')[0].appendChild(link);
        },
        createHeader: function(){
            var p = document.createElement('p');
            p.id="LDClipNavi";
            var a = this.setAttr(document.createElement('a'),{ href: this.clip_href });
            var img = this.setAttr(document.createElement('img'),{
                src: this.base_url+"/img/icon/clip_border.gif",
                alt: "クリップしてコメントする",
                title: "クリップしてコメントする",
                width: "16",
                height: "16"
            });
            a.appendChild(img);
            p.appendChild(a);
            var a = this.setAttr(document.createElement('a'),{ href: this.base_url });
            a.appendChild(document.createTextNode("livedoor クリップ"));
            p.appendChild(a);
            p.appendChild(document.createTextNode("を利用してコメントできます。"));
            var a = this.setAttr(document.createElement('a'),{ href: this.clip_href });
            a.appendChild(document.createTextNode("クリップしてコメントする"));
            p.appendChild(a);
            return p;
        },
        createComments: function(){
            return this.create();
        },
        setAttr: function(element,attribute){
            for (var name in attribute) {
                element.setAttribute(name, attribute[name]);
            }
            return element;
        },
        addClass: function(element,name){
            element.className = name;
            return element;
        },
        toQuery : function (q) {
            var res = [];
            for (var i in q)
                res.push(i + "=" + encodeURIComponent(q[i]));
            return res.join("&");
        }
    }
    ClipComments.SimpleStyle = function(){
        this.css = "http://clip.livedoor.com/css/json_simple.css";
        this.create = function(){
            var div = document.createElement('div');
            div.id = "LDClipCommentBox";
            var ul = document.createElement('ul');
            ul.id = "LDClipCommentList";
            for (var i=0;i<this.comments.length;i++){
                var li = document.createElement('li');
                var a = this.setAttr(document.createElement('a'),{ href: this.base_url + "/clips/" + this.comments[i].livedoor_id });
                var img = this.setAttr(document.createElement('img'), {
                    src: "http://image.profile.livedoor.jp/icon/"+this.comments[i].livedoor_id+"_16.gif",
                    alt: this.comments[i].livedoor_id,
                    title: this.comments[i].livedoor_id,
                    width: "16",
                    height:"16"
                });
                a.appendChild(img);
                li.appendChild(a);
                var span = this.addClass(document.createElement('span'),"LDID");
                var a = this.setAttr(document.createElement('a'),{ href: this.base_url + "/clips/" + this.comments[i].livedoor_id });
                a.appendChild(document.createTextNode(this.comments[i].livedoor_id))
                span.appendChild(a);
                li.appendChild(span);
                var span = document.createElement('span');
                span.appendChild(document.createTextNode(this.comments[i].notes));
                li.appendChild(span);
                ul.appendChild(li);
            }
            div.appendChild(ul);
            return div;
        }
    }
    ClipComments.BalloonStyle = function(){
        this.css = "http://clip.livedoor.com/css/json_balloon.css";
        this.create = function(){
            var div = document.createElement('div');
            div.id = "LDClipBalloonCommentBox";
            var ul = document.createElement('ul');
            ul.id = "LDClipBalloonCommentList";
            for (var i=0;i<this.comments.length;i++){
                var li = this.addClass(document.createElement('li'),"LDClipBalloonComment");
                var dl = document.createElement('dl');
                var dt = document.createElement('dt');
                var a = this.setAttr(document.createElement('a'),{ href: this.base_url + "/clips/" + this.comments[i].livedoor_id });
                var img = this.setAttr(document.createElement('img'), {
                    src:"http://image.profile.livedoor.jp/icon/"+this.comments[i].livedoor_id+"_16.gif",
                    alt:this.comments[i].livedoor_id,
                    title:this.comments[i].livedoor_id,
                    width:"16", height:"16" });
                a.appendChild(img);
                dt.appendChild(a);
                var span = this.addClass(document.createElement('span'),"LDID");
                var a = this.setAttr(document.createElement('a'),{ href: this.base_url + "/clips/" + this.comments[i].livedoor_id });
                a.appendChild(document.createTextNode(this.comments[i].livedoor_id));
                span.appendChild(a);
                dt.appendChild(span);
                dl.appendChild(dt);
                var dd = document.createElement('dd');
                var p = document.createElement('p');
                p.appendChild(document.createTextNode(this.comments[i].notes));
                dd.appendChild(p);
                dl.appendChild(dd);
                li.appendChild(dl);
                ul.appendChild(li);
            }
            div.appendChild(ul);
            return div;
        }
    }
    ClipComments.SimpleStyle.prototype = new ClipComments.Style;
    ClipComments.BalloonStyle.prototype = new ClipComments.Style;
})();
