/* Procedure to display this calendar:
	1.add a div to the html for eg. <div id ="mycal"></div>
	2.add the script tag with source set to this file eg. <SCRIPT LANGUAGE="JavaScript" SRC="calendar.js" type="text/javascript"></SCRIPT>
	3.add the calendar.js and the cal.css files to destination folder where the html file is located.
	4.Functions that can be called:
		a)setfirstdayofweek(1); => will display the calendar with monday as the first weekday.here 0 indicates Sunday, 1 indicates Monday,2 indicates Tuesday and so on.
		b)setinactivedays(1,3,5); => will make the second,forth and sixth weekday in the calendar disabled. 
		c)setvalidfromdate('03/01/2011'); => will make all dates before 03/01/2011 disabled even if this date falls after currentdate if not called all dates before current date are disabled.
		d)setvalidtodate('18/01/2011');=> will make all dates after 18/01/2011 disabled.If not called all dates after current date are selectable.
		e) setinactivedates('01/01/2011','14/12/2010','19/12/2010'); => will make 01/01/2011, 14/12/2010 and 19/12/2010 dates disabled. The dates have to be specified as comma separated strings in the format dd/mm/yyyy
	5.Variable that can be set
		ActivatePrev=false; => ActivatePrev=false indicates that the previous dates cannot be selected and viceversa
	6.To display the calendar to select a from_date or a standalone_date call the function:displaycal()
		paramerts are: 
		1.cal_div_id_in_quotes
		2.element_id_on_click_of_which_the_calendar_has_to_be_displayed_in_quotes
		3.'fromdate' to indicate the date to be selected is a fromdate or a standalone date
		4.calendar_title_in_quotes
		5.document.formname
		6.'dayfieldname','monthfieldname','yearfieldname' or 'datefieldname'
	7.To display the calendar to select a to_date call the function:checktocal('mycal','checkoutimg','Check Out Date',document.requestForm,'CheckOutDay','CheckOutMonth','CheckOutYear','CheckInDay','CheckInMonth','CheckInYear','Select check-in date first.')
		paramerts are: 
		1.cal_div_id_in_quotes
		2.element_id_on_click_of_which_the_calendar_has_to_be_displayed_in_quotes
		3.calendar_title_in_quotes
		4.document.formname
		5.'todayfieldname','tomonthfieldname','toyearfieldname' or 'todatefieldname'
		6.'fromdayfieldname','frommonthfieldname','fromyearfieldname' or 'fromdatefieldname'
		7.'errormsg' that has to displayed when the fromdate is not selected and the user wants to select a todate 
*/


var cal;//calendar div object
var ActivatePrev;//ActivatePrev=false indicates that the previous dates cannot be selected and viceversa
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var monthsnum = new Object();
for(var monthsid = 0; monthsid < months.length; monthsid++)
	monthsnum[months[monthsid]]=monthsid;
var first_div_on_day_arr = [1,2,3,4,5,6,7];//will identify what is the id of the first div that appears in that particular days column.Initially it is divid =1 on sun,divid =2 on mon,divid =3 on tue

//form elements
var myform;
var displaydate;
var from_day,from_month,from_year;//in case of three fields for each date
var to_day,to_month,to_year;//in case of three fields for each date
var from_date, to_date;//in case of one field for eachdate
var date_diff_field = null;//stores the field name of the form element which will hold the value of the no of days between from date and to date.

var fromdate,todate;
var inactive_days = new Array();
var inactive_dates = new Array();
var valid_from_date = null;
var valid_to_date = null;
var first_day_of_week=0;//will hold the value of the first weekday displayed in the calendar eg.(sun,mon,tue..)or (mon,tue,..sun). first_day_of_week=0
var returnfuncname = null; 
var returnfuncarg = new Array(); 

function currentdate(actpreval) {
	//functionality:sets the ActivatePrev variable which is used to identify that all the dates are selectable if set to true and if set to false only the dates in range (validto to validfrom ) inclusive of both if set or else days after the current date
	ActivatePrev=actpreval;
}

