/*
 * Julian.js
 *
 * Copyright 2010 by Anthony Howe. All rights reserved.
 *
 * http://en.wikipedia.org/wiki/Julian_day
 *
 * http://www.tondering.dk/claus/calendar.html
 */

Julian.short_day_name = [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ];
Julian.long_day_name = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ];

Julian.prototype.now = null;

Julian.prototype.getJulianDayNumber = function()
{
	var a = Math.floor((14 - this.now.getUTCMonth()-1) / 12);
	var y = this.now.getUTCFullYear() + 4800 - a;
	var m = this.now.getUTCMonth()+1 + 12 * a - 3;

	return this.now.getUTCDate() + Math.floor((153*m + 2)/5) + y*365 + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400) - 32045;
}

Julian.prototype.getJulianDate = function()
{
	return this.getJulianDayNumber() + (this.now.getUTCHours()-12)/24 + this.now.getUTCMinutes()/1440 + this.now.getUTCSeconds()/86400;

}

Julian.prototype.getChronologicalJulianDay = function()
{
	return this.getJulianDayNumber() + Math.floor(this.now.getHours()/24) + Math.floor(this.now.getMinutes()/1440) + Math.floor(this.now.getSeconds()/86400);
}

Julian.prototype.getReducedJulianDay = function()
{
	return this.getJulianDate() - 2400000;
}

Julian.prototype.getModifiedJulianDay = function()
{
	return this.getJulianDate() - 2400000.5;
}

Julian.prototype.getTruncatedJulianDay = function()
{
	return (this.getJulianDate() - 0.5) % 10000;
}

Julian.prototype.getLilianDayNumber = function()
{
	return Math.floor(this.getJulianDate() - 2299160.5);
}

Julian.prototype.getRataDie = function()
{
	return Math.floor(this.getJulianDate() - 1721424.5);
}

Julian.prototype.getShortDay = function()
{
	return Julian.short_day_name[this.getJulianDayNumber() % 7];
}

Julian.prototype.getLongDay = function()
{
	return Julian.long_day_name[this.getJulianDayNumber() % 7];
}

Julian.getGregorianDate = function(jd)
{
	var a = jd + 32044;
	var b = Math.floor((4 * a + 3) / 146097);
	var c = a - Math.floor((b * 146097) / 4);

	var d = Math.floor((4 * c + 3) / 1461);
	var e = c - Math.floor((1461 * d) / 4);
	var m = Math.floor((5 * e + 2) / 153);

	var day = e - Math.floor((153 * m + 2) / 5) + 1;
	var month = m + 3 - Math.floor(12 * m / 10);
	var year = b * 100 + d - 4800 + Math.floor(m / 10);

	return new Date(year, month-1, day, 0, 0, 0, 0);
}

function Julian()
{
	switch (arguments.length) {
	default:
		this.now = new Date();
		break;
	case 1:
		// new Julian(milliseconds)
		// new Julian(date_string)
		this.now = new Data(arguments[0]);
		break;
	case 3:
		// new Julian(year, month, day)
		this.now = new Date(arguments[0], arguments[1], arguments[2], 0,0,0,0);
		break;
	case 7:
		// new Julian(year, month, day, hour, minute, seconds, milliseconds)
		this.now = new Date(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
		break;
	}
}
