/**
 * Trida pro funkcionalitu booking formulare
 */
function Booking() {
    /**
     * @var DOMobject Objekt s rezervacnim formularem
     */
    this.elForm = jQ('#bookingIbsForm');
    /*
     *
     */
    this.checkForm = new CheckForm('#bookingIbsForm');
}


/**
Nastavuje datumy pro booking
*/
Booking.prototype.setDates = function() {

    // Datum zacatku je aktualni plus jeden den
    var dateStart = new Date();
    
    //na zaklade tasku cislo 21789 - +2 dny pocatecni datum
    dateStart.setTime( dateStart.getTime() + 2 * 24 * 3600 * 1000 );
    
    // Maximalni datum je aktualni plus 360 dni
    var dateEnd = new Date();
    dateEnd.setTime( dateEnd.getTime() + 360 * 24 * 3600 * 1000 );

    // Nastavuje polozku odlet
    jQ(this.elForm).find('#departure0_ibs').val(
        dateStart.getDate() + '.' + (dateStart.getMonth()+1) + '.' + dateStart.getFullYear()
    );
    jQ(this.elForm).find('#bookingDay0').val(dateStart.getDate());
    jQ(this.elForm).find('#bookingMonthSel0').val((dateStart.getMonth()+1) + '/' + dateStart.getFullYear());

    // Nastavuje polozku prilet
    //na zaklade tasku cislo 21789 - +3 dny odletove datum
    dateStart.setDate(dateStart.getDate() + 1); 
    jQ(this.elForm).find('#return0_ibs').val(
        dateStart.getDate() + '.' + (dateStart.getMonth()+1) + '.' + dateStart.getFullYear()
    );
    jQ(this.elForm).find('#bookingDay1').val(dateStart.getDate());
    jQ(this.elForm).find('#bookingMonthSel1').val((dateStart.getMonth()+1) + '/' + dateStart.getFullYear());
    
    // Nastavuje maximalni datum pro booking
    jQ(this.elForm).find('#maxDate').val(
        dateEnd.getDate() + '.' + (dateEnd.getMonth()+1) + '.' + dateEnd.getFullYear()
    );
}

/**
 * Fce testuje hodnotu ve formulari datumu odledu
 */ 
Booking.prototype.checkDepDate = function(depCalendar, retCalendar) {

    var thisObject = this;
    
    // Nastavuje udalost na zmenu hodnoty
    jQ('#departure0_ibs').change(function() {

        var depVal = jQ(this).val();
        var elReturn = jQ('#return0_ibs');
        
        var depDate = thisObject.getCorrectDate(depVal);

        if (depDate != null) {
            if (depCalendar.minDate.getTime() <= depDate.getTime() && depDate.getTime() <= depCalendar.maxDate.getTime()) {

                jQ(thisObject.elForm).find('#bookingDateRange').addClass('hide').removeClass('show');
                jQ(thisObject.elForm).find('#bookingDeparture').addClass('hide').removeClass('show');
                
                // Nastavuje hodnoty do hidden formularu pro IBS
                jQ(thisObject.elForm).find('#dayFromID_package').val(depDate.getDate());
                jQ(thisObject.elForm).find('#monthYearFromID_package').val(
                    (depDate.getMonth()+1) + '/' + depDate.getFullYear()
                );
                
                retCalendar.minDate.setDate(depDate.getDate());
                retCalendar.minDate.setMonth(depDate.getMonth());
                retCalendar.minDate.setFullYear(depDate.getFullYear());
                
                var arrVal = jQ(elReturn).val();
                var arrDate = thisObject.getCorrectDate(arrVal);   

                // Upravuje hodnotu datumu navratu
                if ( (arrDate == null) || ((arrDate.getTime() < depDate.getTime()) || (arrDate.getTime()>depCalendar.maxDate.getTime())) ) {
                    jQ(elReturn).val(
                        depDate.getDate() + '.' + (depDate.getMonth()+1) + '.' + depDate.getFullYear()  
                    );
                }
                jQ(elReturn).change();
            } else {
                jQ(thisObject.elForm).find('#bookingDeparture').addClass('hide').removeClass('show');
                jQ(thisObject.elForm).find('#bookingDateRange').addClass('show').removeClass('hide');
            }
        } else {
           jQ(thisObject.elForm).find('#bookingDeparture').addClass('show').removeClass('hide');
        }
    });
}

/**
 * Fce testuje hodnotu ve formulari datumu navratu
 * 
 * @param Caledar retCalendar Objekt sd kalendarem pro zadavani navratu
 */ 
