/* 	****************************************************
	**** 	International Fixed Calendar Scripting	****
	****************************************************
	**** 	Created By: Txec Ereufighleu            ****
	****	Email: Txec@TalossanProgress.Org        ****
	****	via the Union for Talossan Progress     ****
	****	Date: [IFC] May 2, 2006                 ****
	****	Date: [Gr] April 24, 2006               ****
	****	Copy Right: All Rights Reserved         ****
	****	Direct all correspondence about this    ****
	****        script to the above email address   ****
	**************************************************** */
	
	function clsIFCDate (Input, inMonth, inDay) 
	{ 

/*      ******************************
        *    Arguments/Parameters    *
        ******************************      
		'Input' only : can be empty or a Date Object. 
			If it is empty or not a date object the IFC Date will be for today's date.	
			
		'Input', 'inMonth', 'inDay' : can be a number
			Input will be the IFC Year; inMonth will be the IFC Month (1 - 13); inDay will be the IFC Day (1 - 29)
*/
	
/*      **********************************
        *    Public Functions Summary    *
        **********************************
		 
		function getDate ()
			see toString()
			
		function getDayOfMonth()
			Returns a NUMBER from 1 - 28 (or 29 for Leapday and Year Day) 
				for the IFC Calendar
			
		function getDayOfWeek ()
			Returns a STRING of the following values:
				 Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, or Year Day or Leap Day for the appropriate days
				 of the IFC Calendar
				 
		function getDayOfYear ()
			Returns a NUMBER from 1 - 365 or to 366 in of Leap Year that is the day of the year that the date falls on
			This is indepedant of Calendar Type

		function getGregDate()
			Returns a Date Object Equal to the IFC Date
			
		function getMonth ()
			Returns a STRING of the follwing values:
				January, February, March, April, May, June, Sol, July, August, September, October, November, December
				for the Month in the IFC Calendar

		function getMonthOfYear ()
			Returns a NUMBER from 1 - 13 that is the month of the year that the date falls in for the IFC Calendar 
			
		function getQuarter ()
			Returns a NUMBER from 1 - 4 that is the quarter of the year that the day falls in.
			
		function toString ()
			Returns an IFC Date STRING formatted as follows: DayOfWeek, Month Day Year
				Example: Friday, April 16, 1973
				Example or Leap Day: Leap Day, June 29, 2000

		function getWeekOfYear ()
			Returns a NUMBER from 1 - 52 that is the week of the year that the date falls in
				This is indepedant of Calendar Type

		function getYear ()
			Returns a NUMBER that is the Year

	*/

	/* ************ Private Functions **********************
        * Functions that are for internal processing only   *
        *****************************************************	*/
		
		function TypeOf(CheckObject)		
		{// Returns the type of the CheckObject as a string
			switch (typeof(CheckObject))
			{
				case "undefined" : return "Undefined";
				case "number" 	 : return "Number";
				case "string"  	 : return "String";
				case "object" : 
						switch (CheckObject.constructor)
						{
							case Array 	: return "Array";
							case Date 	: return "Date";
							default		: return "Other Object";
						} // end switch switch (CheckObject.constructor)
				default : return ("Other Primitive");
			} 	// end switch (typeof(CheckObject)
		}	// end TypeOf					

		function DayOfYear (dtConv)
		{ // Get the number of days since the begining of the year (January 1)
			 return Math.round ( ( dtConv.getTime() - new Date (dtConv.getFullYear() ,0 ,1).getTime() )/86400000) +1;
		} // end convDateToDays
			
		function MonthOfYear (weeks)
		{ // Get the IFC Month for the Date
			return Math.ceil(weeks/4);
		} // end MonthOfYear
	
		function WeekOfYear (days)
		{ // Get the week of the year for the date
			if ( (LeapDay) || (YearDay) ) return 0
			else return Math.ceil(days/7);
		} // end Week Of Year
	
		/* 	Functions for Null Day detection 	*/
		
		function isLeapDay()
		{ // if the day is the day designated as Leap Day return true
			if ( isLeapYear() ) 
				if ( grDate.getTime() == dtLeapDay.getTime() ) return true;
			return false;
		} // end isLeapDay

		function isLeapYear()
		{// If the year is evenly divisible by 4 it is  Leap Year
			if (Year % 4 == 0) return true;
			return false;
		}// end isLeapYear

		function isYearDay()
		{// If the day is the last day if the year it is Year Day
			if (grDate.getTime() == dtYearDay.getTime() ) return true;
			return false;
		}// end isYearDay
	
		function IFCToGreg (IFCYear, IFCMonth, IFCDay)
		{	// IFCYear 		: is a number value that is valid for the a Date object's year (generally > 1970)
			// IFCMonth 	: is an number value from 1 - 13; Month of Year
			// IFCDay		: is an number value from 1 - 29; Day of Month
	
			var dtGreg = null;
			var LeapYear = false;
			if (IFCYear % 4 == 0) LeapYear = true;
	
			var MSYear = new Date (IFCYear, 0, 1).getTime();
			var MSDays	= 0;
				
			var MSDays	= ( ( (IFCMonth* 28) + IFCDay) * 86400000);
			var dtGreg = new Date( MSYear + MSDays );

			if ( (LeapYear) && ( IFCMonth > 5) ) 
				dtGreg = new Date(dtGreg.getFullYear(), dtGreg.getMonth(), dtGreg.getDate()+1) ;
			return dtGreg;
		} // end function ProcesssConversion



	/* 	************ Public Functions *********
		* Public Functions for external use *
		***************************************	*/

		clsIFCDate.prototype.getDayOfMonth = function ()
		{	
			var ctrDay = Days;

			if ( (YearDay) || (LeapDay) ) return 29;

			return (ctrDay - ( (Months - 1) * 28 )  );
		} // end getDayOfMonth

		clsIFCDate.prototype.getDayOfWeek = function ()
		{
			ctrDay = Days;
			if (YearDay) return "Year Day";
			if (LeapDay) return "Leap Day";
			
			switch ( ctrDay % 7 )
			{
				case 1 % 7	: return "Sunday";
				case 2 % 7	: return "Monday";
				case 3 % 7	: return "Tuesday";
				case 4 % 7	: return "Wednesday";
				case 5 % 7	: return "Thursday";
				case 6 % 7	: return "Friday";
				case 0		: return "Saturday";
			} // end switch ( ctrDay % 7 )
		} // end getDayOfWeek

		clsIFCDate.prototype.getDayOfYear = function ()
		{	
			return Days;
		} // end getDayOfYear

		clsIFCDate.prototype.getMonth = function ()
		{
			var ctrMonth = Months;
			if (YearDay) return "December" 
			if (LeapDay) return "June" 
			
			switch (ctrMonth)
			{
				case 1:  return "January";
				case 2:  return "February";
				case 3:  return  "March";
				case 4:  return  "April";
				case 5:	 return  "May";
				case 6:  return  "June";
				case 7:  return  "Sol";
				case 8:	 return  "July";
				case 9:	 return  "August";
				case 10: return  "September";
				case 11: return  "October";
				case 12: return  "November";
				case 13: return  "December";
				default: return null;
			} // end switch (weeks)
		} // end getMonthOfYear

		clsIFCDate.prototype.getMonthOfYear = function ()
		{
			if (YearDay) return 12;
			if (LeapDay) return 6;
			
			return Months;
		} // end gerMonthOfYear		

		clsIFCDate.prototype.getWeekOfYear = function ()
		{
			if ( (YearDay) || (LeapDay) ) return 0;
			return Weeks;
		} // end getWeekOfYear


		clsIFCDate.prototype.getYear = function ()
		{
			return Year;
		} // end GetIFCYear

		clsIFCDate.prototype.getQuarter = function ()
		{
			return Math.ceil(Weeks/13);
		} // end GetIFCYear

		clsIFCDate.prototype.getDate = function ()
		{
			return this.getDayOfWeek() + ", " + this.getMonth() + " " + this.getDayOfMonth() + ", " + this.getYear();
		} // end getIFCDate

		clsIFCDate.prototype.toString = function ()
		{
			return this.getDayOfWeek() + ", " + this.getMonth() + " " + this.getDayOfMonth() + ", " + this.getYear();
		} // end getIFCDate		

		clsIFCDate.prototype.getGregDate = function ()
		{
			return grDate;
		} // end getIFCDate



	/* 	********** Core Class Code **********
		*	Variable Intitialization and 	*
		*	Primary Class Processing Code	*
		*************************************	*/
	//	var DaysInYear = 365;

		var Days = 0;
		var Weeks = 0;
		var Months = 0;
		var Year = 0;

		var YearDay = false;
		var LeapDay = false;
		var dtLeapDay;
		var dtYearDay;

		var grDate;

		// Process Arguments is Input, inMonth and inDay of Type 'Number'
		if ( ( TypeOf(Input) == "Number" ) && ( TypeOf(inMonth) == "Number" ) && ( TypeOf(inDay) == "Number" ) )
		{
			Input = IFCToGreg(Input, inMonth, inDay);
		}
		
		// Process Argument is Input is of Type 'Date'
		if ( TypeOf (Input) == "Date") 
		{
			grDate = Input;
			// Reset date object so that time is zeroed out else results could be off by one day.
			grDate = new Date( grDate.getFullYear(), grDate.getMonth(), grDate.getDate() );
		
			Year	= grDate.getFullYear();
			dtLeapDay = new Date(Year,5,17) 
			dtYearDay = new Date(Year,11,31) 
			LeapYear = isLeapYear();
			// The Grogorian to IFC Calendar Day for Leap Day is [GR] June 17/ [IFC] June 29
			LeapDay = isLeapDay();
						
			Days 	= DayOfYear( grDate );
			YearDay = isYearDay();

			if ( (LeapYear) && (grDate.getTime() > dtLeapDay.getTime()) )
			{
				Days -= 1;
			} 

			Weeks = WeekOfYear(Days);
			Months 	= MonthOfYear(Weeks);
		} 	
		else grDate = new Date();

	} // end clsIFCDate
	
