// Calendar functions ************************************************

//********************************************Globals*****************************************************
DATE_OBJ=null;CAL_OBJ=null;DATE_NAME=null;DATE_FORM=null;CAL_VISIBLE=null;START_DAY=null;

//********************************************Calendar rendering of table and links*****************************************************
function renderCal(m,y,all) {
	
	var calDate=new Date(y,m-1,1);	//subtract 1 from month because Date() uses index values for month (0-11)
	var weekDay = calDate.getDay();	//(0-6)
	var month = calDate.getMonth(); //(0-11)
	var year = calDate.getFullYear();

  var wDayArr = new Array('S','M','T','W','T','F','S');
  var monthArr=new Array('January','February','March','April','May','June','July','August','September','October','November','December');
  var firstDayOfMonth = new Date(year,month,1).getDay();  // First day of the month(0-6)
  var numberDays = 32 - new Date(year,month,32).getDate();	// Number days in curr month(1-31)
  var monthName = monthArr[month].toUpperCase();	//Get current month name from array
  var dayOfWeek = wDayArr[weekDay];	//Get current weekday name from array(S,M,T..)
  
	var today,mm,dd,yy;	//for keeping track of today or selected inDate
	var d1=formatDate(DATE_FORM.inDate.value);	//check inDate's value
	if(DATE_NAME=='inDate' || d1==null)	//inDate box was clicked or inDate is blank
		today=new Date();	//set current day to today's date.
	else {
		mm=d1[0]; dd=d1[1]; yy=d1[2];
		today=new Date(yy,mm-1,dd);	//set current day to inDate's date.
	}
	
	var currMonth = today.getMonth();	
	var currDay = today.getDate();
	var currYear = today.getFullYear();
	
  var day;
  //Manipulate starting day for navigation purposes; 50 disables all days, 0 enables all days
  if (all && all==true)
    day = 0;
  else{
    if (year<currYear)
      day = 50;
    else if(year>currYear)
      day = 0;
    else if(year==currYear) {
      if(month<currMonth)
        day = 50;
      else if(month>currMonth)
        day = 0
      else
        day = START_DAY;
    }
  }

	// Create the table tag opener and day headers
	month=month+1;	//add 1 to pass correct param(params need to be actual month values, not indexes) for recursion
	var calendar =	'<table class="cal" cellspacing="1" >' +
  								'<tr>' +
									'<td class="month">' +
									'<a href="javascript:void(0)" onclick="renderCal('+ (month>1?month-1:12) +','+ (month>1?year:year-1) +','+all+');">&laquo;</a>' +
									'</td>' +
									'<td colspan=5 class="month">' +
									monthName +' '+ year +
									'</td>' +
									'<td class="month">' +
									'<a href="javascript:void(0)" onclick="renderCal('+ (month<12?month+1:1) +','+ (month<12?year:year+1) +','+all+');">&raquo;</a>' +
									'</td>' +
									'</tr>' +
									'<tr>';
			
	// Create the calendar headers
	var weekDayName;
  for(weekDayName in wDayArr) {
		calendar +=		'<td class="week">'+ wDayArr[weekDayName] +'</td>';
	} 
									
	// Create the rest of the calendar; Initiate the day counter, starting with the 1st.
	var dayCounter = 1;
	calendar += 		'</tr>' +
							 		'<tr>';
									
  // The variable weekDayTemp is used to ensure that the calendar display consists of exactly 7 columns.
  if (firstDayOfMonth > 0) { 
  	calendar += 	'<td colspan="'+ firstDayOfMonth +'" class="emptyDay">&nbsp;</td>'; 
	}

	weekDayTemp = firstDayOfMonth;
	while (dayCounter <= numberDays) {
		if (weekDayTemp == 7) {	// Seventh column (Saturday) reached. Start a new row.
			weekDayTemp = 0;
			calendar +=	'</tr>' +
									'<tr>';
		}

		if (dayCounter < day) {	//mark all days up to starting day inactive
 			calendar += '<td class="inactiveDay">'+ dayCounter +'</td>';
		}
		else		// mark all days from starting day to last day of month active
			calendar += '<td class="activeDay"><a href="javascript:void(0)" onclick="setDateVal('+month+','+dayCounter+','+year+');">'+ dayCounter +'</a></td>';

		dayCounter++;	// Increment counters
		weekDayTemp++;
	}

	// Complete the row of the last week in month, if necessary
	if (weekDayTemp != 7) { 
		var remainingDays = 7 - weekDayTemp;
		calendar +=		'<td colspan="'+ remainingDays +'" class="emptyDay">&nbsp;</td>'; 
	}
	
	calendar += '</tr>' +
							'</table>';

	writeObject(CAL_OBJ,calendar);	//Writes rendered table into the calendar wrapper div

	CAL_VISIBLE = true;

}

