﻿var wDays = new Array ("يكشنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنجشنبه", "جمعه","شنبه");
var Months = new Array ("فروردين", "ارديبهشت", "خرداد", "تير", "مرداد", "شهريور", "مهر", "آبان", "آذر", "دي", "بهمن", "اسفند");

function PersianCalendar()
{
	this.GregorianDate = new Date();
	this.pDate = 0;
	this.pMonth = 0;
	this.pYear = 0;

	if (typeof(_persianCalendar_prototype_called) == 'undefined')
	{
		_persianCalendar_prototype_called = true;
		PersianCalendar.prototype.getDay = getDay;
		PersianCalendar.prototype.getPDay = getPDay;
		PersianCalendar.prototype.getDate = getDate;
		PersianCalendar.prototype.getMonth = getMonth;
		PersianCalendar.prototype.getYear = getYear;
		PersianCalendar.prototype.getFullYear = getFullYear;
		PersianCalendar.prototype.setDate = setDate;
		PersianCalendar.prototype.setMonth = setMonth;
		PersianCalendar.prototype.setYear = setYear;
		PersianCalendar.prototype.setPDate = setPDate;
		PersianCalendar.prototype.addDays = addDays;
		PersianCalendar.prototype.addMonths = addMonths;
		PersianCalendar.prototype.addYears = addYears;
		PersianCalendar.prototype.persianMonthName = persianMonthName;
		PersianCalendar.prototype.persianDayName = persianDayName;
	}

	this.setPDate();
}

function getDay()
{
	return this.GregorianDate.getDay();
}

function getPDay()
{
	return (this.getDay()) % 7;
}

function getDate()
{
	return this.GregorianDate.getDate();
}

function getMonth()
{
	return this.GregorianDate.getMonth();
}

function getYear()
{
	return this.GregorianDate.getFullYear();
}

function getFullYear()
{
	return this.GregorianDate.getFullYear();
}

function setDate(date)
{
	this.GregorianDate.setDate(date);
	this.setPDate();
}

function setMonth(month)
{
	this.GregorianDate.setMonth(month);
	this.setPDate();
}

function setYear(year)
{
	this.GregorianDate.setYear(year);
	this.setPDate();
}

function addDays(days)
{
	this.setDate(this.getDate() + days);
}

function addMonths(months)
{
	var currentPresianDate = this.pDate;
	this.setMonth(this.getMonth() + months);
	this.addDays(currentPresianDate - this.pDate);
}

function addYears(years)
{
	var currentPersianDate = this.pDate;
	this.setYear(this.getYear() + years);
	this.addDays(currentPersianDate - this.pDate);
}

function persianMonthName()
{
	return Months[this.pMonth - 1];
}

function persianDayName()
{
	return wDays[this.getDay()];
}

//******************************************************************************************
//
//			Solar Conversion Unit
//
//******************************************************************************************

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;
}

function setPDate()
{
	var M = new Integer(this.getMonth() + 1);
	var D = new Integer(this.getDate());
	var Y = new Integer(this.getYear());

	if (GregorianToSolar(Y, M, D))
	{
		this.pDate = D.value;
		this.pMonth = M.value;
		this.pYear = Y.value;
	}
	else
	{
		Result = false;
	}

	return true;
}

//******************************************************************************************
//*
//*			Rendering Calendar
//*
//*	
//******************************************************************************************

var baseCalendar;

function InitCalendar()
{
	baseCalendar = new PersianCalendar();
}

function OpenCalendar()
{
 	mycal.innerHTML = GetCalendar();
}

function DisposeCalendar()
{
 	mycal.innerHTML = '';
}

function PrevMonth()
{
	baseCalendar.addMonths(-1);
	mycal.innerHTML = GetCalendar();
}

function NextMonth()
{
	baseCalendar.addMonths(1);
	mycal.innerHTML = GetCalendar();
}

function itgl(sel)
{
	sel.style.color = "#FFFFFF";
	if (sel.innerText != "")
		sel.style.backgroundColor = "#777777";
}

function otgl(sel)
{
	sel.style.color = "#000000";
	sel.style.backgroundColor = "#aaaaaa";
}

