/*
* //<%-- $Id: date_utils.js,v 1.8 2009/09/14 10:05:16 annette Exp $ --%>
*/
/* ald/de/js/date_utils.js*/

/*  JQuery-flavoured version of date_utils.js with modifications due  
*    to usage of jquery.datepicker calendar and the fact that          
*   the date inputs in the form can only be filled by the calendar.   
*/
/*
adjustDuration(String formName, String startDateField, String endDateField, String durationField, Boolean isTT)
adjustEndDate(String formName, String startDateField, String endDateField, String durationField)
changeDate(String formName, String theDateField, Int newDurationValue)
changeTime(String formName, String timeField, Int timeValue)
checkDate(String formName,String dateField)
checkDateFromFormField(String formName,String dateField,String pattern)
checkDateFromId(String dateFieldId,String pattern) 
checkForSpecialDurationValues(String selectedDurationValue, Int theSelectedIndex)
checkJourneyDateBoundaryValue(String formName, String startDateField, String endDateField, Boolean submitThis) (formerly known as dateDiff())
checkTime(String formName, String timeField)
doEndDate(String formName, String startDateField, String endDateField, Boolean submitThis)
doStartDate(String formName, String startDateField, String endDateField, Boolean submitThis)
getComputableDuration(Int theSelectedIndex)
getDays(Int month, Int year)
getDurationBetween(String startValue, String endValue) String formatted as dd.mm.yyyy
Date.getEndDate(Int durationValue)
getFormDate(String formName, String dateField, String pLocale)
getTodaysDate()
isDate(String formName, String dateField)
isInt(String string)
isExternal()
leapYear(Int year)
parseIntString(String string)
set4DigitYear(String formName, String dateFieldName)
setCalculatedDuration(String formName, String startDateField, String endDateField, String durationField)
setCalculatedEndDate(String formName, String startDateField, String endDateField,Int selectedDurationValue)
setErrorField(String reference, String errorMessage)
setTTDuration(Int computedDurationValue)
Date.toDateStringDE()
toDateObj(String theDateString)
*/


// Resets selected duration value but only if it is bigger than 
// the difference between start and end date.
// isTT is an optional parameter used to detect the usage of TT duration ranges in the form
// Use for earliest start date / latest end date.

function adjustDuration(formName,startDateField,endDateField,durationField,isTT){

  var selectedDurationValue = "";
  var thisEndDateValue = document.forms[formName].elements[endDateField].value;
  var thisStartDateValue = document.forms[formName].elements[startDateField].value;
  var thisDurationValue = getDurationBetween(thisStartDateValue,thisEndDateValue);
  var theSelectedIndex = document.forms[formName].elements[durationField].selectedIndex;
  
  if(isTT != undefined && isTT == true){
    selectedDurationValue = getComputableDuration(theSelectedIndex);
  }
  else {  
    selectedDurationValue = document.forms[formName].elements[durationField].value;
    selectedDurationValue = checkForSpecialDurationValues(selectedDurationValue,theSelectedIndex);
  }
  
  if(thisDurationValue < selectedDurationValue){
  
    if(isTT != undefined && isTT == true){
      document.forms[formName].elements[durationField].selectedIndex = setTTDuration(thisDurationValue);
    }
    else {
      document.forms[formName].elements[durationField].selectedIndex = thisDurationValue;
    
    }
  }
}

// Resets end date but only if the difference between start and end date is
// smaller than the selected duration value.
// isTT is an optional parameter used to detect the usage of TT duration ranges in the form
// Use for earliest start date / latest end date.
function adjustEndDate(formName,startDateField,endDateField,durationField,isTT){

  var thisEndDateValue = document.forms[formName].elements[endDateField].value;
  var thisStartDateValue = document.forms[formName].elements[startDateField].value;
  
  if(!isDate(formName, endDateField)){
    thisEndDateValue = thisStartDateValue;
  }
  var thisDurationValue = getDurationBetween(thisStartDateValue,thisEndDateValue);
  var selectedDurationValue = document.forms[formName].elements[durationField].value;
  var theSelectedIndex = document.forms[formName].elements[durationField].selectedIndex;
  
  if(isTT != undefined && isTT == true){
    if(selectedDurationValue == -1) // -1 (TT-value "beliebig") is set to default duration 7 days
      selectedDurationValue = 7;
    else {
      selectedDurationValue = getComputableDuration(document.forms[formName].elements[durationField].selectedIndex);
    }
  }
  else
    selectedDurationValue = checkForSpecialDurationValues(selectedDurationValue,theSelectedIndex);

  if(thisDurationValue < selectedDurationValue){
    setCalculatedEndDate(formName,startDateField,endDateField,selectedDurationValue);
    $('#endDate').dpSetSelected($('#endDate').get(0).value);
  }
}