// ******************************************Calendar logic and positioning*************************************************************
function showCal(obj,all) {
	
	var calObj = getObject('dateCal');	//calendar div
	CAL_OBJ = calObj;
	DATE_NAME = obj.name;	//date name (inDate or outDate)
	DATE_FORM = obj.form;
	DATE_OBJ = getObject(obj.id);	//date textbox
	
	var date,month,year,numDays,daysLeft,m,d,y;	
	var d1=formatDate(DATE_FORM.inDate.value);	//check inDate's value
	var d2=formatDate(DATE_FORM.outDate.value);	//check outDate's value
	var offset=false;	//flag for when current day has 31 days and next month has 30 days(prevent offsetting 31 days into 30 days)
	var today=new Date();	//current date
	var currMonth = today.getMonth();	
	var currDay = today.getDate();
	var currYear = today.getFullYear();
	if(DATE_NAME=='inDate') {	//inDate box was clicked
		date=new Date();	//if no value in inDate or outDate, display calendar set to current month
		if(d1==null && d2==null) {
  		numDays = 32 - new Date(currYear,currMonth,32).getDate();	// Number days in curr month(1-31)
  		daysLeft = numDays-currDay+1;
			if(daysLeft<=4)
 				date.setMonth(date.getMonth()+1);	//changes month to next month if less than 4 days left in the month	
		}
 		else if(d1==null && d2!=null) {
 			m=d2[0];d=d2[1]	//set inDate display month to month of outDate
 			d=parseInt(d);	//convert to integer
 			if(d==1)
				date.setMonth(m-2);	//if first of month is picked, display prev month
			else
				date.setMonth(m-1);	//else display current month
 		}
 		else if(d1!=null) {	//set inDate display month to month of inDate
 			m=d1[0];d=d1[1];y=d1[2]
 			date.setMonth(m-1);
 		}
 	}
 	else {	//outDate was clicked
		date=new Date();	//if no value in inDate or outDate, display calendar set to current month
 		if(d1==null && d2==null) {
  		numDays = 32 - new Date(currYear,currMonth,32).getDate();	// Number days in curr month(1-31)
  		daysLeft = numDays-currDay+1;
			if(daysLeft<=4)
 				date.setMonth(date.getMonth()+1);	//changes month to next month if 4 days or less are left in the month	
 		}
 		else if(d1==null && d2!=null) {
 			m=d2[0]; //set inDate display month to month of outDate
			date.setMonth(m-1);	//display calendar set to month entered into outDate
 		}
		else if(d1!=null && d2==null) {
 			m=d1[0]; d=d1[1]; y=d1[2];	//set outDate starting date to value of inDate
			date=new Date(y,m-1,d);	//subtract 1 from month because Date() uses index values for month (0-11)
  		numDays = 32 - new Date(y,m-1,32).getDate();	// Number days in curr month(1-31)
 			d=parseInt(d);	//convert to integer
  		daysLeft = numDays-d+1;
 			if(daysLeft==1) {	//if one day left in month, display next month
  			numDays1 = 32 - new Date(y,m-1,32).getDate();	// Number days in curr month(1-31)
  			numDays2 = 32 - new Date(y,m,32).getDate();	// Number days in next month(1-31)
				if(numDays1 == numDays2)	//is number of days in current month > days in next month?
					date.setDate(date.getDate()+numDays1);	//offset to shift to next month
				else if(numDays1 < numDays2)
					date.setDate(date.getDate()+numDays1);	//offset to shift to next month
				else {	//numDays1 > numDays2
					date.setDate(date.getDate()+numDays2);	//offset to shift to next month
					offset=true;
				}			
			}
		}
 		else if(d1!=null && d2!=null) {
 			m=d2[0]; d=d1[1]; y=d1[2];	//set outDate starting day/year to value of inDate; set display month to outDate value 
			date=new Date(y,m-1,d);	//subtract 1 from month because Date() uses index values for month (0-11)
		}
 	}

	if(offset)
		START_DAY=31
	else
		START_DAY=date.getDate();	//global for keeping track of starting enabled day
	month=date.getMonth()+1;	//add 1 because getMonth returns 0-11
	year=date.getFullYear();	//returns yyyy format
 
	if (!CAL_VISIBLE)	//user clicked on date box and calendar still visible, supress re-rendering
		renderCal(month,year,all);	//renders calendar table and inserts it into the dateCal div.

	var absX = getX(DATE_OBJ);	//abs positioning of date textbox
	var absY = getY(DATE_OBJ);
	
	var x_offset = getW(DATE_OBJ);	//width offset of date textbox
	var y_offset = 0;

	var x = absX + x_offset;	//abs positioning of calendar div; lined up with top left corner of date box
	var y = absY + y_offset;
		
	moveObject(calObj,x,y);	//change css positioning
	showObject(calObj);
	distributeFormValue(DATE_OBJ);
	
	trackMouseClick(hideCal);

}