Booking.prototype.checkRetDate = function(retCalendar) {
    
    var thisObject = this;
    
    jQ('#return0_ibs').change(function() {
        
        var retVal = jQ(this).val();

        var retDate = thisObject.getCorrectDate(retVal);
        if (retDate != null) {
            if (retCalendar.minDate.getTime() <= retDate.getTime() && retDate.getTime() <= retCalendar.maxDate.getTime()) {
                
                jQ(thisObject.elForm).find('#bookingReturn').addClass('hide').removeClass('show');
                jQ(thisObject.elForm).find('#bookingDateRange').addClass('hide').removeClass('show');

                // Nastavuje hodnoty do hidden formularu pro IBS
                jQ(thisObject.elForm).find('#dayToID_package').val(retDate.getDate());
                jQ(thisObject.elForm).find('#monthYearToID_package').val(
                    (retDate.getMonth()+1) + '/' + retDate.getFullYear()
                );

            } else {
                jQ(thisObject.elForm).find('#bookingReturn').addClass('hide').removeClass('show');
                jQ(thisObject.elForm).find('#bookingDateRange').addClass('show').removeClass('hide');
            }
        } else {
            jQ(thisObject.elForm).find('#bookingReturn').addClass('show').removeClass('hide');
        }
    });
    
}

Booking.prototype.getCorrectDate = function(strDate) {
	
	var testDate = null;
	
	var checkReg = RegExp('^(([0-3][0-9]|[0-9])\.([1]{1}[0-2]{1}|[0]{1}[1-9]{1}|[1-9]{1})\.[2]{1}[0]{1}[0-9]{2})$');
    if (checkReg.test(strDate) == true) {

       	var viewDate = new Date();
        
        var parseDate = strDate.split('.', 3);
   		for (var index in parseDate) {
			intValue = parseDate[index] * 1;
			index = index * 1;
			switch(index) {
				case 0:
				  viewDate.setDate(intValue);
				  var day = intValue;
				  break;
				case 1:
    			  intValue = intValue - 1; // Index mesice 0..11
				  var month = intValue;					
				  viewDate.setMonth(intValue);
				  break;
				case 2:
				    var year = intValue;		
					viewDate.setFullYear(intValue);
				  break;
			}
   		}
   		
   		if ( 
   		    day == (viewDate.getDate() * 1) &&
   		    month == (viewDate.getMonth() * 1) &&
            year == (viewDate.getFullYear() * 1)
   		) {
   		    testDate = viewDate;
   		}
   	}

	return testDate;
}


/**
 * Fce vlozi po odeslani do destinacnich inputu IATA kody
 * - nejdrive dojde k testu zda je pouzit AAG string z naseptavace 
 *
 * @return bool
 */ 
function setXMLLogiesDestination() {
    var departureDest = jQ('#from1_package').val();
    var returnDest = jQ('#to1_package').val();
    var regWhispererString = new RegExp(/\(([A-Z]{3})\)$/);

    if(regWhispererString.test(departureDest) == true) {
        depIataCode = departureDest.substring(departureDest.length-1,departureDest.length-4);
        jQ('#from1_package').val(depIataCode);
    }
    
    if(regWhispererString.test(returnDest) == true) {
        retIataCode = returnDest.substring(returnDest.length-1,returnDest.length-4);
        jQ('#to1_package').val(retIataCode);
    }
    
    
    return true;
}

/**
 * Fce jez se vola po vytvoreni domu
 * vola veskere potrebne metody pro kontrolu rezervace
 *
 * @param Caledar depCalendar Objekt sd kalendarem pro zadavani odledu
 * @param Caledar calendarRet Objekt sd kalendarem pro zadavani navratu
 */ 
function onReadyBooking() {

    var bookingIBS = new Booking();
    bookingIBS.setDates();

    // Seznam letist
    if (typeof destOpenAirportListId == 'undefined') {
        var destOpenAirportListId = new Array('airportList_dep0','airportList_arr0','airportList_dep1','airportList_arr1');
    } 
    var airportList = new AirportList('#idActiveAirportList', '#aiportListPopup', '#list_aiportListPopup');
    airportList.setAirportList(destOpenAirportListId);
    
    // Minimalni datum
    var minDateDep = new Date();    
    // Maximalni soucastne + 331 dni
    var maxDateDep = bookingIBS.getCorrectDate(jQ('#maxDate').val());

    var minDateRet = new Date();
    var maxDateRet = new Date();
    maxDateRet.setTime(maxDateDep.getTime());
    
    var calendarDep = new Calendar('#departure0_ibs', '#calendarDeparture', '#departure0_ibs', minDateDep, maxDateDep, false);
    calendarDep.setCal();
    
    var calendarRet = new Calendar('#return0_ibs', '#calendarReturn', '#return0_ibs', minDateRet, maxDateRet, false);
    calendarRet.setCal();

    bookingIBS.checkDepDate(calendarDep, calendarRet);
    bookingIBS.checkRetDate(calendarRet);

    bookingIBS.checkForm.isEmpty('ctyf', '#bookingFrom0');
    bookingIBS.checkForm.isEmpty('ctyt', '#bookingTo0');
    
    bookingIBS.checkForm.setCheckFunction(function() {
        return setXMLLogiesDestination();
    });

}