// Changes the date input field to a valid date for the specified parameters
function changeDate(formName, theDateField, newDurationValue) {
	
  var dString = document.forms[formName].elements[theDateField].value;
	var thisDate = new Date(toDateObj(dString));
	thisDate = thisDate.getEndDate(newDurationValue);
	
	document.forms[formName].elements[theDateField].value = thisDate;
	$('#endDate').dpSetSelected($('#endDate').get(0).value);
}


/* change time by 30 minute intervals (car rental search) */
function changeTime(formName, timeField, timeValue) {
  var actval = document.forms[formName].elements[timeField].value;
  if (actval.length != 5) {
    alert("Bitte in dieser Form eingeben: 10:00");
    return;
  }
  var actmin = actval.substr(3,2);
  var acthrs = actval.substr(0,2);
  if (isInt(actmin) && isInt(acthrs)) {
    actmin = parseIntString(actmin);
    acthrs = parseIntString(acthrs);
    actmin+=timeValue*30;
    if (actmin < 0) {
      acthrs--;
      if (acthrs < 0) acthrs=23;
      actmin=30;
    }
    if (actmin > 59) {
      acthrs++;
      if (acthrs > 23) acthrs=0;
      actmin=0;
    }
    if (actmin < 10) actmin = "0" + actmin;
    if (acthrs < 10) acthrs = "0" + acthrs;
    var ts = acthrs + ":" + actmin;
    document.forms[formName].elements[timeField].value=ts;
  } else {
    alert("Bitte in dieser Form eingeben: 10:00");
  }
}


/**
*	Checks if a given date string is a valid date,
*/
function checkDate(dateString, messageBox, dateField, theFormName) {
	var errorFlag = false;
	var fixed = false;
	var formName = undefined;
	formName = theFormName;
	

	dateString = dateString.split(".");
	if(dateString.length != 3)
	 errorFlag = true;
	else {
		var day = dateString[0];
		var month = dateString[1];
		var year = dateString[2];
		if (!isInt(day) || !isInt(month) || !isInt(year)) {
			errorFlag = true;
		} 
		else {
			var intMonth = parseInt(month, 10);
			if (intMonth > 12) {
				fixed = true;
				month = 12;
			}
			if (intMonth < 1) {
				fixed = true;
				month = "01";
			}
			if (parseInt(day, 10) < 1) {
				fixed = true;
				day = 1;
			}
			if (getDays((intMonth-1), year) < parseInt(day,10)) {
				fixed = true;
				day = getDays((intMonth-1), year);
			}
			if(day.length == 1 && day.match(/\d/) && parseInt(day) != 0){
			 day = "0" + day;
			 fixed = true;
			}
			if(month.length == 1 && month.match(/\d/) && parseInt(month) != 0){
				month = "0" + month;
				fixed = true;
			}
			if(year.length == 2){
				var thisYear = getTodaysDate().split('.');
				thisYear = thisYear[2]-2000;
				//console.log(thisYear);
				if(parseInt(year, 10) > thisYear)	
					year = parseInt(year, 10) + 1900;
				 else
				 	year = parseInt(year, 10) + 2000;
				 fixed = true;
			}
	
		}
	}
	
	if (errorFlag) {
		
			document.getElementById(messageBox).innerHTML = "Bitte Datumsangabe in dieser Form: " + getTodaysDate() + " TT.MM.JJJJ ";
		
	}
	if (fixed) {
		
			document.getElementById(dateField).value = (day + "." + month + "." + year);
		}
	
	if(errorFlag)
		return false;
	else
		return true;
}

