
// dateV.js
// date validator for the home page. this is a companion to index.js


//--------------------------------------------------------------------------------------------
				// E V E N T    H A N D L I N G
// -------------------------------------------------------------------------------------------

// set the arriv date to today, and the departure date to today + 1 day
// dynamic behavior : populate checkout if loStay is set and vice-versa

var i = 0;
while(document.forms[i])
{
    var f = document.forms[i];
	if( f.arrivalDateMonth != null
		&& f.arrivalDateDay != null
		&& f.arrivalDateYear != null
		&& f.departureDateMonth != null
		&& f.departureDateDay != null
		&& f.departureDateYear != null )
	{
		  //setDateToToday(f);
		  f.arrivalDateDay.onchange = function() { setCheckoutFromCheckin(f); }
		  f.arrivalDateMonth.onchange = function() { setCheckoutFromCheckin(f); }
		  f.arrivalDateYear.onchange = function() { setCheckoutFromCheckin(f); }
	}

	i++ ; // next form if any

}
//------------------------------------
// default the checkin date to today's date
function setDateToToday(fo)
{
		// get the date from server (defined in JSP page) if we can.
		var now;
		// donot use system time for default date.
		//(typeof today == 'undefined' || today == null) ? now = new Date() : (now = today);
		now = new Date();

  		//debug( "Today is " + now.getMonth() + "/" + now.getDate() + "/" + now.getFullYear());
  		var index_year = getYearIdx( now.getFullYear() );
  		var index_month = now.getMonth() + 1; // in Javascript, months are zero-based
  		var index_day = now.getDate();

  		//debug("indexes :");
  		//debug("year= " + index_year + " month= " + index_month + " day= " + index_day);

  		fo.arrivalDateYear.options[index_year-1].selected = true;
  		fo.arrivalDateMonth.options[index_month-1].selected = true;
  		fo.arrivalDateDay.options[index_day-1].selected = true;

		// set the checkout field accordingly (i.e + 1 day)
		setCheckoutFromCheckin(fo);

}
//-------------------------------------
// set the checkout date form the checkin date at start
// to reflect a stay of 1 day by default
function setCheckoutFromCheckin(f)
{
		// use short names
		// values
  		var inyear = f.arrivalDateYear.options[f.arrivalDateYear.selectedIndex].value;
  		var inmonth = f.arrivalDateMonth.options[f.arrivalDateMonth.selectedIndex].value;
  		var inday = f.arrivalDateDay.options[f.arrivalDateDay.selectedIndex].value;

        var checkinFilled = ( inyear != '' && inmonth != '' && inday != '');
		if( !checkinFilled)
			return;

 	 	var outyear = f.departureDateYear.options[f.departureDateYear.selectedIndex].value;
  		var outmonth = f.departureDateMonth.options[f.departureDateMonth.selectedIndex].value;
  		var outday = f.departureDateDay.options[f.departureDateDay.selectedIndex].value;


		// if chout is filled just return. Why ? We don't want to set checkout to checkin
		// + 1 day EVERYTIME checkin is touched. For example, If I enter 10/10/01 as checkin,
		// checkout will be automatically 10/11/01. Then I change the checkout date to be
		// 10/14/01, since I really want to stay 3 nights..That's ok. But say I changed my mind
		// about the checkin day, but the checkout day is fine. I want my stay to be from
		// 10/11/01 till 10/14/01..If we don't return here, the checkout date will be once again
		// changed automatically to checkin + 1 . Then, I'll have to change the checkout again
		// to 10/14/01 once again...Kind of annoying..
		// Well, if this annoyance is deemed 'okay', just comment out the next 3 lines..
		var checkoutFilled = ( outyear != '' && outmonth != '' && outday != '');
		//if(checkoutFilled)
		//	return;

		// we have checkin but not checkout. set checkout = checkin + 1 day
		var checkin = new Date(inyear, inmonth -1, inday);

                //for debugging
                //alert('checkin date: ' + checkin);
                //alert('checkin in millisec: ' + checkin.getTime());

		oneDayInMillis =  24 * 3600 * 1000;
		checkoutMillis = checkin.getTime() + oneDayInMillis;

                //for debugging
                //alert('checkoutMillis: ' + checkoutMillis);
                //alert('testing date function (Oct 28): ' + new Date(1004241600000));
                //alert('testing date function (Oct 28 + one day in mills): ' + new Date(1004328000000));

                //alert('Oct 28 (date): ' + new Date('October 28,2001'));
                //alert('Oct 28 (millis): ' + new Date('October 28,2001').getTime());

                //alert('Oct 29 (date):' + new Date('October 29,2001'));
                //alert('Oct 29 (millis): ' + new Date('October 29,2001').getTime());

                //alert('Oct 31 - Oct 30: ' new Date(October 31,2001) - new Date(October 30,2001));

		chout = new Date( checkoutMillis );
                //Fix for strange Oct 28 javascript bug - BEGIN
                //if adding one day in miilis is not enough to increment chout by 1 day, keep adding 1 hour in millis until chout is one day after checkin
                var oneDayInMillisAdjusted = (24 * 3600 * 1000) + (3600 * 1000);
                if(chout.getDate() == checkin.getDate()) {
                    while(chout.getDate() == checkin.getDate()) {
                        chout = new Date(checkin.getTime() + oneDayInMillisAdjusted);
                        oneDayInMillisAdjusted += 3600;
                    }
                }

                //Fix for strange Oct 28 javascript bug - END

        offset = parseInt(f.arrivalDateYear.options[1].value.toString().slice(2),10)-1;
		f.departureDateDay.selectedIndex = parseInt( chout.getDate(), 10 );
		f.departureDateMonth.selectedIndex = parseInt( chout.getMonth(), 10 )+1;
		f.departureDateYear.selectedIndex = parseInt( chout.getFullYear().toString().slice(2), 10 ) - offset;
		
		
    
}