function setDates(identName) {
    var inputInDate = document.getElementById('id_inmo');
    var inputOutDate = document.getElementById('id_outm');
    var selectInDate = document.getElementById('monthYearFromID_'+identName).value;
    var selectOutDate = document.getElementById('monthYearToID_'+identName).value;
    
    inputInDate.value = dateArray[selectInDate];
    inputOutDate.value = dateArray[selectOutDate];
    
}

// *********************************** //
// Funkce pro prediktivni vyhledavani  //
// *********************************** //

// Najde vnoreny element - vrati ID elementu.
function searchChildNodeByTagName(p_parentObjectID, p_tagName) {

  var oTargetObject = null;
  var oTargetSelect = null;
  var sNodeName = "";
  var sNodeID = null;
  
  try {
    oTargetObject = document.getElementById(p_parentObjectID);
  } catch(eException) {
    
  }

  for(nCounter = 0; nCounter < oTargetObject.childNodes.length; nCounter++) {
    sNodeName = oTargetObject.childNodes[nCounter].nodeName;
    sNodeName = sNodeName.toUpperCase();
    if(sNodeName = p_tagName.toUpperCase()) {
      try {
        sNodeID = oTargetObject.childNodes[nCounter].id;
      } catch(eException) {
      }
    }
  }
  return sNodeID;
}

// Zobrazi nalezene shody (zadava se pouze id DIVu s napovedou a reference na INPUT).
function showAvailableDestinationsFast(p_targetObjectID, p_referenceObject, p_eEvent) {

  var sNodeID = null;

  sNodeID = searchChildNodeByTagName(p_targetObjectID, "SELECT");
  
  // Zavola metodu s doplnenym selectem.
  showAvailableDestinations(p_targetObjectID, sNodeID, p_referenceObject, p_eEvent);
}

// Zobrazi nalezene shody.
function showAvailableDestinations(p_targetObjectID, p_targetSelectID, p_referenceObject, p_eEvent) {

  var sWrittenString = null;
  var oTargetObject = null;
  var aResultList = null;
  var bIataCodeFound = false;
  var nKeyCode = null;
  
  try {
    sWrittenString = p_referenceObject.value;
    oTargetObject = document.getElementById(p_targetObjectID);
    oTargetSelect = document.getElementById(p_targetSelectID);
  } catch(eException) {

  }

  try {
    nKeyCode = p_eEvent.keyCode;
  } catch(eException) {
    try {
      nKeyCode = p_eEvent.which;
    } catch(eException2) {
    }
  }
  
  // Po stisku sipky dolu presune vyber na moznosti.
  if(nKeyCode == 40) {
    setSelectBoxActive(p_targetSelectID);
  }

// Po stisku klavesy Enter nastavi hodnotu z nabidky.
  if(nKeyCode == 13) {
    try {
      if(document.getElementById(p_targetSelectID).options.length > 0) {
        p_referenceObject.value = document.getElementById(p_targetSelectID).options[document.getElementById(p_targetSelectID).selectedIndex].innerHTML;
      }
    } catch(eException) {
    }
    hideAvailableDestinationsById(p_targetObjectID, true);
    return false;
  }

  resetDestinationFields(oTargetSelect);
  
  // Pokud je znaku mene jak 3, skryje napovedu.
  if(sWrittenString.length < 3) {
    hideAvailableDestinations(oTargetObject);
  }
  
  // Pokud je znaku 3 a vice, zobrazi napovedu.
  if(sWrittenString.length >= 3) {
    
    // Pro 3 znaky hleda podle IATA kodu.
    aResultList = searchInIataCodes(sWrittenString);

    // Hleda podle nazvu letiste.
    if(aResultList.length == 0) {
      aResultList = searchInAirportNames(sWrittenString);
    } else {
      aResultList = mergeArrays(aResultList, searchInAirportNames(sWrittenString));
    }

    // Hleda podle nazvu mesta.
    if(aResultList.length == 0) {
      aResultList = searchInCityNames(sWrittenString);
    } else {
      aResultList = mergeArrays(aResultList, searchInCityNames(sWrittenString));
    }

    // Hleda podle nazvu zeme.
    if(aResultList.length == 0) {
      aResultList = searchInCountryNames(sWrittenString);
    } else {
      aResultList = mergeArrays(aResultList, searchInCountryNames(sWrittenString));
    }

    // Zobrazi vysledky - pokud je nalezena alespon 1 moznost. 
    if(aResultList.length > 0) {
      for(nCounter = 0; nCounter < aResultList.length; nCounter++) {
        addDestinationElementRecord(oTargetObject, oTargetSelect, gDestinationListCities[aResultList[nCounter]], gDestinationListIATA[aResultList[nCounter]], gDestinationListAirports[aResultList[nCounter]], gDestinationListCountries[aResultList[nCounter]]);
      }
      if(aResultList.length <= nMinOptionLinesCount) {
        oTargetSelect.size = nMinOptionLinesCount;
      }
    }
  }
}