/* Wrapper function for checkDate to allow more flexibility with regard to the parameters */
function checkDateFromFormField(formName,dateField,messageBox) {
	
	var dateString = document.forms[formName].elements[dateField].value;
	return checkDate(dateString, messageBox, formName);
		
}
/* Wrapper function for checkDate to allow more flexibility with regard to the parameters */
function checkDateFromId(dateFieldId,messageBox) {
	
	var dateString = document.getElementById(dateFieldId).value;
	if(dateString != ""){
		return checkDate(dateString, messageBox,dateFieldId);
	}
	else
		return true;	
}

// this takes care of some quite inexplicable oddities whose origins have been swallowed 
// by history
function checkForSpecialDurationValues(selectedDurationValue,theSelectedIndex){
// stupid hack to counter the fact that Web ThomasCook Reisen returns 255 for "beliebig"  
  if(selectedDurationValue == 255 && theSelectedIndex == 0){
    selectedDurationValue = -1;
  }
// another stupid hack to filter through the strange duration values of NEC  
/*
  if(typeof(selectedDurationValue) == 'string' && selectedDurationValue.charAt(0) == "6"){
            selectedDurationValue = parseInt(selectedDurationValue.substr(2),10);
          }
  else if(selectedDurationValue == "13" && theSelectedIndex == 22)
    selectedDurationValue = 22;
  */  
    return parseInt(selectedDurationValue,10);
}

//  Checks if the given date is within the specified parameters of start date, end date etc.
//  submitThis is set to true/false to prevent the date calculations from being called twice when
//  submitting the form

function checkJourneyDateBoundaryValues(formName,startDateField,endDateField,submitThis) {
    var isError = false;
    var start = null;
    var end = null;
    
    if((submitThis && isDate(formName, startDateField)) || !submitThis){
      start = getFormDate(formName,startDateField,'de'); 
    }
    
    if (null == start) {
    	setErrorField(startDateField, "Bitte w&auml;hlen Sie das fr&uuml;heste Hinreisedatum.");
    	
    	isError = true;
    }
    if(endDateField != ""){
    if((submitThis && isDate(formName, endDateField)) || !submitThis){
      var end = getFormDate(formName,endDateField,'de'); 
    }
      if (null == end) {
      	setErrorField(endDateField, "Bitte w&auml;hlen Sie das sp&auml;teste R&uuml;ckreisedatum.");
      
      	isError = true;
      }
    }
    
	var today = new Date();
	var now = Date.UTC( today.getFullYear(),today.getMonth(),today.getDate());
  var diffStart = (start - now) / (1000 * 60 * 60 * 24);
  diffStart = Math.ceil(diffStart);
  if(endDateField != ""){
  	var diffEnd = (end - now) / (1000 * 60 * 60 * 24);
  	diffEnd = Math.ceil(diffEnd);
  }
	var maxEnd = max + min + minDur;
   
  if (diffStart < min) {
  //alert(1);
    if(!submitThis){
      var message = "Reisetermin muss mindestens " + min + " Tage in der Zukunft liegen.";
  		setErrorField(startDateField, message);
		
      changeDate(formName,startDateField,min-diffStart);
      diffStart = diffStart + (min - diffStart);
    }
    isError = true;
  }
  
  if (diffStart > max)
  {
    if(!submitThis){
    	 setErrorField(startDateField, "Das Startdatum darf h&ouml;chstens " + max + " Tage in der Zukunft liegen.");
        /*alert("1b: " + diffStart + " / " + diffEnd + " - " + (max - diffStart));*/
    
      changeDate(formName,startDateField,max-diffStart);
      diffStart = max;
    }
    //alert(2);
    isError = true;
  }

  if (endDateField != ""){
    if (diffEnd < (diffStart + minDur)) {
      if(!submitThis){
        if(!isError){
          setErrorField(endDateField, "Das Enddatum muss mindestens " + minDur + " Tage nach dem Startdatum liegen.");
          /*alert("3a: " + diffStart + " / " + diffEnd + " - " + ((diffStart - diffEnd) + minDur));*/
        }
        changeDate(formName,endDateField,(diffStart-diffEnd)+minDur);
        diffEnd = diffEnd + (diffStart - diffEnd) + minDur;
      }
      //alert(5);
      isError = true;
    }
  
    if (maxDur != ""){
      if(diffEnd > (diffStart + maxDur))
      {
        if(!submitThis){
            setErrorField(endDateField, "Das Enddatum darf h&ouml;chstens " + maxDur + " Tage nach dem Startdatum liegen.");
          
          changeDate(formName,endDateField,(diffStart+maxDur)-diffEnd);
          diffEnd = diffEnd + ((diffStart + maxDur) - diffEnd);
        }
        //alert(6);
        isError = true;
      }
    }
    if(!isError)
    isError = false;
  }
  if(diffEnd < (min + minDur)){
      if(!submitThis){
        if(!isError) {
          setErrorField(endDateField, "Das Enddatum muss mindestens " + (min + minDur) + " Tage in der Zukunft liegen.");
          /*alert("2a: " + diffStart + " / " + diffEnd + " - " + ((min - diffEnd) + minDur));*/
        }
        changeDate(formName,endDateField,(min-diffEnd)+minDur);
        diffEnd = diffEnd + ((min - diffEnd) + minDur);
      }
      //alert(3);
      isError = true;
    }
    
    if (diffEnd > maxEnd) {
      if(!submitThis){
        if(!isError){
          setErrorField(endDateField, "Das Enddatum darf h&ouml;chstens " + maxEnd + " Tage in der Zukunft liegen.");
          /*alert("2b: " + diffStart + " / " + diffEnd + " - " + (max - diffEnd));*/
        }
        changeDate(formName,endDateField,maxEnd-diffEnd);
        diffEnd = maxEnd;
      }
      //alert(4 + " " +eval(maxEnd-diffEnd));
     isError = true;
    }
  if(!isError)
    return true;
  else
    return false;
    
}