//setinactivedays arguments:comma separated weekday numbers for eg. 0,2,3,6
function setinactivedays() {
	//functionality: sets the inactive_days array.The days in this array are not selectable.Here 0 indicates the first weekday displayed in the calendar 1 => second day and so on.
	for(var i = 0;i < arguments.length; i++)
		inactive_days[i] = arguments[i];	
}

//setinactivedates arguments:comma separated date strings for eg. '01/02/2010','14/12/2010'
function setinactivedates() {
	//functionality: sets the inactive_dates array.The dates in this array are not selectable.eg. 01/01/2010 will disable the date 1st Jan,2010
	for(var i = 0;i < arguments.length; i++) 
		inactive_dates[i] = arguments[i];
}

function setdatedifffield(fieldname) {
	//functionality: sets the value of date_diff_field
	date_diff_field = date_diff_field;
}

function setfirstdayofweek(daynum) {
	//functionality: 1.sets the firstdayofweek.
	//				2.also rearranges the first_div_on_day_arr array.
	var divid;
	first_day_of_week = daynum;
	for(var i = 0 ;i < daynum;i++) {
		divid = first_div_on_day_arr.pop();
		first_div_on_day_arr.reverse();
		first_div_on_day_arr.push(divid); 
		first_div_on_day_arr.reverse();
	}
}

function setvalidfromdate(validfrom) {
	//functionality: sets the valid_from_date which when set will make all days from this day uptil valid_to_date (if set) as selectable even if this date appears before the current date.
	valid_from_date = validfrom;
}
function setvalidtodate(validto) {
	//functionality: sets the valid_to_date.All dates after this date are not selectable.
	valid_to_date = validto;
}

function setReturnFunctionName() {
	//functionality:sets the ActivatePrev variable which is used to identify that all the dates are selectable if set to true and if set to false only the dates in range (validto to validfrom ) inclusive of both if set or else days after the current date
	returnfuncname=arguments[0];
	
	for(var i=1;i<arguments.length;i++) {
		returnfuncarg[i-1] =  arguments[i];
	}
	
}


function setFields(formref,day,month,year) {
	//functionality: sets the fields in which the selected date will be displayed.Here dd will be displayed in from_day,mm in from_month and yyyy in from_year if displaydate is fromdate and in to_day, to_month, to_year otherwise
	myform = formref;
	if(displaydate == "fromdate") {
		from_day = day;
		from_month = month;
		from_year = year;
	}
	else {
		to_day = day;
		to_month = month;
		to_year = year;
	}
}

function setField(formref,field) {
	//functionality: sets the field in which the selected date will be displayed.Date will be displayed in the format dd/mm/yyyy in the field set.
	myform = formref;
	if(displaydate == "fromdate") 
		from_date = field;
	else 
		to_date = field;
}

function setDefaultDates() {
	//functionality: sets the fromdate and todate to dates already displayed in the fields set earlier
	fromdate = (myform[from_year].value != "" && myform[from_month].value != "" && myform[from_day].value != "") ? new Date(myform[from_year].value,(parseInt(myform[from_month].value)-1),myform[from_day].value) : null;
	todate = (to_day != null && to_month != null && to_year != null) ? new Date(myform[to_year].value, (parseInt(myform[to_month].value)-1), myform[to_day].value) : null;		
}

function setmonthyear() {
	//functionality: sets the month and year divs to values based on which (fromdate selection or todate selection) calendar is to be displayed.
	var calyear=document.getElementById("year");
	var calmonth=document.getElementById("month");
	if((displaydate=="fromdate" && fromdate != null) || (displaydate=="todate" && todate==null)) {
		calmonth.innerHTML = months[fromdate.getMonth()];
		calyear.innerHTML = fromdate.getFullYear();
	}
	else if(displaydate == "todate" && todate!=null){ 
		calmonth.innerHTML = months[todate.getMonth()];
		calyear.innerHTML = todate.getFullYear();
	}
	else {
		calmonth.innerHTML = months[parseInt(new Date().getMonth())];
		calyear.innerHTML = new Date().getFullYear();
	}
}

function getnumofdays(yr,mn) {	
	//functionality: returns the number of days in a month
	var montharr=[31,28,31,30,31,30,31,31,30,31,30,31];
	if(mn == 1)
		return ((yr % 4 == 0 && yr % 100 != 0)||(yr % 400 == 0)) ? 29 : 28;
		
	return montharr[mn];
}