// Prida radek do vysledku.
function addDestinationElementRecord(p_targetObject, p_targetSelect, p_City, p_IataCode, p_Airport, p_Country) {

  var nLastOptionIndex = p_targetSelect.options.length;
  
  if(nLastOptionIndex < 0) {
    nLastOptionIndex = 1;
  }
  
  if(nLastOptionIndex >= 0) {
    p_targetObject.style.visibility = "visible";
    p_targetObject.style.display = "block";
  }
  if((p_IataCode != "undefined") && (p_IataCode != null)){
    p_targetSelect.size = nLastOptionIndex + 1;
    p_targetSelect.options[nLastOptionIndex] = new Option(p_City + ', ' + p_Airport + ', ' + p_Country + ' (' + p_IataCode + ')', p_IataCode);
  }
  
  // Pokud je pocet radku vetsi, nez povoleny limit, vytvori scrollbar.
  if(p_targetSelect.size > nMaxOptionLinesCount) {
    p_targetSelect.size = nMaxOptionLinesCount;
  }
}

// Odstrani zaznamy z nabidky.
function resetDestinationFields(p_targetSelect) {

  p_targetSelect.options.length = 0;
}

// Prohleda IATA kody.
function searchInIataCodes(p_searchString) {

  var aIataCodesList = new Array();
  var nIndex = 0;

  for(nCounter = 0; nCounter < gDestinationListIATA.length; nCounter++) {
    if(gDestinationListIATA[nCounter] == p_searchString.toUpperCase()) {
      aIataCodesList[nIndex] = nCounter;
      nIndex += 1;
    }
  }

  return aIataCodesList;
}

// Prohleda nazvy letist.
function searchInAirportNames(p_searchString) {

  var aAirportNamesList = new Array();
  var nIndex = 0;
  var nWordLength = p_searchString.length;
  var sMatchWord = null;
  var sMatchWord2 = null;

  for(nCounter = 0; nCounter < gDestinationListAirports.length; nCounter++) {
    sMatchWord = gDestinationListAirports[nCounter].substring(0, nWordLength);
    sMatchWord = sMatchWord.toUpperCase();
    sMatchWord2 = gDestinationListAirportsIndex[nCounter].substring(0, nWordLength);
    sMatchWord2 = sMatchWord2.toUpperCase()
    if((sMatchWord == p_searchString.toUpperCase()) || (sMatchWord2 == p_searchString.toUpperCase())) {
      aAirportNamesList[nIndex] = nCounter;
      nIndex += 1;
    }
  }

  return aAirportNamesList;
}

// Prohleda nazvy mest, vcetne diakritiky.
function searchInCityNames(p_searchString) {

  var aCityNamesList = new Array();
  var nIndex = 0;
  var nWordLength = p_searchString.length;
  var sMatchWord = null;
  var sMatchWord2 = null;
  
  for(nCounter = 0; nCounter < gDestinationListCitiesIndex.length; nCounter++) {
    sMatchWord = gDestinationListCities[nCounter].substring(0, nWordLength);
    sMatchWord = sMatchWord.toUpperCase();
    sMatchWord2 = gDestinationListCitiesIndex[nCounter].substring(0, nWordLength);
    sMatchWord2 = sMatchWord2.toUpperCase()
    if((sMatchWord == p_searchString.toUpperCase()) || (sMatchWord2 == p_searchString.toUpperCase())) {
      aCityNamesList[nIndex] = nCounter;
      nIndex += 1;
    }
  }

  return aCityNamesList;
}