//--------------------------------------------------------------------------------------------
				// E R R O R    H A N D L I N G
// -------------------------------------------------------------------------------------------
// function setErrCode is defined in index.js

// errors . see index.js

//--------------------------------------------------------
// check the dates
// Error : incomplete or invalid dates
// Error : checkin date after checkout date
// Error : checkin date = checkout date
// Error : checkin date before today
// Error : too far out in the future
// Error : stay too long
function okDates(f)
{
		  if( fieldsEmty(f) )
		     return true;

		  if( ! okCheckin(f) )
		     return false;

		  if( ! okCheckout(f) )
		     return false;

		  if( ! okCheckinAndCheckout(f) )
		     return false;

		  // fill in date hidden fields if any
		  fillInDates(f);

   	  	  return true;
}

//------------------------------------------------------
// ADDED: if no date field is filled at all, just return true without doing any checking,
// since user should be able to do a global search without a date
function fieldsEmty(f)
{
   		// all fields must exist, otherwise the check is not needed
   		if(
		    f.arrivalDateMonth == null || f.arrivalDateDay == null || f.arrivalDateYear == null
			|| f.departureDateMonth == null || f.departureDateDay == null
			|| f.departureDateYear == null
		  )
		 		return true;

  		// use short names
  		var inyear = f.arrivalDateYear.options[f.arrivalDateYear.selectedIndex].value;
  		var inmonth = f.arrivalDateMonth.options[f.arrivalDateMonth.selectedIndex].value;
  		var inday = f.arrivalDateDay.options[f.arrivalDateDay.selectedIndex].value;

 	 	var outyear = f.departureDateYear.options[f.departureDateYear.selectedIndex].value;
  		var outmonth = f.departureDateMonth.options[f.departureDateMonth.selectedIndex].value;
  		var outday = f.departureDateDay.options[f.departureDateDay.selectedIndex].value;

  		// If no date field is filled at all, just return true without doing any checking,
  		// since user should be able to do a global search without a date
  		if( inyear == '' && inmonth == '' && inyear == ''
      		&& outyear == '' && outmonth == '' &&  outday == '' )
		{
		        // reset the dates hidden fields
				if(f.arrivalDate != null && f.departureDate != null)
				{
						f.arrivalDate.value = '';
			    		f.departureDate.value = '';
			    		//alert('Dates reset');
				}

				return true;
		}

		return false;
}
//------------------------------------------------------
// Error : incomplete or invalid checkin date
// Error : checkin date before today
function okCheckin(f)
{
    	if( f.arrivalDateMonth == null || f.arrivalDateDay == null || f.arrivalDateYear == null )
		 		return true;

  		// use short names
  		var inyear = f.arrivalDateYear.options[f.arrivalDateYear.selectedIndex].value;
  		var inmonth = f.arrivalDateMonth.options[f.arrivalDateMonth.selectedIndex].value;
  		var inday = f.arrivalDateDay.options[f.arrivalDateDay.selectedIndex].value;

		if ( ! dateValid(inyear,inmonth,inday) )
		{
		  	setErrCode(f,25);
		  	return false;
		}
		// Error : checkin date before today
	  	var today = new Date();
		// Note: in Javascript, months are zero-based (i.e Jan is 0 and Dec is 11),
   		var checkin = new Date(inyear, inmonth -1, inday);
	  	if(getDiffDays(today,checkin) < -1)
	  	{
	      	setErrCode(f,24);
		  	return false;
	  	}

		return true;
}
//--------------------------------------------------------
// Error : incomplete or invalid checkout date
function okCheckout(f)
{
        if( f.departureDateMonth == null || f.departureDateDay == null
		    || f.departureDateYear == null )
		 		  return true;

  		// use short names
 	 	var outyear = f.departureDateYear.options[f.departureDateYear.selectedIndex].value;
  		var outmonth = f.departureDateMonth.options[f.departureDateMonth.selectedIndex].value;
  		var outday = f.departureDateDay.options[f.departureDateDay.selectedIndex].value;

		if ( ! dateValid(outyear,outmonth,outday) )
	    {
	  	  	     setErrCode(f,25);
	      	     return false;
	    }

		return true;
}