function drawstructure() {
	//functionality: sets the innerHTML of the calendar div to the structure of the calendar ie creates the required tables and divs.
	var daysarr = ["Su","Mo","Tu","We","Th","Fr","Sa"];
	var i,j;
	var str = "";
	
	//clear the calendar
	cal.innerHTML = "";
	//add the stylesheet
	str += "<link rel='stylesheet' href='cal.css' type='text/css'>";
	//creating the iframe background;
	str += "<iframe style='position:absolute;' frameBorder='0' scrolling='no' src='blank.htm' width='200' height='215'></iframe>";
	
	//creating the resetbutton, title and closebutton
	str += "<div id='calendar' style='z-index:4;'>";
	str += "<table border='0' cellspacing='0' cellpadding='0' width='200' height='20'>";
	str += "<tr align='center'><td><input type='button' name='resetbutton' value='' onClick='resetcal()' class='resetbutton'></td><td ><div id='caltitle'></div></td><td><input type='button' name='closebutton' value='' onClick=displaycal(cal.id,null,null,null,null,null,null,null) class='closebutton'></td></td></tr>"
	str += "</table>";
	
	//creating the move buttons, and month and year div
	str += "<table border='0' cellspacing='1' cellpadding='1' bgcolor='#FFFFFF' align='center' class='caltable' width='180' height='170'><tr><TD colspan='7'>";
	str += "<table width='100%' border='0' cellspacing='0' cellpadding='0' class='hlrow'><tr><td width='25' height='22'><a class='movebutton' href='javascript:void(0)' onclick='prevmonth()'><img src='images/arrow-left.gif' border='0'></a></td><td class='hlrow'><span id='month'></span>&nbsp;<span id='year'></span></td><td></td><td width='25'><a class='movebutton' href='javascript:void(0)' onclick='nextmonth()'><img src='images/arrow-right.gif' border='0'></a></td></tr>";
	str += "</table></TD></tr>";
	
	//creating the days of week ie Su,Mo.....
	str += "<TR>";  
	for(i = first_day_of_week;i < daysarr.length;i++) 
		str += "<td height='30'>" + daysarr[i] + "</td>";
	for(i = 0;i < first_day_of_week;i++) 
		str += "<td height='30'>" + daysarr[i] + "</td>";
	str += "</TR>";  
	
	var count = 1;
	for(i = 0; i < 6;i++) {
		str += "<tr>";
		for(j = 0;j < 7;j++,count++) 
			str += "<TD width=25 height=20><div id=div" + count + " onMouseOver=switchon('div" + count + "') onMouseOut=switchoff('div" + count + "') onclick=validdate('" + count + "')></div></TD>";
		str += "</tr>";
	}
	
	str += "</table></div>";
	cal.innerHTML = str;
}

function fillcal() {
	//functionality: fills the calendar structure with the date values.
	var yr = document.getElementById("year").innerHTML;
	var mn = monthsnum[document.getElementById("month").innerHTML];
	var num_of_days = getnumofdays(yr,mn);
	var	firstday = new Date(yr,mn,1,null,null,null,null).getDay(); //first weekday ie the week day on which the date 1 falls on in this month and year.
	var currnDate, currnMonth, currnYr; //these variables hold the date from which the dates are selectable 
	if(valid_from_date != null && displaydate != "todate")	 { //set currnDate, currnMonth, currnYr to the validto date if set.
		currnDate = parseInt(valid_from_date.substr(0,2));
		currnMonth = parseInt(parseInt(valid_from_date.substr(3,2)) - 1);
		currnYr = parseInt(valid_from_date.substr(6));	
	}
	else if(fromdate == null || displaydate == "fromdate") {//set currnDate, currnMonth, currnYr to the current date
		currnYr = new Date().getFullYear();
		currnMonth = new Date().getMonth();
		currnDate = new Date().getDate();
	}
	else {//set currnDate, currnMonth, currnYr to the fromdate
		currnYr = fromdate.getFullYear();
		currnMonth = fromdate.getMonth();
		currnDate = fromdate.getDate();
	}
		
	if(!ActivatePrev)
		if(yr < currnYr || (yr == currnYr && mn < currnMonth))
			inactivedates(1, firstday, num_of_days);
		else if(yr > currnYr || (yr == currnYr && mn > currnMonth)) 
			chkvalidtodate(yr, mn, 1, firstday, num_of_days);
		else {
				inactivedates(1,firstday,currnDate-1);
				chkvalidtodate(yr, mn, currnDate, firstday, num_of_days);
		}
	else
		activedates(1,firstday,num_of_days);
	
// 	highligting the current date
/* 	if(yr==new Date().getFullYear() && mn==new Date().getMonth())
 		document.getElementById("div"+parseInt(new Date().getDate()+firstday)).className="currentdate";	
*/
}