function hideCal(event) {
	var calObj = getObject('dateCal');
	var dateObj = DATE_OBJ;
	var x=getEventX(event);
	var y=getEventY(event);

	if(!(isInside(dateObj,x,y,0,0,4,0)||isInside(calObj,x,y))) {	//if mouse over date text box or the calendar, supress hiding
		hideObject(calObj);
		untrackMouseClick();
		CAL_VISIBLE = false;
	}
}

function setDateVal(m,d,y) {
	var calObj = getObject('dateCal');
	var dateObj = DATE_OBJ;
	var dateVal = (m<10?'0':'')+m+'/'+(d<10?'0':'')+d+'/'+y;
	dateObj.value = dateVal;
	distributeFormValue(dateObj);
	hideObject(calObj);
	checkDates();	//check to see if inDate > outDate and reset outDate to mm/dd/yyyy if true.
}

function checkDates() {
	var m1,m2,d1,d2,y1,y2;
	var date1=formatDate(DATE_FORM.inDate.value);	//check inDate's value
	var date2=formatDate(DATE_FORM.outDate.value);	//check inDate's value
	if(date1!=null && date2!=null) {
		m1=date1[0]; d1=date1[1]; y1=date1[2];
		m2=date2[0]; d2=date2[1]; y2=date2[2];
		var iDate=new Date(y1,m1-1,d1);
		var oDate=new Date(y2,m2-1,d2);
		if(iDate > oDate)	{
			DATE_FORM.outDate.value = 'mm/dd/yyyy';
			distributeFormValue(DATE_FORM.outDate);
		}
	}

}


// **************************************************************

//Date Functions ***********************************************
// Accepts dates of the format: MM/DD/YYYY, M/D/YY, MM-DD-YYYY  (and all 16 combinations of those three forms)
// Also accepts: Day.Month.Year (using periods with the same allowance digit allowance as specified above)
// Returns: Parsed date in a 3 element numeric array (month,day,4-dig year).  If the date cannot be retrieved from the 
// given text returns null.
function formatDate(pDateStr) {
	var month, day, year, currYear;
	var dateArr = pDateStr.split(/[-/]/);  // Allow 'month/day/year' or 'month-day-year' formats
	var currDate=new Date();
	currYear = currDate.getFullYear();
	
	if( dateArr.length==3 ) {	
		month = parseInt(dateArr[0],10);
		day =parseInt(dateArr[1],10);
		year =parseInt(dateArr[2],10);
	} 
	else {
		dateArr = pDateStr.split(/\./);  // Allow 'day.month.year' format
		if( dateArr.length==3 ) {
			day =parseInt(dateArr[0],10);
			month = parseInt(dateArr[1],10);
			year =parseInt(dateArr[2],10);
		}
		else
			return null;
	}
	
	// Verify good month, day and year ranges
	if (year<2000)	//if they enter only last two digits of the year
		year += 2000;

	if((isNaN(day)) || (isNaN(month)) || (isNaN(year)))	//Check to see if text(or nothing) was entered instead of numbers
		return null;	
	if((month<1 || month>12) || (day<1 || day>31) || (year<currYear || year> currYear+7))	//check ranges
		return null;
	if(day>(month==2?28+((year%4==0)&&((year%100!=0)||(year%400==0))?1:0):30+(month<8?1-((month-1)%2):(month-1)%2)))	//Check for Leap Year
		return null;

	//pad month and day with leading zeros
	if(month<10)
		month = '0' + month;
	if(day<10)
		day = '0' + day;
		
	//d.value=(m<10?'0':'')+m+'/'+(d<10?'0':'')+d+'/'+y;	//pad dates with zeros

	return new Array(month,day,year);
}