function stgl(sel)
{
	if (sel.innerText != "")
	{
		baseCalendar.addDays(sel.innerText - baseCalendar.pDate);
		mycal.innerHTML = GetCalendar();
		SelectedChanged(baseCalendar.pDate, baseCalendar.pMonth, baseCalendar.pYear);
	}
}

function GetCalendar()
{
	//  DECLARE AND INITIALIZE VARIABLES

	var Calendar = new PersianCalendar();
	var weekday = Calendar.getDay();
	var today = new PersianCalendar();
	var DAYS_OF_WEEK = 7;
	var DAYS_OF_MONTH = 31;
	var cal;

	Calendar.setDate(baseCalendar.getDate());
	Calendar.setMonth(baseCalendar.getMonth());
	Calendar.setYear(baseCalendar.getYear());
	Calendar.addDays(1 - Calendar.pDate);

	today.setDate(baseCalendar.getDate());
	today.setMonth(baseCalendar.getMonth());
	today.setYear(baseCalendar.getYear());

	var TR_start = '<TR>';
	var TR_end = '</TR>';
	var highlight_start = '<TD WIDTH="25" HEIGHT="20"  ID="cal"><CENTER><TABLE CELLSPACING=0 BORDER=0 BORDERCOLOR=CCCCCC ID="cal"><TR><TD ID="sel" onclick=stgl(this)><CENTER>';
	var highlight_end   = '</CENTER></TD></TR></TABLE></CENTER>';
	var mhighlight_start = '<TD WIDTH="25" HEIGHT="20"  ID="cal"><CENTER><TABLE CELLSPACING=0 BORDER=0 BORDERCOLOR=CCCCCC ID="cal"><TR><TD ID="cal" onclick=stgl(this); onmouseover="itgl(this)" onmouseout="otgl(this)"><CENTER>';
	var mhighlight_end   = '</CENTER></TD></TR></TABLE></CENTER>';
	var TD_start = '<TD WIDTH="25" HEIGHT="20" ID="cal" onclick=stgl(this); onmouseover="itgl(this)" onmouseout="otgl(this)"><CENTER>';
	var TD_end = '</CENTER></TD>';
	var TDN_start = '<TD WIDTH="25" ID="wk"><CENTER>';
	var TDN_end = '</CENTER></TD>';
	var BEGINMONTH = '<TD id="calh"><CENTER><SPAN onclick=PrevMonth() style="cursor:hand">&lt;</SPAN></CENTER></TD>';
	var ENDMONTH = '<TD id="calh"><CENTER><SPAN onclick=NextMonth() style="cursor:hand">&gt;</SPAN></CENTER></TD>';

	cal =  '<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 BORDERCOLOR=darkgray dir="rtl"><TR><TD>';
	cal += '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2>' + TR_start;
	cal += BEGINMONTH + '<TD COLSPAN="5" ID="calh"><CENTER><B>';
	cal += Calendar.persianMonthName()  + '   ' + Calendar.pYear + '</B>' + TD_end + ENDMONTH + TR_end;
	cal += TR_start;


	for(index=0; index < DAYS_OF_WEEK; index++)
		cal += TDN_start + wDays[index] + TDN_end;

	cal += TD_end + TR_end;
	cal += TR_start;

	for(index=0; index < Calendar.getPDay(); index++)
		cal += TD_start + '  ' + TD_end;

	for(index=0; index < DAYS_OF_MONTH + 7; index++)
	{
		if (index < Calendar.pDate)
		{
			week_day = Calendar.getPDay();

			if (week_day == 0)
				cal += TR_start;

			if (week_day != DAYS_OF_WEEK)
			{
				var dday  = Calendar.pDate;
				var tday = today.pDate;

				if( tday == dday )
					cal += highlight_start + dday + highlight_end + TD_end;
				else
					cal += mhighlight_start + dday + mhighlight_end + TD_end;
			}
			else
				cal += TR_end;

			Calendar.addDays(1);
		}
	}// end for loop


	if (Calendar.getDay() > 0)
	{
		for(index= Calendar.getDay(); index < 7; index++)
		cal += TD_start + '  ' + TD_end;
	}

	cal += '</TD></TR></TABLE></TABLE>';

	//  PRINT CALENDAR
	return cal;
}