function chkvalidtodate(yr, mn, currnDate, firstday, num_of_days) {
	//functionality: will check which dates are selectable based on the validtodate if it is set.
	if(valid_to_date != null) {
		var validtoDate = parseInt(valid_to_date.substr(0,2));
		var validtoMonth = parseInt(parseInt(valid_to_date.substr(3,2)) - 1);
		var validtoYr = parseInt(valid_to_date.substr(6));	
	
		if(yr < validtoYr || (yr == validtoYr && mn < validtoMonth))
			activedates(currnDate, firstday, num_of_days);
		else if(yr > validtoYr || (yr == validtoYr && mn > validtoMonth)) 
			inactivedates(currnDate, firstday, num_of_days);
		else {
				activedates(currnDate, firstday, validtoDate);
				inactivedates((validtoDate + 1), firstday, num_of_days);
		}
	}
	else
		activedates(currnDate, firstday, num_of_days);
}

function inactivedates(day,firstday,num_of_days) {
	//functionality: fills the calendar with inactive dates ie setting the innerHTML to date and class to inactivedate
	for(var divid = first_div_on_day_arr[firstday] + day - 1; divid < (first_div_on_day_arr[firstday] + num_of_days); divid++, day++) {
		curdiv = document.getElementById("div"+divid);
		curdiv.innerHTML = day;
		curdiv.className = "inactivedate";
	}
}

function activedates(day,firstday,num_of_days) {
	//functionality: fills the calendar with active dates ie setting the innerHTML to date and class to activedate and also adds the inactivedates if that date or weekday is supposed to be inactive
	var yr = document.getElementById("year").innerHTML;
	var mn = monthsnum[document.getElementById("month").innerHTML];
	var formatedmn,formatedday;
	var msfromdate,mstodate;
	var checkday;
	var nowdate = new Date(yr,mn,day);
	var msnowdate = nowdate.getTime();
	var nowdate_day = nowdate.getDay();
	if(fromdate!=null) 
		msfromdate=fromdate.getTime();
	if(todate != null) 
		mstodate=todate.getTime();
		
	formatedmn = (++mn<10) ? "0"+ mn : mn;
	for(var divid = first_div_on_day_arr[firstday] + day - 1; divid < (first_div_on_day_arr[firstday] + num_of_days); divid++, day++) {
		curdiv = document.getElementById("div" + divid);
		
		//checkday is used to identify in which cell/div in the current row will this date appear.To check if this belongs to a column which is supposed to be disabled ,checkday is searched in the inactive_days array
		checkday = ((nowdate_day - first_day_of_week) >= 0) ? (nowdate_day - first_day_of_week) : (7 - first_day_of_week + nowdate_day);
		//check if this weekday is to be disabled or this date is to be disabled.
		formatedday = (day <10 ) ? "0" + day : day;
		if(inactive_days.join(",").indexOf((checkday)) != -1 || inactive_dates.join(",").indexOf(formatedday+"/"+formatedmn+"/"+yr) != -1 )  {
			curdiv.innerHTML = day;
			curdiv.className = (msfromdate != null && mstodate != null && msnowdate > msfromdate && msnowdate < mstodate) ? "inactivestayclass" : "inactivedate"; //inactivestayclass is the class for those dates which are not clickable but is between the fromdate and todate.
		}
		else { //if not make it an active date
			curdiv.innerHTML = "<a href='javascript:void(0)' class='caldateanchor' id='anch"+divid+"'>" + day + "</a>";
			curdiv.className = ((msfromdate != null && msnowdate == msfromdate) || (mstodate != null && msnowdate > msfromdate && msnowdate <= mstodate)) ? "stayclass" : "activedate";
		}
		msnowdate += (1 * (1000 * 60 * 60 * 24));
		nowdate_day = (nowdate_day < 6) ? ++nowdate_day: 0;
	}
}