function dateErr(dateStr){
	alert('The '+dateStr+' does not seem to be a valid date.\nPlease provide a date in either the format\n"mm/dd/yyyy" or "dd. mm. yyyy".');

}

function verifyData(f,pref){
	var n,iDateStr,oDateStr;
	
	if(!(f.inDate.value))	//fail safe to avoid js error
		alert('Please add a valid '+iDateStr+'.');
	else if(!(f.outDate.value))
		alert('Please add a valid '+oDateStr+'.');
	
	switch (pref) {
		case 'h':	//hotel
			iDateStr = 'Check-In Date';
			oDateStr = 'Check-Out Date';
			
			if(f.city&&(!f.city.value)){
				alert('Please provide a city name\nfor your hotel search.');
				return false;
			}
  	break;
		
		case 'f':	//flight
			iDateStr = 'Departure Date';
			oDateStr = 'Return Date';
			
			if((f.from&&(!f.from.value))||(f.to&&(!f.to.value))){
				alert('Please provide city names or airport codes\nfor your flight search.');
				return false;
			}
  	break;

		case 'c':	//cars
			iDateStr = 'Pickup Date';
			oDateStr = 'Return Date';
 
			if(f.site&&(!f.site.value)){
				alert('Please provide city names or airport codes\nfor your car search.');
				return false;
			}
 		break;

		default:
	}
	
	var d1=formatDate(f.inDate.value);
	var d2=formatDate(f.outDate.value);

	if(d1 == null) {
		dateErr(iDateStr);
		f.inDate.value = 'mm/dd/yyyy';
		distributeFormValue(f.inDate);
		return false;
	}

	switch (pref) {
		case 'f':	//flight
			if(!f.type||!f.type[1].checked){
				if(d2 == null) {
					dateErr(oDateStr);
					f.outDate.value = 'mm/dd/yyyy';
					distributeFormValue(f.outDate);
					return false;
				}
				if((d2[2]<d1[2])||( (d2[2]==d1[2])&&( (d2[0]<d1[0])||( (d2[0]==d1[0])&&(d2[1]<d1[1]) ) ) )){
					alert('The '+oDateStr+' must be ON OR AFTER the '+iDateStr+'.\nPlease correct and try again.');
					f.inDate.value = 'mm/dd/yyyy';
					distributeFormValue(f.inDate);
					return false;
				}
			}
  	break;

		default:
			if(d2 == null) {
				dateErr(oDateStr);
				f.outDate.value = 'mm/dd/yyyy';
				distributeFormValue(f.outDate);
				return false;
			}
		
			if((d2[2]<d1[2])||( (d2[2]==d1[2])&&( (d2[0]<d1[0])||( (d2[0]==d1[0])&&(d2[1]<d1[1]) ) ) )){
				alert('The '+oDateStr+' must be ON OR AFTER the '+iDateStr+'.\nPlease correct and try again.');
				f.inDate.value = 'mm/dd/yyyy';
				distributeFormValue(f.inDate);
				return false;
			}
	}
		
	return true;
}
//**************************************************************
//console
function verifyDate(d,n,f) {  if (!d.value) {    alert('Please add a valid '+n+'.');    return false;  }  var e1,e2;  if ((e1=d.value.match(/^(1[0-2]|0?[1-9])\/(3[01]|[12][0-9]|0?[1-9])\/((20)?[0-9]{2})$/))||(e2=d.value.match(/^(3[01]|[12][0-9]|0?[1-9])\.\s*(1[0-2]|0?[1-9])\.\s*((20)?[0-9]{2})$/))) {    var day,month,year;    if (e1) {      day=Number(e1[2]);      month=Number(e1[1]);      year=Number(e1[3]);    } else {      day=Number(e2[1]);      month=Number(e2[2]);      year=Number(e2[3]);    }    year=(year<2000?year+2000:year);    if (day>(month==2?28+((year%4==0)&&((year%100!=0)||(year%400==0))?1:0):30+(month<8?1-((month-1)%2):(month-1)%2))) {      alert('The '+n+' does not seem to be a valid date.');      return false;    }    d.value=(month<10?'0':'')+month+'/'+(day<10?'0':'')+day+'/'+year; } else {var txt='The '+n+' does not seem to be a valid date.';if(f==null||f!=true){txt +='\nPlease provide a date in either the format\n"mm/dd/yyyy" or "dd. mm. yyyy".';}alert(txt);    return false;  }  return true;}