// Prohleda nazvy zemi, vcetne diakritiky.
function searchInCountryNames(p_searchString) {

  var aCountryNamesList = new Array();
  var nIndex = 0;
  var nWordLength = p_searchString.length;
  var sMatchWord = "";
  
  for(nCounter = 0; nCounter < gDestinationListCountries.length; nCounter++) {
    sMatchWord = gDestinationListCountries[nCounter].substring(0, nWordLength);
    sMatchWord = sMatchWord.toUpperCase();
    sMatchWord2 = gDestinationListCountriesIndex[nCounter].substring(0, nWordLength);
    sMatchWord2 = sMatchWord2.toUpperCase()
    if((sMatchWord == p_searchString.toUpperCase()) || (sMatchWord2 == p_searchString.toUpperCase())) {
      aCountryNamesList[nIndex] = nCounter;
      nIndex += 1;
    }
  }

  return aCountryNamesList;
}

// Skryje napovedu (dle ID objektu).
function hideAvailableDestinationsById(p_targetObjectID, p_forceHide) {

  // ID selectboxu vnoreneho do vrstvy, ktera se skryva. 
  var sChildSelectBoxID = null;
  var bHidingEnabled = true;
  
  // Vrstva, ktera se skryva.
  p_targetObject = document.getElementById(p_targetObjectID);
  
  // Ziska ID selectu vnoreneho do vrstvy.
  sChildSelectBoxID = searchChildNodeByTagName(p_targetObjectID, "SELECT");
  try {
    // Pokud ma select nastaven priznak "focused", nastavi priznak "aktivni". 
    if(aActiveFields[sChildSelectBoxID] == true) {
      bHidingEnabled = false;
    }
  } catch(eException) {
  }
  // Pokud neni selectbox oznacen jako aktivni, skryje vrstvu s danou prediktivni napovedou.
  if(bHidingEnabled || p_forceHide) {
    try {
    	setTimeout("hideAvailableDestinations(p_targetObject);", 100);
      //hideAvailableDestinations(p_targetObject);
      aActiveFields[sChildSelectBoxID] = null;
    } catch(eException) {
    }
  }
}

// Skryje napovedu.
function hideAvailableDestinations(p_targetObject) {

  p_targetObject.style.visibility = "hidden";
  p_targetObject.style.display = "none";
}

// Slouci do pole neduplicitni polozky.
function mergeArrays(p_array1, p_array2) {

  var aResultArray = new Array();
  var bItemAlreadyPresent = false;
  
  aResultArray = p_array1;
  // Pokud druhe pole nic neobsahuje, vraci rovnou pouze prvni pole. 
  if(p_array2 == null) {
    return aResultArray;
  }
  
  for(nCounter = 0; nCounter < p_array2.length; nCounter++) {
    bItemAlreadyPresent = false;
    for(nCounter2 = 0; nCounter2 < aResultArray.length; nCounter2++) {
      if(p_array2[nCounter] == aResultArray[nCounter2]) {
        bItemAlreadyPresent = true;
      }
    }
    if(bItemAlreadyPresent == false) {
      aResultArray[aResultArray.length] = p_array2[nCounter];
    }
  }
  return aResultArray;
}

// Nastavi hodnotu do pole.
function setLocationValue(p_targetObjectID, p_targetListID, p_sourceObject, eEvent) {

  var oTargetObject = null;
  var sEventType = null;
  var nKeyCode = null;
  
  // Zjisti typ udalosti.
  try {
    sEventType = eEvent.type;
  } catch(eException) {
  }
  
  // Zjisti stisknutou klavesu (detekce Enter).
  if(sEventType == "keypress") {
    try {
      nKeyCode = eEvent.keyCode;
    } catch(eException) {
      try {
        nKeyCode = eEvent.which;
      } catch(eException2) {
      }
    }
  }
  
  // Pokud je vybrana nabidka kliknutim, nebo klavesou Enter, nastavi se vybrana hodnota.
  if((sEventType == "click") || (nKeyCode == 13)) {
    try {
      oTargetObject = document.getElementById(p_targetObjectID);
      oTargetObject.value = p_sourceObject.options[p_sourceObject.options.selectedIndex].innerHTML;
      hideAvailableDestinations(document.getElementById(p_targetListID));
      oTargetObject.focus();
    } catch(eException) {
    }
  }
  return false;
}

// Nastavi pole s vyberem jako aktivni.
function setSelectBoxActive(p_targetListID) {

  document.getElementById(p_targetListID).focus();

  // Nastavi do globalni promenne ID pole, ktere je aktivni. 
  aActiveFields[p_targetListID] = true;
}