// Checks if the given time is valid
function checkTime(formName,timeField) {
  var error = false;
  var ts = document.forms[formName].elements[timeField].value;
  if (ts.length != 5) {
    error = true;
  } else if (ts.charAt(2) != ':') {
    error = true;		
  } else {
    var hrs = ts.substr(0,2);
    var mins = ts.substr(3,2);
    if (!isInt(hrs) || !isInt(mins)) error = true;
    if (parseIntString(hrs) > 23) error = true;
    if (parseIntString(mins) > 59) error = true;
  }
  if (error) {
    alert("Bitte in dieser Form eingeben: 10:00");
    document.forms[formName].elements[timeField].value = "10:00";
  }
}


// clear error message divs
function clearErrorFields(reference1, reference2){
  var theField = reference1 + "Error";
  if(document.getElementById(theField) != undefined){
    $('#' + theField).get(0).innerHTML = "";
    $('#' + theField).get(0).style.display = "none";
  }
  if(reference2 != ''){
    theField = reference2 + "Error";
    if(document.getElementById(theField) != undefined){
      $('#' + theField).get(0).innerHTML = "";
      $('#' + theField).get(0).style.display = "none";
    }
  } 
}

function doEndDate(formName,startDateField,endDateField,submitThis) {
clearErrorFields(startDateField, endDateField);

if(!isDate(formName, startDateField)){
  var startDate = new Date();
  startDate = new Date(startDate.getTime() + (min * 1000*60*60*24));
  document.forms[formName].elements[startDateField].value = startDate.toDateStringDE();
}
  if(checkDateFromFormField(formName,endDateField)) {
  	checkJourneyDateBoundaryValues(formName,startDateField,endDateField,submitThis);
  }
}


function doStartDate(formName,startDateField,endDateField,submitThis) {
  clearErrorFields(startDateField, endDateField);
  if(checkDateFromFormField(formName,startDateField)) {
    checkJourneyDateBoundaryValues(formName,startDateField,endDateField,submitThis);
  }
}

