﻿/********************************************************************************/
/*                                                                              */
/*  solar.js - Solar Date Utility Functions                                     */
/*  Copyright(C) 2002-2003 Mahmood Shafiee Zargar, all rights reserved.         */
/*                                                                              */
/*  sobh@softhome.net                                                           */
/*  http://sobh.netfirms.com                                                    */
/*                                                                              */
/*  Original Pascal Code By Kambiz R. Khojaste                                  */
/*                                                                              */
/*  This file is provided "AS IS" without any warranty of any  kind, either     */
/*  express or implied. The entire  risk as to the quality  and performance     */
/*  of the functions provided in this  unit are with you. The author is NOT     */
/*  liable for  any DAMAGES resulting from the use  and misuse of the unit,     */
/*  especially he is NOT liable for DAMAGES that were caused BY ANY VERSION     */
/*  WHICH HAS NOT BEEN PROGRAMMED BY THE AUTHOR HIMSELF.                        */
/*                                                                              */
/********************************************************************************/

/********************************************************************************/
/*                                                                              */
/*  Usage:                                                                      */
/*                                                                              */
/*  ConvertDateTag(DateStr, Format)                                             */
/*  DateStr: A date string formatted as "m/d/yyyy" or "mm/dd/yyyy".             */
/*  Format: An optional number between 0 and 9 that appoints output format.     */
/*    Default is 0.		       													*/
/*  Returns a date string formatted in one of ten provided formats.             */
/*                                                                              */
/*  ConvertArchiveTag(DatesStr, Format)                                         */
/*  DatesStr: A string containing two dates formatted as "m/d/yyyy - m/d/yyyy"  */
/*    or "mm/dd/yyyy - mm/dd/yyyy".                                             */
/*  Format: An optional number between 0 and 9 that appoints output format.     */
/*    Default is 0.		       													*/
/*  Returns a string containing two dates formatted in one of ten provided      */
/*    formats, separated by " - ".                                              */
/*                                                                              */
/*  * If you want to change the input format, you should make changeds in       */
/*      ConvertStr function.                                                    */
/*  * ConvertStr function uses GregorianToSolar function to do the date         */
/*      convertion. There is also a SolarToGregorian function which can be used */
/*      to convert Solar dates into Gregorian dates. (May be applied into date  */
/*      entry forms.) Both of these methods are complete in implementation and  */
/*      the only reason of not implenting a ConvertStr for the reverse          */
/*      functionality was the lack of usage for myself. Feel free to use it if  */
/*      needed.                                                                 */
/*                                                                              */
/********************************************************************************/

var dkSolar = 0;
var dkGregorian = 1;

var DaysOfMonths = new Array();
var LeapMonth = new Array();
var DaysToMonth = new Array();

DaysOfMonths = [[31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29], [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]];
LeapMonth = [12, 2];
DaysToMonth = [[0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 365], [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]];

function Integer(val)
{
  this.value = val;
}

function IsLeapYear(DateKind, Year)
{
	if (DateKind == dkSolar) 
		return ((((Year + 38) * 31) % 128) <= 30);
	else
		return (((Year % 4) == 0) && (((Year % 100) != 0) || ((Year % 400) == 0)));
}

function DaysOfMonth(DateKind, Year, Month)
{
	var Result;
	if ((Year != 0) && ((Month <= 12) && (Month >= 1))) 
	{
		Result = DaysOfMonths[DateKind][Month - 1];
		if ((Month == LeapMonth[DateKind]) && IsLeapYear(DateKind, Year)) Result++;
	}
	else
		Result = 0;
	return Result;
}

function IsDateValid(DateKind, Year, Month, Day)
{
	return ((Year!= 0) && (Month >= 1) && (Month <= 12) && (Day >= 1) && Day <= (DaysOfMonth(DateKind, Year, Month)));
}

function DaysToDate(DateKind, Year, Month, Day)
{
	var Result;
	if (IsDateValid(DateKind, Year, Month, Day))
	{
		Result = DaysToMonth[DateKind][Month - 1] + Day;
		if ((Month > LeapMonth[DateKind]) && IsLeapYear(DateKind, Year)) Result++;
	}
	else
		Result = 0;
	return Result;
}