function validdate(divid) {
	//functionality: 1.sets the fromdate or todate values based on the value of  displaydate
	//				2. calls the dispdate() function to display the selected date in the required field
	if(document.getElementById("div"+divid).className != "inactivedate") {
		var txtday,txtmonth,txtyear;
		var mn=monthsnum[document.getElementById("month").innerHTML];
		var day=document.getElementById("anch"+divid).innerHTML;
		if(displaydate == "fromdate") {
			fromdate = new Date(document.getElementById("year").innerHTML,mn,day);
			(from_day != null && from_month != null && from_year != null) ? dispdate(from_day,from_month,from_year,fromdate) : dispdate(from_date,fromdate);
			
			if((todate == null && to_day != null && to_month != null && to_year != null) || (todate == null && todate != null) || (todate!=null && fromdate.getTime() > todate.getTime())) {
				todate = new Date(fromdate.getTime() + (1 * (1000 * 60 * 60 * 24)));
				(to_day != null && to_month != null && to_year != null) ? dispdate(to_day,to_month,to_year,todate) : dispdate(to_date,todate);
			}
 			if(todate != null)
				setnum_days_stay();
		}
		else {
			todate = new Date(document.getElementById("year").innerHTML,mn,day);
			(to_day != null && to_month != null && to_year != null) ? dispdate(to_day,to_month,to_year,todate) : dispdate(to_date,todate);
		}
		displaycal(cal.id,null,null,null,null,null,null,null);
		if(returnfuncname != null) 
			returnfuncname.apply(this,returnfuncarg);
	}
}

//dispdate arguments:dayfield,monthfield,yearfield,date or datefield,date
function dispdate() {
	//functionality: displays the date in the required field ie either the dd,mm,yyyy values is separate fields or the 1 field
	if(arguments.length == 4) {
		var txtday = (arguments[3].getDate()<10) ? "0" + arguments[3].getDate() : arguments[3].getDate();
		var mn = parseInt(arguments[3].getMonth());
		var txtmonth = (++mn<10) ? "0" + mn : mn;
		var txtyear = arguments[3].getFullYear();
		myform[arguments[0]].value = txtday;
		myform[arguments[1]].value = txtmonth
		myform[arguments[2]].value = txtyear;
	}
	else {
		var txtday = (arguments[1].getDate()<10) ? "0" + arguments[1].getDate() : arguments[1].getDate();
		var mn = parseInt(arguments[1].getMonth());
		var txtmonth = (++mn<10) ? "0" + mn : mn;
		var txtyear = arguments[1].getFullYear();
		myform[arguments[0]].value = txtday + "/" + txtmonth + "/" + txtyear;
	}
}

function setnum_days_stay() {
	//functionality: displays the number of days between from date and to date in the date_diff_field if it exists.
	if(date_diff_field != null)
	myform.numdays.value = (Math.ceil((todate.getTime() - fromdate.getTime())/(1000*60*60*24)));//1000*60*60*24=milliseconds in one day 
}

function prevmonth() {
	//functionality: displays the previous month's calendar
	if(document.getElementById("month").innerHTML == months[0]) {
		document.getElementById("month").innerHTML = months[11];
		document.getElementById("year").innerHTML = parseInt(document.getElementById("year").innerHTML) - 1;
	}
	else
		document.getElementById("month").innerHTML = months[(monthsnum[document.getElementById("month").innerHTML] - 1)];
	
	clearcal();
	fillcal();
}

function nextmonth() {
	//functionality: displays the next month's calendar
	if(document.getElementById("month").innerHTML == months[11]) {
		document.getElementById("month").innerHTML = months[0];
		document.getElementById("year").innerHTML = parseInt(document.getElementById("year").innerHTML) + 1;
	}
	else
		document.getElementById("month").innerHTML = months[(monthsnum[document.getElementById("month").innerHTML] + 1)];
		
	clearcal();
	fillcal();
}