// Generates duration as an integer from TT duration values.
// Awkward and fragile construct that relies on TT never changing their duration
// ranges. Use with caution.
function getComputableDuration(theSelectedIndex){
// first array consists of indices in the duration dropdown list,
// second array contains the longest duration in each range,
// i.e. 1-4 days = 4
  
  var ttDurationValues = new Array(new Array(0,1,2,3,4,5,6,7,8,9),new Array(1,4,8,7,12,16,14,22,21,40));
  var computableDuration = "";
  
  for(var i = 0; i < 10; i++){
    if(theSelectedIndex == ttDurationValues[0][i]) {
      computableDuration = ttDurationValues[1][i];
    }
  }
  
  return computableDuration;
}

//  specifies how many days a given month has
function getDays(month, year) {
	var ar = new Array(12);
	ar[0] = 31;
	ar[1] = (leapYear(year)) ? 29 : 28;
	ar[2] = 31;
	ar[3] = 30;
	ar[4] = 31;
	ar[5] = 30;
	ar[6] = 31;
	ar[7] = 31;
	ar[8] = 30;
	ar[9] = 31;
	ar[10] = 30;
	ar[11] = 31;
	return ar[month];
}
// Calculates duration between a given start and end date.
function getDurationBetween(startValue,endValue){
  var one_day=1000*60*60*24;
  var theDuration = Math.ceil((toDateObj(endValue).getTime()-toDateObj(startValue).getTime())/(one_day));
  return theDuration;
}
// Returns a Date object with the date "duration"-days later
Date.prototype.getEndDate = function(durationValue) {
//   Construction of end date:
//  start date + 1h (to take care of daylight saving time) + 24h * duration

	  n = new Date(this.getTime()+3600000+(86400*(durationValue*1000)));
    n = n.toDateStringDE();
  	return n;
};  

//  will try to construct a date from given field in given form
//	if anything at all goes wrong, it will return null */
	
function getFormDate(formName, dateField, pLocale) {
	   
	if (pLocale != 'de') return null;
	var dateString = document.forms[formName].elements[dateField].value;
	var noError = true;
	var retDate = null;
  	noError = checkDateFromFormField(formName, dateField, pLocale);
    retDate = new Date(toDateObj(dateString));

    if (noError) {
    	return retDate;
    } 
    else {
    	return null;
    }
}

// Convenience method to display today's date as a string with the format dd.mm.yyyy
function getTodaysDate(){
  var todaysDate = new Date();
  todaysDate = todaysDate.toDateStringDE();
  return todaysDate;
}
function isDate(formName, fieldName){
  var fieldValue = document.forms[formName].elements[fieldName].value;
  var isDateString = true;
  if (fieldValue.length != 10) {
  		isDateString = false;
	} 
	else if (fieldValue.charAt(2) != '.' || fieldValue.charAt(5) != '.') {
		isDateString = false;
	} 
	return isDateString;
}
// Checks if given parameter can be cast to integer
// iterate through string. Upon first non-digit, return false 
function isInt(string) {

	for (var i=0; i<string.length; i++) {
		if (!(parseInt(string.charAt(i)) > 0) && (string.charAt(i) != '0')) return false;
	}
	return true;
}

function isExternal(){
var standalone = false;
		standalone = $('#standalone').text();
		
return standalone;
}
// Detects if the parameter is a leap year.
function leapYear(year) {
	if ((year % 400 ==0) || ((year %100 != 0) && (year % 4 == 0))) {
		return true;
	}
	return false;
}

// Converts a number passed to the function as a string to an integer
// Deprecated - use parseInt(number, base) instead 
//   e.g. parseInt(08, 10) returns 8 (10 being the decimal base - duh).
function parseIntString(string) {
	var i = 0;
	while(string.charAt(i) == '0') i++;
	if (i == string.length) return 0;
	return parseInt(string.substring(i,string.length));
}


// Sets the year of a given date to four digits if it is only two.
function set4DigitYear(formName, dateFieldName) {
  var theDateField = document.forms[formName][dateFieldName].value;
  theDateField = theDateField.split('.');
  if(theDateField[2].length < 3){
    theDateField[2] = parseInt(theDateField[2], 10)+2000;
  document.forms[formName][dateFieldName].value = theDateField[0] + "." + theDateField[1] + "." + theDateField[2]; 
  }
}