//------------------------------------------------------
// Error : checkin date after checkout date
// Error : checkin date = checkout date
// Error : too far out in the future
// Error : stay too long
function okCheckinAndCheckout(f)
{
      if(
		    f.arrivalDateMonth == null || f.arrivalDateDay == null || f.arrivalDateYear == null
			|| f.departureDateMonth == null || f.departureDateDay == null
			|| f.departureDateYear == null
		)
		 		return true;

  		// use short names
  		var inyear = f.arrivalDateYear.options[f.arrivalDateYear.selectedIndex].value;
  		var inmonth = f.arrivalDateMonth.options[f.arrivalDateMonth.selectedIndex].value;
  		var inday = f.arrivalDateDay.options[f.arrivalDateDay.selectedIndex].value;
 	 	var outyear = f.departureDateYear.options[f.departureDateYear.selectedIndex].value;
  		var outmonth = f.departureDateMonth.options[f.departureDateMonth.selectedIndex].value;
  		var outday = f.departureDateDay.options[f.departureDateDay.selectedIndex].value;

		var checkin = new Date(inyear, inmonth -1, inday);
   		checkoutFilled = ( outyear != "" && outmonth != "" && outday != "");
   		if(checkoutFilled)
     		var checkout = new Date(outyear, outmonth -1, outday);

		// Error : checkin date after checkout date
		if( getDiffDays(checkin,checkout) < 0 )
		{
	      		setErrCode(f,22); //
		  		return false;
	   	}

        // Error : checkin date = checkout date
	    if( inyear == outyear && inmonth == outmonth && inday == outday )
		{
	      	setErrCode(f,23); //
		  	return false;
	   	}

   		// Error : stay too long (> 30 days or 1 month)
		limit = new Date(31 * 24 * 60 * 60 * 1000);
		excess = (checkout.getTime() - checkin.getTime() > limit.getTime())
		                   ? true : false ;
		if (excess)
	   	{
	        setErrCode(f,26); //
		    return false;
	    }

		// Error : too far out in the future (> 550 days or 18 months)
		if(checkoutFilled)
		{
                        var today = new Date();
                        today.setHours(0);
                        today.setMinutes(0);
                        today.setSeconds(0);
                        today.setMilliseconds(0);
			var limit = new Date(550 * 24 * 60 * 60 * 1000);
                        /*have to add the 1 hr in millis because of the possibility of daylight savings time removing an hour.*/
			var excess = (checkout.getTime() - today.getTime() >= (limit.getTime() - (60*60*1000)))
		                   ? true : false ;

			if (excess)
	    	{
	        	setErrCode(f,29); //
		    	return false;
	    	}
		 }

		return true;
}
//----------------------------------------------------
// update if necessary the date hidden fields
function fillInDates(f)
{
          if(
		    f.arrivalDateMonth == null || f.arrivalDateDay == null || f.arrivalDateYear == null
			|| f.departureDateMonth == null || f.departureDateDay == null
			|| f.departureDateYear == null || f.arrivalDate == null || f.departureDate == null
		    )
		 		return;

		   // use short names
  			var inyear = f.arrivalDateYear.options[f.arrivalDateYear.selectedIndex].value;
  			var inmonth = f.arrivalDateMonth.options[f.arrivalDateMonth.selectedIndex].value;
  			var inday = f.arrivalDateDay.options[f.arrivalDateDay.selectedIndex].value;
 	 		var outyear = f.departureDateYear.options[f.departureDateYear.selectedIndex].value;
  			var outmonth = f.departureDateMonth.options[f.departureDateMonth.selectedIndex].value;
  			var outday = f.departureDateDay.options[f.departureDateDay.selectedIndex].value;

		  // "arrivalDate" --> format : yyyy-mm-dd
		  checkinFilled = ( inyear != "" && inmonth != "" && inday != "");
		  if(checkinFilled)
		  {
		  	f.arrivalDate.value = inyear + '-' + paddZero(inmonth) + '-' + paddZero(inday) ;
			var checkin = new Date(inyear, inmonth -1, inday);
		  }
		  else
		  {
		    f.arrivalDate.value = '';
			var checkin = null;
		  }

		  // "departureDate" --> format : yyyy-mm-dd
		  checkoutFilled = ( outyear != "" && outmonth != "" && outday != "");
   		  if(checkoutFilled)
		  {
		    f.departureDate.value = outyear + '-' + paddZero(outmonth) + '-' + paddZero(outday) ;
     		var checkout = new Date(outyear, outmonth -1, outday);
		  }
		  else
		  {
		    f.departureDate.value = '';
		    var checkout = null;
		  }


	  	  // "lengthOfStay" --> format : nn
	      if(f.lengthOfStay != null)
	  	  		f.lengthOfStay.value =  paddZero( getDiffDays(checkin,checkout) );



}

