/*
 * Javascript Humane Dates
 * Copyright (c) 2008 Dean Landolt (deanlandolt.com)
 * Re-write by Zach Leatherman (zachleat.com)
 * Further modifications by Chris Dornfeld (downrightnow.com)
 * 
 * Adopted from the John Resig's pretty.js
 * at http://ejohn.org/blog/javascript-pretty-date
 * and henrah's proposed modification 
 * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
 * and Zach Leatherman's re-write
 * at http://www.zachleat.com/web/2008/03/23/yet-another-pretty-date-javascript/
 * 
 * Licensed under the MIT license.
 */

Date.prototype.humaneDate = function (allowFutureDates, useMixedCase) {
	// date format to return for unwanted future dates
	// only applies in combination with formatDate library
	var fallbackDateFormat = 'D, F j, Y  g:i a';

	if (useMixedCase === undefined) {
		useMixedCase = false;
	}
	if (allowFutureDates === undefined) {
		allowFutureDates = false;
	}

	var timeFormats = [
		// seconds threshold, unit(s) description, seconds per unit (multiples)
		[60, 'A Moment'],
		[90, '1 Minute'], // 60*1.5
		[3600, 'Minutes', 60], // 60*60, 60
		[5400, '1 Hour'], // 60*60*1.5
		[86400, 'Hours', 3600], // 60*60*24, 60*60
		[129600, '1 Day'], // 60*60*24*1.5
		[604800, 'Days', 86400], // 60*60*24*7, 60*60*24
		[907200, '1 Week'], // 60*60*24*7*1.5
		[2628000, 'Weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
		[3942000, '1 Month'], // 60*60*24*(365/12)*1.5
		[31536000, 'Months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
		[47304000, '1 Year'], // 60*60*24*365*1.5
		[3153600000, 'Years', 31536000], // 60*60*24*365*100, 60*60*24*365
		[4730400000, '1 Century'] // 60*60*24*365*100*1.5
	];

	var curDateObj = new Date;
	var secondsAgo = (curDateObj - this) / 1000;

	var suffix = '';
	if (secondsAgo < 0) {
		// future date, or user's system clock doesn't match server clock
		if (allowFutureDates) {
			secondsAgo = Math.abs(secondsAgo);
			suffix = ' From Now';
		} else {
			if (Math.abs(secondsAgo) < 60) {
				// grace period if date under 1 minute in the future
				// (accounts for minor time differences)
				secondsAgo = 0;
				suffix = ' Ago';
			} else {
				// future dates aren't wanted or expected, return absolute date
				if (Date.prototype.formatDate) {
					return this.formatDate(fallbackDateFormat);
				}
				return this.toString();
			}
		}
	} else {
		suffix = ' Ago';
	}

	var humaneDateText = '';
	var i = 0;
	var thisFormat;
	while (thisFormat = timeFormats[i]) {
		if (secondsAgo < thisFormat[0]) {
			if (thisFormat.length == 2) {
				// single unit of time (1 hour, 1 day, etc.)
				humaneDateText = thisFormat[1] + suffix;
				break;
			} else {
				// multiple units of time (2 hours, etc.)
				humaneDateText = Math.round(secondsAgo / thisFormat[2]) + ' ' + thisFormat[1] + suffix;
				break;
			}
		}
		i++;
	}
	// handle multiple centuries
	if (secondsAgo > timeFormats[timeFormats.length-1][0]) {
		humaneDateText = Math.round(secondsAgo / timeFormats[timeFormats.length-1][0]) + ' Centuries' + suffix;
	}

	if (useMixedCase) {
		return humaneDateText;
	}
	return humaneDateText.toLowerCase();
};

if (typeof jQuery != 'undefined') {
	jQuery.fn.humaneDates = function() {
		return this.each(function() {
			// <span class="timestamp timestamp_123456789">date goes here</span>
			var timestampAttr = 'class';
			var timestampPattern = /timestamp_(\d+)( |$)/;
			var unixTimestamp = null;
			var matches = timestampPattern.exec(jQuery(this).attr(timestampAttr));
			if (matches && matches.length > 1) {
				unixTimestamp = parseInt(matches[1]);
			}
        	
			if (unixTimestamp) {
				var msTimestamp = unixTimestamp * 1000;
				var dateObj = new Date(msTimestamp);
//				jQuery(this).append(' ('+dateObj.humaneDate()+')');
				jQuery(this).text(dateObj.humaneDate());
				// also replace timestamp with human-readable absolute date
				if (Date.prototype.formatDate) {
					jQuery(this).attr('title', dateObj.formatDate('D, F j, Y  g:i a'));
				} else {
					jQuery(this).attr('title', dateObj.toString());
				}
				jQuery(this).addClass('timestampRelative');
			}
		});
	};
};