// sets a duration after change of end date
// use for fixed start and end dates
function setCalculatedDuration(formName, startDateField, endDateField, durationField) {
  
  var endDate = document.forms[formName].elements[endDateField].value;
  var startDate = document.forms[formName].elements[startDateField].value;
  //Calculate difference btw the two dates, and convert to days
  var calculatedDuration = getDurationBetween(startDate,endDate); 
  
  if(calculatedDuration > maxDur){
    calculatedDuration = maxDur;
  }
  document.forms[formName].elements[durationField].value = calculatedDuration;
}

//  In Bucher relaunch, we forgo the traditional alert boxes and use divs to
//  display error messages.
function setErrorField(reference, errorString){
  var theField = reference + "Error";
  
  if(document.getElementById(theField) != undefined && !isExternal()){
    $('#' + theField).get(0).style.display = "block";
    $('#' + theField).get(0).innerHTML = errorString;
  }
}


// sets an end date according to a given duration
// Use for fixed start and end dates
function setCalculatedEndDate(formName, startDateField, endDateField, durationValue){
  var calculatedEndDate = getFormDate(formName,startDateField,'de');
  calculatedEndDate = calculatedEndDate.getEndDate(durationValue);
  document.forms[formName].elements[endDateField].value = calculatedEndDate;
}

// Transforms duration as an integer into a TT duration range.
// Returns the index of the duration list to be selected.
// Awkward and fragile construct that relies on TT never changing their duration
// ranges. Use with caution.
function setTTDuration(computedDurationValue){
        if         (computedDurationValue >= 1 && computedDurationValue <= 4){ return 1;}
        else if    (computedDurationValue >= 5 && computedDurationValue <= 8){ return 2;}
        else if    (computedDurationValue == 7){ return 3;}
        else if    (computedDurationValue >= 9 && computedDurationValue <= 12){ return 4;}
        else if    (computedDurationValue >= 13 && computedDurationValue <= 16){ return 5;}
        else if    (computedDurationValue == 14){ return 6;}
        else if    (computedDurationValue >= 16 && computedDurationValue <= 22){ return 7;}
        else if    (computedDurationValue == 21){ return 8;}
        else if    (computedDurationValue > 22){ return 9;}
        else return 0;
}

// Converts a String with the format "dd.mm.yyyy" into a Date object
function toDateObj(theDateString){
  var theDate = theDateString.split('.')
  theDate = new Date(parseInt(theDate[2],10), parseInt(theDate[1],10)-1, theDate[0]);
  return theDate;
}

// Converts a Date Object into a String with the format dd.mm.yyyy
Date.prototype.toDateStringDE = function(){
    var day = this.getDate();
	  if(day <= 9)
	   day = "0" + day;
    var month = this.getMonth() + 1;
	  if(month <= 9)
	   month = "0" + month;
	  var year = this.getFullYear();
	  var theDateString = day + "." + month + "." + year;
	  
	return theDateString;
};

/*
function popupCal() {
	var pLeft = (screen.width-200)/2;
	var pTop = (screen.height-180)/2;
	var calwin = window.open('','cal','width=146,height=150,left='+pLeft+',top='+pTop+',resizable=0,scrollbars=0,toolbar=0,menubar=0,status=0');
	if (window.focus) {calwin.focus();}
}
*/
/* 	
	Little helper for better readability - replaces
	document.getElementById();
*/

function getElem(id) {
	if ( typeof(id) == 'string' ) {
		return document.getElementById(id);
	}
	return id;
}

/**********************************************************************/
/**
* 	Initialisierung und Aufruf der Datumskalender
*/
function initJourneyDateCalendar(){	

Date.format = 'dd.mm.yyyy';
$(function()
{
	$('.date-pick').datePicker({clickInput:true})
	$('#startDate').bind(
		'dpClosed',
		function(e, selectedDates)
		{
			var d = selectedDates[0];
			if (d) {
				d = new Date(d);
				$('#endDate').dpSetStartDate(d.addDays(1).asString());
			}
		}
	);
	$('#endDate').bind(
		'dpClosed',
		function(e, selectedDates)
		{
			var d = selectedDates[0];
			if (d) {
				d = new Date(d);
				$('#startDate').dpSetEndDate(d.addDays(-1).asString());
			}
		}
	);
});
}


$(document).ready(function() { 
	initJourneyDateCalendar();	
});