function changeyear(opn) {
	//functionality: displays the previous or next year's calendar;Currently this function is not called as there is no option in the calendar to change the year.
	document.getElementById("year").innerHTML = (opn =="prev")?parseInt(document.getElementById("year").innerHTML)-1:parseInt(document.getElementById("year").innerHTML)+1;
	clearcal();
	fillcal();
}

function clearcal() {
	//functionality: clears the calendar ie erases all the dates.
	for(var i = 1; i <= 42; i++) {
		document.getElementById("div"+i).innerHTML="";
		document.getElementById("div"+i).className="";
	}		
}

function resetcal() {
	//functionality: resets the calendar ie clears all the dates and also the form fields
 	clearcal();
	fromdate=null;//clicking reset button the from date and to date should also be reset
	todate=null;
	if(from_day != null && from_month != null && from_year != null) {
		myform[from_day].value="";
		myform[from_month].value="";
		myform[from_year].value="";
	}
	else
		myform[from_date].value = "";
	if(to_day != null && to_month != null && to_year != null) {
		myform[to_day].value="";
		myform[to_month].value="";
		myform[to_year].value="";
	}
	else if(to_date != null)
		myform[to_date].value = "";
	
	displaycal(cal.id,null,null,null,null,null,null,null,null);
}
//displaycal arguments:calid,imgid,displayfield,caltitle,formref,day,month,year or calid,imgid,displayfield,caltitle,formref,date
function displaycal() {
	//functionality: displays or hides the calendar based on whether it is currently hidden or displayed respectively
	cal = document.getElementById(arguments[0]);
	cal.style.display = (cal.style.display == "none" || cal.style.display == "") ? "block":"none";
	if(cal.style.display == "block") {
		drawstructure();
		displaydate = arguments[2];	
		if(arguments.length == 8)
  			setFields(arguments[4],arguments[5],arguments[6],arguments[7]);
  		else
  			setField(arguments[4],arguments[5]);
  		
		document.getElementById("caltitle").innerHTML = arguments[3];
	
		//set top and left of calendar to be displayed
		var temp=0;
  		var caltop=0;
  		var calleft = document.getElementById(arguments[1]).offsetWidth;
  		var obj = document.getElementById(arguments[1]);
  		do {
  			temp++;
  			caltop += obj.offsetTop;
  			calleft += obj.offsetLeft;
  		}while(obj = obj.offsetParent);
  		cal.style.position = "absolute";
		cal.style.top = caltop+'px';
  		cal.style.left = calleft+'px';
  		
		setmonthyear();
		fillcal();	
	}
}

function switchon(divid) {
	//functionality: called on mouseover of the date div will highlight the particular div
	var curndiv = document.getElementById(divid);
	if(curndiv.className == "activedate")
		curndiv.className = "mouseoverclass";
}

function switchoff(divid) {
	//functionality: called on mouseout of the date div will remove the highlight on the particular div
	var curndiv=document.getElementById(divid);
	if(curndiv.className == "mouseoverclass")
		document.getElementById(divid).className = "activedate";
}
//displaycal arguments:calid,imgid,displayfield,caltitle,formref,day,month,year or calid,imgid,displayfield,caltitle,formref,date
//checktocal arguments:calid,imgid,caltitle,formref,day,month,year,frmday,frmyear,frmmonth,errmsg or calid,imgid,caltitle,formref,todate,frmdate,errmsg
function checktocal(){
	//functionality: will check if the fromdate is selected before displaying the todate calendar if not then will display the error msg provided.
	if(arguments.length == 11)  {
		displaydate = "fromdate";
		setFields(arguments[3],arguments[7],arguments[8],arguments[9]);
		displaydate = "todate";
		if(myform[from_day].value != "") 
			displaycal(arguments[0],arguments[1],"todate",arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);
		else 
			alert(arguments[10]);
	}
	else  {
		displaydate = "fromdate";
		setField(arguments[3],arguments[5]);
		displaydate = "todate";
		if(myform[from_date].value != "") 
			displaycal(arguments[0],arguments[1],"todate",arguments[2],arguments[3],arguments[4],arguments[5]);
		else 
			alert(arguments[6]);
	}
}
