/**
    @author Yoan Blanc <yoan at dosimple dot ch>
*/

// thanks to http://www.merlyn.demon.co.uk/js-date3.htm#ISO
function TryISO(value) {
    var RE, OK, Dobj, OH = OM = 0;

    RE = /^(\d{4})?-?(\d\d)?-?(\d\d)?T?(\d\d)?:?(\d\d)?:?(\d\d)?([Z+-])?(\d\d)?:?(\d\d)?$/;
    OK = RE.test(value);
    if (RegExp.$7 != "Z") {
        OH = RegExp.$7 + RegExp.$8;
        if (RegExp.$9)
            OM = RegExp.$7 + RegExp.$9
    }
    Dobj = RegExp.$7 ? new Date(Date.UTC(RegExp.$1 || 77, RegExp.$2 - 1, RegExp.$3, RegExp.$4 - OH, RegExp.$5 - OM, RegExp.$6)) : new Date(RegExp.$1 || 77, RegExp.$2 - 1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6);

    return (OK ? Dobj : null)
}

// my hook
function $(o) {
    return document.getElementById(o)
}

Comments = {
    comment: "/blog/2007/03/03/comments.php",
    form: "/blog/2007/03/03/form.html",
    commentfile: "comments.json",
    location: undefined,
    today: undefined,
    // informations stored in the cookie
    informations: ['name', 'email', 'link'],
    
    test: function() {
        
        if(!FORK) {
            alert('FORK is not defined')
        } else if(!FORK.Ajax) {
            alert('FORK.Ajax is not defined')
        } else if(!FORK.Ajax.isSupported()) {
            alert('Your browser is not capable of Ajax')
        }  else if(!FORK.Event) {
            alert('FORK.Event is not defined')
        }  else if(!FORK.Cookie) {
            alert('FORK.Cookie is not defined')
        } else {
            return true
        }
        return false
    },

    main: function() {
        
        var bookmarks = FORK.Dom.getElementsByClass('bookmark', {tag: 'a'});
        
        // one page only, not the montly view
        if(bookmarks && bookmarks.length == 1) {
            // extract: /blog/YYYY/MM/DD/
            var location = bookmarks[0].href;
            var today = location.substr(-16);
            
            Comments.location = location;
            Comments.today = today;
            Comments.getComments(today);
        }
    },

    getComments: function(today) {
        //today = today || this.today;
        var json = this.today + '/' + this.commentfile;
        
        new FORK.Ajax("GET", json, 
            {
                onSuccess: Comments.showComments
            });
    },

    getForm: function() {
        
        new FORK.Ajax("GET", Comments.form, 
            {
                onComplete: Comments.showForm
            });
    },
    
    // return the type of comment
    commentType: function(comment) {
        if (comment.source && comment.source.length)
            return "Trackback";
        else if(comment.dc.creator && comment.dc.creator.length)
            return "Comment";
        else if(comment.author && comment.author.length)
            return "Post-It";
        else
            return "Pingback"
    },

    // formatNumber(93, 4) => 0093
    formatNumber: function(value, size) {
        var prefix='';
        for (var i = 1; i<size; i++)
            if((Math.log(value)/Math.log(10)) < size-1)
                prefix += "0";
        
        return prefix+value
    },

    formatDate: function(value) {
        var date = TryISO(value);
        var fn = Comments.formatNumber;
        return '<abbr title="'+value+'" class="published">'+date.getFullYear()+'-'+fn(date.getMonth()+1, 2)+'-'+fn(date.getDate(), 2)+' @ '+fn(date.getHours(),2)+':'+fn(date.getMinutes(),2)+'</abbr>'
    },
    
    formatText: function(text) {
        text = "<p>"+text+"</p>";
        
        text = text.replace(/http:\/\/[^\s)]+/gi, function(match) { return '<a href="'+match+'" rel="no-follow">'+match+'</a>'});
        text = text.replace(/\n\n/g, '</p><p>');
        
        return text
    },

    formatComment: function(comment) {
        var type = Comments.commentType(comment);
        
        var html = '';
        switch(type){
            case "Comment":
                if(comment.title.length)
                    html += "<h5>" + comment.title + "</h5>";
                if(comment.description.length)
                    html += Comments.formatText(comment.description);
                
                html += '<p class="infos">'+type;
                html += ' by <span class="vcard">';
                
                if (comment.link && comment.link.length)
                    html += '<a href="'+comment.link+'" rel="no-follow" class="url fn">'+comment.dc.creator+'</a>';
                else
                    html += comment.dc.creator;
                
                if(comment.author)
                    html += ' <img src="http://www.gravatar.com/avatar.php?gravatar_id='+comment.author+'&amp;size=20" alt="gravatar" width="20" height="20" class="photo" />';
                
                html += '</span>';
                
                break;
            
            case "Post-It":
                // not supported
                return;
            
            case "Trackback":
                if(comment.title.length)
                    html += "<h5>" + comment.title + "</h5>";
                if(comment.description.length)
                    html += "<p>"+comment.description+"</p>";
                
                html += '<p class="infos">'+type+' from <a href="'+comment.link+'" rel="no-follow">';
                if(comment.source.length > 23)
                    html += comment.source.substr(0, 20)+"...";
                else
                    html += comment.source;
                html += "</a>";
                
                break;
            
            case "Pingback":
                html += '<p class="infos">'+type+' from <a href="'+comment.link+'" rel="no-follow">';
                if(comment.link.length > 23)
                    html += comment.link.substr(0, 20)+"...";
                else
                    html += comment.link;
                html += "</a>";
                
                break;
            default:
                break;
        } 
        
        // published date
        if(comment.dc.created)
            //html += ' — <a href="#c' + comment.uid + '">' + Comments.formatDate(comment.dc.created) + '</a>';
            html += ' — ' + Comments.formatDate(comment.dc.created);
        html += "</p>";
        
        return html
    },

    showComments: function(o) {
        
        // clean
        var co = FORK.Dom.getElementsByClass('comments', {tag: 'div'});
        if (co.length > 0)
            co[0].parentNode.removeChild(co[0]);
        
        var preview = $('comment-preview');
            if (preview)
                preview.parentNode.removeChild(preview);
        
        //var comments = FORK.Json.load("("+o.responseText+")");
        // the above seems not working
        var comments = eval(o.responseText);
        
        // new html
        var html = '<h4>Comments</h4>';
        
        if(comments.length > 0) {
            html += '<ol>';
            
            for(var i = 0; i < comments.length; i++) {
                html += '<li class="';
                html += (i % 2) ? 'odd' : 'even';
                html += '" id="c' + comments[i].uid + '">';
                
                html += Comments.formatComment(comments[i], i)+'</li>'
            }
            html += '</ol>'
        } else {
            html += "<p><em>No comments so far!</em></p>";
        }
        
        // fixme: block comments older than a month
        html += '<p><a href="#" id="add-comment">Add your comment</a></p>';
        
        var entry = $('entry');
        var div = document.createElement('DIV');
        div.className = "comments";
        div.innerHTML = html;
        
        entry.appendChild(div)
        
        FORK.Event.addListener($('add-comment'), "click", Comments.addComment);
    },

    addComment: function(e) {
        // prevent the link to be followed
        FORK.Event.preventDefault(e);
        
        Comments.getForm();
    },

    showForm: function(o) {
        var link = $('add-comment')
        link.parentNode.style.display = "none";
        var entry = $('entry');
        var div = document.createElement('DIV');
        div.className = "form";
        div.innerHTML = o.responseText;
        entry.appendChild(div);
        
        var form = entry.getElementsByTagName('form')[0];
        
        // set the user values
        if(FORK.Cookie.isSupported()) {
            var c = new FORK.Cookie('user-informations');
            for(var i=Comments.informations.length-1; i>=0; --i)
                if(c[Comments.informations[i]])
                    form[Comments.informations[i]].value = c[Comments.informations[i]];
        }
        
        FORK.Event.addListener($('preview-comment'), "click", Comments.previewComment);
        FORK.Event.addListener(form, "submit", Comments.submitComment)
    },
    
    previewComment: function(e) {
        // prevent the form to be sended
        FORK.Event.preventDefault(e);
        
        // ... ? preview/submit
        new FORK.Ajax("POST", Comments.comment + '?preview',
            {
                form: $('entry').getElementsByTagName('form')[0],
                headers: {'Referer': Comments.location},
                onComplete: Comments.submitted
            })
    },
    
    submitComment: function(e) {
        // prevent the form to be sended
        FORK.Event.preventDefault(e);
        
        // ... ? preview/submit
        new FORK.Ajax("POST", Comments.comment + '?submit',
            {
                form: this,
                headers: {'Referer': Comments.location},
                onComplete: Comments.submitted
            });
        
        // save the user values
        if(FORK.Cookie.isSupported()) {
            var c = new FORK.Cookie('user-informations');
            for(var i=Comments.informations.length-1; i>=0; --i)
                if(this[Comments.informations[i]])
                    c[Comments.informations[i]] = this[Comments.informations[i]].value;
            
            c.store(365, "/") // a year
        }
    },
    
    submitted: function(o) {
        var comments = eval(o.responseText);
        
        if(comments && comments.length == 1 && comments[0]['commented']) {
            // clean
            var co = FORK.Dom.getElementsByClass('comments-info', {tag: 'p'});
            if (co.length > 0)
                co[0].parentNode.removeChild(co[0]);
            
            var entry = $('entry');
            var p = document.createElement('P');
            p.className = "comments-info";
            p.innerHTML = "Thanks for your comment.";
            entry.appendChild(p)
            
            // cleaning the room
            var link = $('add-comment')
            link.parentNode.style.display = "block";
            
            var form = FORK.Dom.getElementsByClass('form', {tag: 'div'});
            if(form && form.length == 1)
                form[0].parentNode.removeChild(form[0]);
            
            Comments.getComments()
        } else {
            var html = comments[0].description;
            
            // clean
            var preview = $('comment-preview');
            if (preview)
                preview.parentNode.removeChild(preview);
            
            var entry = $('entry');
            var div = document.createElement('DIV');
            div.className = "comments";
            div.id = "comment-preview";
            div.innerHTML = "<h4>Preview</h4>" + Comments.formatText(html);
            entry.appendChild(div);
        }
    }
};

if (Comments.test())
    FORK.Event.addListener(window, "load", Comments.main);