function DateOfDay(DateKind, Days, Year, Month, Day)
{
	var LeapDay = 0;
	Month.value = 0;
	Day.value = 0;
	for (var m = 2; m <= 13; m++) 
	{
		if ((m > LeapMonth[DateKind]) && (IsLeapYear(DateKind, Year))) LeapDay = 1;
		if (Days <= (DaysToMonth[DateKind][m - 1] + LeapDay))
		{
			Month.value = m - 1;
			if (Month.value <= LeapMonth[DateKind]) LeapDay = 0;
			Day.value = Days - (DaysToMonth[DateKind][Month.value - 1] + LeapDay);
			break;
		}
	}
	return IsDateValid(DateKind, Year, Month.value, Day.value);
}

function GregorianToSolar(Year, Month, Day)
{
	var	LeapDay, Days, PrevGregorianLeap, Result;
	if (IsDateValid(dkGregorian, Year.value, Month.value, Day.value))
	{
		PrevGregorianLeap = IsLeapYear(dkGregorian, Year.value - 1);
		Days = DaysToDate(dkGregorian, Year.value, Month.value, Day.value);
		Year.value -= 622;
		if (IsLeapYear(dkSolar, Year.value)) LeapDay = 1
		else LeapDay = 0;
		if (PrevGregorianLeap && (LeapDay == 1)) Days += 287
		else Days += 286;
		if (Days > (365 + LeapDay))
		{
			Year.value++;
			Days -= (365 + LeapDay);
		}
		Result = DateOfDay(dkSolar, Days, Year.value, Month, Day);
	}
	else Result = false;
	return Result;
}

function SolarToGregorian(Year, Month, Day)
{
	var LeapDay, Days, PrevSolarLeap, Result;
	if (IsDateValid(dkSolar, Year.value, Month.value, Day.value))
	{
    	PrevSolarLeap = IsLeapYear(dkSolar, Year.value - 1);
    	Days = DaysToDate(dkSolar, Year.value, Month.value, Day.value);
	    Year.value += 621;
    	if (IsLeapYear(dkGregorian, Year.value)) LeapDay = 1
	    else LeapDay = 0;
	    if (PrevSolarLeap && (LeapDay = 1)) Days += 80
	    else Days += 79;
	    if (Days > (365 + LeapDay))
	    {
			Year.value++;
			Days -= (365 + LeapDay);
		}
		Result = DateOfDay(dkGregorian, Days, Year.value, Month, Day);
	}
	else Result = false;
	return Result;
}

var MonthNames = new Array();
var WeekDayNames = new Array();
var MonthDayNames = new Array();
MonthNames = ["&#1601;&#1585;&#1608;&#1585;&#1583;&#1740;&#1606;", "&#1575;&#1585;&#1583;&#1740;&#1576;&#1607;&#1588;&#1578;", "&#1582;&#1585;&#1583;&#1575;&#1583;", "&#1578;&#1740;&#1585;", "&#1605;&#1585;&#1583;&#1575;&#1583;", "&#1588;&#1607;&#1585;&#1740;&#1608;&#1585;", "&#1605;&#1607;&#1585;", "&#1570;&#1576;&#1575;&#1606;", "&#1570;&#1584;&#1585;", "&#1583;&#1740;", "&#1576;&#1607;&#1605;&#1606;", "&#1575;&#1587;&#1601;&#1606;&#1583;"];
WeekDayNames = ["&#1740;&#1705;&#1588;&#1606;&#1576;&#1607;", "&#1583;&#1608;&#1588;&#1606;&#1576;&#1607;", "&#1587;&#1607; &#1588;&#1606;&#1576;&#1607;", "&#1670;&#1607;&#1575;&#1585; &#1588;&#1606;&#1576;&#1607;", "&#1662;&#1606;&#1580; &#1588;&#1606;&#1576;&#1607;", "&#1580;&#1605;&#1593;&#1607;", "&#1588;&#1606;&#1576;&#1607;"];
MonthDayNames = ["&#1575;&#1608;&#1604;", "&#1583;&#1608;&#1605;", "&#1587;&#1608;&#1605;", "&#1670;&#1607;&#1575;&#1585;&#1605;", "&#1662;&#1606;&#1580;&#1605;", "&#1588;&#1588;&#1605;", "&#1607;&#1601;&#1578;&#1605;", "&#1607;&#1588;&#1578;&#1605;", "&#1606;&#1607;&#1605;", "&#1583;&#1607;&#1605;", "&#1740;&#1575;&#1586;&#1583;&#1607;&#1605;", "&#1583;&#1608;&#1575;&#1586;&#1583;&#1607;&#1605;", "&#1587;&#1740;&#1586;&#1583;&#1607;&#1605;", "&#1670;&#1607;&#1575;&#1585;&#1583;&#1607;&#1605;", "&#1662;&#1575;&#1606;&#1586;&#1583;&#1607;&#1605;", "&#1588;&#1575;&#1606;&#1586;&#1583;&#1607;&#1605;", "&#1607;&#1601;&#1583;&#1607;&#1605;", "&#1607;&#1580;&#1583;&#1607;&#1605;", "&#1606;&#1608;&#1586;&#1583;&#1607;&#1605;", "&#1576;&#1740;&#1587;&#1578;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1740;&#1705;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1583;&#1608;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1587;&#1608;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1670;&#1607;&#1575;&#1585;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1662;&#1606;&#1580;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1588;&#1588;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1607;&#1601;&#1578;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1607;&#1588;&#1578;&#1605;", "&#1576;&#1740;&#1587;&#1578; &#1608; &#1606;&#1607;&#1605;", "&#1587;&#1740; &#1575;&#1605;", "&#1587;&#1740; &#1608; &#1740;&#1705;&#1605;"];