//------------------------------------------------------
                 // utility functions
//-------------------------------------------------------

// strip leading zero, if any.
function stripZero(s)
{
   if(s.charAt(0) == '0')
      s = s.substr(1);

   return s;
}
//-----------------------------------------------
// padd a zero if string is one char
function paddZero(s)
{
	if(s.length ==1)
	  s = '0' + s;

	return s;
}
//-------------------------------------------------
// utility function to validate dates
function dateValid(year, month, day)
{
  		// check for all fields
			if (year == "" || month == "" || day == "")
          		return false;

	   // work with ints
		var y = (year);
		var m = stripZero(month);
		var d = stripZero(day);

	    //alert('Inside dateValid()  y= ' + y + ' m= ' + m + 'd= ' +d );

		if(isNaN(y) || isNaN(m) || isNaN(d))
	  		return false;

		// check for compatibility month-day i.e avoid things like Feb 31

		//  Jan is 1 and Dec is 12
		// Feb(2) cannot have values 29 (except leap year),30,31
		if (m==2)
		{
	   		var isleap = false;
	   		// A year is a leap year if it is evenly divisible by 4 but not evenly divisible by 100
	   		// unless it is also evenly divisible by 400 ...
	   		if (y % 4 ==0)
	   		{
	     		if( !(y % 100 == 0) || ((y % 100 == 0) && (y % 400 == 0)) )
		 			isleap = true;
	   		}

	   		if(d==30 || d==31)
	     		return false;

	   		if(!isleap && d==29)
	     		return false;

		}
		// all 30 - days months should not get 31 : April(4),June(6),Sept(9),Nov(11)
		if (m==4 || m==6 || m==9 || m==11)
		{
	   		if(d==31)
	     		return false;
		}


   		return true;
}

//--------------------------------------------------------
// diff in days between two dates
function getDiffDays(indate,outdate)
{
        if(indate == null || outdate == null)
		  return '';

  		var diff = '';
  		// this will give us a float i.e something like 7.9583333.. for 8 days
  		var df =  ( outdate.getTime()-indate.getTime() ) / (1000 * 60 * 60 * 24);

  		// convert to a whole number
  		df = Math.round(df);

  		// convert to string
  		diff = df.toString(10);

  		return diff;
}

//---------------------------------------------------------

// strip leading zero, if any.
function stripZero(s)
{
   if(s.charAt(0) == '0')
      s = s.substr(1);

   return s;
}
//--------------------------------------------------------

// utility function to get a year's index
function getYearIdx(y)
{
  		// if(y == 2001) return 1;
  		// else if (y == 2012) return 12;
  		year = y.toString();

        return parseInt( stripZero(year.slice(2)) ,10) ;
}
