/**
	@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')
		// IE fails
		//} else if(!FORK.Event.isSupported()) {
		//	alert('Your browser is not capable of using the FORK Event library')
		}  else if(!FORK.Cookie) {
			alert('FORK.Cookie is not defined')
		// should work without it
		//} else if(!FORK.Cookie.isSupported()) {
		//	alert('Your browser is not capable of using the FORK Cookie library. Please enable them.')
		} 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.getDay(), 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 += "<h4>" + comment.title + "</h4>";
				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 += "<h4>" + comment.title + "</h4>";
				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 = '<h3>Comments</h3>';
		
		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 = "<h3>Preview</h3>" + Comments.formatText(html);
			entry.appendChild(div);
		}
	}
};

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