function ConvertStr(DateStr, Format)
{
	var Result;
	var ObjDate = new Date();
	var SplDate = DateStr.split("/");			
	var M = new Integer(parseInt(SplDate[0]));
	var D = new Integer(parseInt(SplDate[1]));
	var Y = new Integer(parseInt(SplDate[2]));
	ObjDate.setFullYear(Y.value);
	ObjDate.setMonth(M.value - 1);
	ObjDate.setDate(D.value);
	var W = ObjDate.getDay();

	if (GregorianToSolar(Y, M, D))
		switch (Format)
		{
		case 0:
			Result = D.value + "/" + M.value + "/" + Y.value;
			break;
		case 1:
			Result = (Y.value - Math.floor(Y.value / 100) * 100) + "/" + M.value + "/" + D.value;
			break;
		case 2:
			Result = (D.value + " " + MonthNames[M.value - 1] + " " + Y.value);
			break;
		case 3:
			Result = (MonthDayNames[D.value - 1] + " " + MonthNames[M.value - 1] + " " + Y.value);
			break;
		case 4:
			Result = (MonthDayNames[D.value - 1] + " " + MonthNames[M.value - 1] + " &#1605;&#1575;&#1607; " + Y.value);		
			break;
		case 5:
			Result = WeekDayNames[W] + "&#1548; " + D.value + "/" + M.value + "/" + Y.value;
			break;
		case 6:
			Result = WeekDayNames[W] + "&#1548; " + D.value + "/" + M.value + "/" + (Y.value - Math.floor(Y.value / 100) * 100);
			break;
		case 7:
			Result = WeekDayNames[W] + "&#1548; " + (D.value + " " + MonthNames[M.value - 1] + " " + Y.value);
			break;
		case 8:
			Result = WeekDayNames[W] + "&#1548; " + (MonthDayNames[D.value - 1] + " " + MonthNames[M.value - 1] + " " + Y.value);
			break;
		case 9:
			Result = WeekDayNames[W] + "&#1548; " + (MonthDayNames[D.value - 1] + " " + MonthNames[M.value - 1] + " &#1605;&#1575;&#1607; " + Y.value);		
			break;
		default:
			//Result = D.value + "/" + M.value + "/" + Y.value;
			Result = Y.value + "/" + M.value + "/" + D.value;
			break;
		}
	else
		Result = "Error converting date.";
	return Result;
}	

function ConvertDateTag(DateStr, Format)
{
	return ConvertStr(DateStr, Format);
}

function ConvertArchiveTag(DatesStr, Format)
{
	var Dates = new Array();
	Dates = DatesStr.split("-");
	var Result = ConvertStr(Dates[0], Format) + " - " + ConvertStr(Dates[1], Format);
	return "<div align=right dir=rtl>" + Result + "</div>";
}
