/* VERSION RELEASED: 12/17/2007 */
/* variables required to be global */
var MaximumDate;
var MinimumDate;
var PageDate;
var gwDynFareCalendar = new Array(2);
var CurrencySigns;
var LowFareLimits;
var DepartureStation = "CGN";
var ArrivalStation = "HAM";
var grossPriceOutward = 0.00;
var grossPriceReturn = 0.00;

/*
  Name: PrependZero
  Desc: Prepends a zero to given date string (day, month)
        if required.
*/

function PrependZero( date )
{
  if ( date < 10 )
  {
    date = '0' + date;
  }

  return date;
}

function PreSelectDateInCalendar() {
	var date_split = PageDate.split("/");
	var date_page_mth = Number(date_split[0]);
	var date_page_yea = Number(date_split[1]);
	var date_now_mth = new Date().getMonth() + 1;
	var date_now_yea = new Date().getYear() + 1900;

	if ( ( date_page_yea == date_now_yea ) && ( date_page_mth == date_now_mth ) )
	{
		var NewOutwardDateObject = new Date();
		var NewReturnDateObject = new Date();
	}
	else
	{
		var NewOutwardDateObject = new Date(date_page_yea, date_page_mth - 1, 1);
		var NewReturnDateObject = new Date(date_page_yea, date_page_mth - 1, 1);
	}
	
    gwDynFareCalendar[0].setMonth(NewOutwardDateObject.getMonth());
    gwDynFareCalendar[0].setYear(NewOutwardDateObject.getFullYear());
    gwDynFareCalendar[0].select(NewOutwardDateObject);
    gwDynFareCalendar[0].render();

    gwDynFareCalendar[1].setMonth(NewReturnDateObject.getMonth());
    gwDynFareCalendar[1].setYear(NewReturnDateObject.getFullYear());
    gwDynFareCalendar[1].select(NewReturnDateObject);
    gwDynFareCalendar[1].render();
}

/*
Name: SetCalendarBySearchUi
Desc: this function sets the calendar
      values by using the fields of
      the compact search above.
*/
function SetCalendarBySearchUi(){
  // set the departure and arrival station for the calendar
  DepartureStation = document.getElementById("Origin").value;
  ArrivalStation = document.getElementById("Destination").value;
  
  // update the dates on both calendars
  var NewOutwardDate = document.getElementById("OutwardDate").value;
  var NewReturnDate = document.getElementById("ReturnDate").value;
  
  // check if the current month ends
  // in less than 5 days and if so
  // set the next month by default
  var TodayDate = new Date();
  var NextMonthDate = new Date(TodayDate.getFullYear(),
                                TodayDate.getMonth()+1,
                                TodayDate.getDate());
  var OneDay=1000*60*60*24;
  var DifferenceToNextMonth = Math.ceil(
            (NextMonthDate.getTime()
              -TodayDate.getTime())
              /(OneDay));
  var DaysToSwapToNextMonth = 7;      
  
  if(NewOutwardDate!=""){
    var NewOutwardDateObject = new Date(NewOutwardDate.substring(NewOutwardDate.lastIndexOf(".")+1),
                                      (NewOutwardDate.substring(NewOutwardDate.indexOf(".")+1,NewOutwardDate.lastIndexOf("."))-1),
                                      NewOutwardDate.substring(0,NewOutwardDate.indexOf(".")));
  }else{
    var NewOutwardDateObject = new Date();
    
    // check if the current month ends
    // in less than 5 days and if so
    // set the next month by default
    if(DifferenceToNextMonth<DaysToSwapToNextMonth){
      NewOutwardDateObject = NextMonthDate;
    } 
  }
  
  if(NewReturnDate!=""){
    var NewReturnDateObject = new Date(NewReturnDate.substring(NewReturnDate.lastIndexOf(".")+1),
                                      (NewReturnDate.substring(NewReturnDate.indexOf(".")+1,NewReturnDate.lastIndexOf("."))-1),
                                      NewReturnDate.substring(0,NewReturnDate.indexOf(".")));
  }else{
    var NewReturnDateObject = new Date();
    
    // check if the current month ends
    // in less than 5 days and if so
    // set the next month by default
    if(DifferenceToNextMonth<DaysToSwapToNextMonth){
      NewReturnDateObject = NextMonthDate;
    }
  }                                    
  
  // update the calendars view now
  gwDynFareCalendar[0].setMonth(NewOutwardDateObject.getMonth());
  gwDynFareCalendar[0].setYear(NewOutwardDateObject.getFullYear());
  gwDynFareCalendar[0].select(NewOutwardDateObject);
  gwDynFareCalendar[0].render();
  
  gwDynFareCalendar[1].setMonth(NewReturnDateObject.getMonth());
  gwDynFareCalendar[1].setYear(NewReturnDateObject.getFullYear());
  gwDynFareCalendar[1].select(NewReturnDateObject);
  gwDynFareCalendar[1].render();
  
  // recall the price downloader
  InitiateCalendarPriceDownloads();
}

/*
Name: InitializeCalendar
Desc: loads the global variables
        and instanciates them in
        order to keep the code
        a little cleaner.
*/
function InitializeCalendar(){
    var TodayDate = new Date();
    PageDate = (TodayDate.getMonth()+2)
             + "/" + TodayDate.getFullYear();
    //PageDate = "6"
    //         + "/" + TodayDate.getFullYear();

    // check if the current month ends
    // in less than 5 days and if so
    // set the next month by default
    var NextMonthDate = new Date(TodayDate.getFullYear(),
                                TodayDate.getMonth()+1,1);
    var OneDay=1000*60*60*24;
    var DifferenceToNextMonth = Math.ceil((NextMonthDate.getTime()-TodayDate.getTime())/(OneDay))
    var DaysToSwapToNextMonth = 7; 
    
    // check if the current month ends
    // in less than 5 days and if so
    // set the next month by default
    if(DifferenceToNextMonth<DaysToSwapToNextMonth){
      PageDate = (NextMonthDate.getMonth()+1)
             + "/" + NextMonthDate.getFullYear();
    }  
             
    MaximumDate = "10/30/2010";
    MinimumDate = (TodayDate.getMonth()+1) 
                + "/" + TodayDate.getDate()
                + "/" + TodayDate.getFullYear(); 
                
    CurrencySigns = new Object();
    CurrencySigns["EUR"] = "&euro;";
    CurrencySigns["GBP"] = "&pound;";
    CurrencySigns["USD"] = "$";
    CurrencySigns["CZK"] = "CZK";
    CurrencySigns["NOK"] = "NOK";
    CurrencySigns["CHF"] = "CHF";
    CurrencySigns["SEK"] = "SEK";
    
    LowFareLimits = new Object();
    LowFareLimits["EUR"] = 20;
    LowFareLimits["GBP"] = 13;
    LowFareLimits["USD"] = 26;
    LowFareLimits["CZK"] = 0;
    LowFareLimits["NOK"] = 0;
    LowFareLimits["CHF"] = 17;
    LowFareLimits["SEK"] = 0;
    
    // define the parameters for the search
    GetSearchArguments();
    PreInitializeSearchUi();
}

/*
Name: PreInitializeSearchUi
Desc: initializes the search ui for the first time
      with the pre-confiugred values.
*/
function PreInitializeSearchUi(){
  SetStation("Origin",DepartureStation,Stations[DepartureStation].name);
  SetStation("Destination",ArrivalStation,Stations[ArrivalStation].name);
}

/*
Name: PerformCalendarFlightSearch
Desc: searches the flights by using the
      dates defined in the calendar.
*/
function PerformCalendarFlightSearch(Culture){
  var cult = Culture || "de-DE";

	// Track the element click with OMTR
    trackElementClick("FlightSearchButton","Calendar: Showflights clicked");

    // pick the flight info values
    var OriginValue = document.getElementById("Origin").value;
    var DestinationValue = document.getElementById("Destination").value;
    var SelectedOutwardDate = gwDynFareCalendar[0].getSelectedDates();
    var SelectedReturnDate = gwDynFareCalendar[1].getSelectedDates();
    
    var OutwardDateValue = SelectedOutwardDate[0].getDate()+"."
                          + (SelectedOutwardDate[0].getMonth()+1)+"."
                          + SelectedOutwardDate[0].getFullYear();
    
    var ReturnDateValue = "";
    
    if(SelectedReturnDate.length>0){
      var ReturnDateValue = SelectedReturnDate[0].getDate()+"."
                          + (SelectedReturnDate[0].getMonth()+1)+"."
                          + SelectedReturnDate[0].getFullYear();
    }
    
    var DateFlexibilityValue = "0|0";

    // define the passengers
    var AdultCountValue = document.getElementById("AdultPaxCount").innerHTML;
    var ChildCountValue = document.getElementById("ChildPaxCount").innerHTML;
    var InfantCountValue = document.getElementById("InfantPaxCount").innerHTML;
    
    // regular and flexible fares
    var FareTypesValue = "R,F";
    
    var TravelTypeValue = "OneWay";
    if(document.getElementById("TripTypeRoundTripRadio").checked){
        TravelTypeValue = "RoundTrip";
    }
    
    // start the search now
    SearchFlights(OriginValue,DestinationValue,
                OutwardDateValue,ReturnDateValue,
                DateFlexibilityValue,AdultCountValue,
                ChildCountValue,InfantCountValue,
                FareTypesValue,TravelTypeValue,cult);
}

/*
Name: GetSearchArguments
Desc: this function allows to define
        the search arguments in the
        querystring of the url.
        
        DEPSTA can be "CGN" (or any iata station-code)
        ARRVSTA can be "SXF" (or any iata station-code)
        FLIGHTDATE must be in "mm-yyyy" format
*/
function GetSearchArguments(){
    // load the parameters for the departure and arrival
    // station from the querystring and set it as an
    // configuration setup for this calendar
    var DepartureParam = GetQueryStringParameter("DEPSTA");
    var ArrivalParam = GetQueryStringParameter("ARRVSTA");
    if(DepartureParam!=""){DepartureStation=DepartureParam;}
    if(ArrivalParam!=""){ArrivalStation=ArrivalParam;}
    
    // check wether a specific month has been selected
    // or not and if so, redefine the page-date of
    // the calendar to the selected month
    var DateParam = GetQueryStringParameter("FLIGHTDATE");
    if(DateParam!=""){
        // date variable is set in the querystring,
        // redefine the initial date value now
        PageDate = DateParam.replace("-","/");
    }
}

/*
Name: GetQueryStringParameter
Input: Name of the querystring parameter
Desc: this function reads parameters
        from the querystring and returns
        the value of the requested parameter.
*/
function GetQueryStringParameter(name){
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}

/*
Name: ShowCalendar
Desc: initializes the calendar
        and displays it in its
        current container on the
        page. It also calls the
        localization and init functions.
*/                    
function ShowLowFareCalendar(culture){   
    // first of all call the initialization
    InitializeCalendar();

    // instanciate both of the calendar controls  
	gwDynFareCalendar[0] = new YAHOO.widget.Calendar
	                ("gwCalendar_0","LowFareCalendarContainerOutward", 
	                { title:"", close:false,
	                 mindate: MinimumDate, maxdate: MaximumDate, 
	                 pagedate: PageDate } );
	                 
	gwDynFareCalendar[1] = new YAHOO.widget.Calendar
	                ("gwCalendar_1","LowFareCalendarContainerReturn", 
	                { title:"", close:false,
	                 mindate: MinimumDate, maxdate: MaximumDate, 
	                 pagedate: PageDate } );
	                 
	// calls the translation for the calendars             
	TranslateCalendar(gwDynFareCalendar[0], culture);
	TranslateCalendar(gwDynFareCalendar[1], culture);
	
	// renders both calendars
	gwDynFareCalendar[0].render();
	gwDynFareCalendar[1].render();
	
	// subscribe the calendars event to my handler-function
	// --> register handlers for a page change
	gwDynFareCalendar[0].changePageEvent.subscribe
	        (InitiateCalendarPriceDownloads, gwDynFareCalendar[0], true); 	
			
	gwDynFareCalendar[1].changePageEvent.subscribe
	        (InitiateCalendarPriceDownloads, gwDynFareCalendar[1], true); 
	
	// --> register handlers for date selection        
//	gwDynFareCalendar[0].selectEvent.subscribe
//	        (ShowTotalPriceOut, gwDynFareCalendar[0], true); 	

	gwDynFareCalendar[0].selectEvent.subscribe
	        (MarkTimeSpanInCalendars, gwDynFareCalendar[0], true); 	

//	gwDynFareCalendar[1].selectEvent.subscribe
//	        (ShowTotalPriceIn, gwDynFareCalendar[1], true); 	
			
	gwDynFareCalendar[1].selectEvent.subscribe
	        (MarkTimeSpanInCalendars, gwDynFareCalendar[1], true); 
			
    PreSelectDateInCalendar();
			
	// adds the prices to the calendar
	InitiateCalendarPriceDownloads();
}

/*
Name: NavigateCalendar
Input: direction to navigation ("next" or "previous")
Desc: this function navigates the calendar
        to the "right" or to the "left".
*/
function NavigateCalendar(direction,calendarid){
    if(direction=="next"){gwDynFareCalendar[calendarid].nextMonth();}
    else{gwDynFareCalendar[calendarid].previousMonth();}
}

/*
Name: InitiateCalendarPriceDownloads
Desc: this function calls the calendar
        price download with a little
        timeout, so that the calendars
        and the DOM can update their
        data fast enough. When not using
        the timeout it may occur that both
        the calendars and the basic DOM
        are not yet updated correctly.
*/
var DownloadProcessActive = false;
var DownloadRequestPending = false;
function InitiateCalendarPriceDownloads(){
    /* Internet Explorer Style Fix */
    FixIEBorderSpacing(); // must be called on re-render

    if(!DownloadProcessActive){
        setTimeout('DownloadCalendarPrices()',200);
        DownloadProcessActive = true;
    }else{
        DownloadRequestPending = true;
    }
}

/*
Name: FixIEBorderSpacing
Desc: this function is a workaround
        for the IE ignoring the CSS
        style property 'border-spacing'
        where IE ignores it and shows
        collapsed borders instead of
        spaces.
*/
function FixIEBorderSpacing(){
    var FirstCal = document.getElementById("gwCalendar_0");  	
    var SecondCal = document.getElementById("gwCalendar_1"); 
    if(FirstCal){FirstCal.cellSpacing="2";}
    if(SecondCal){SecondCal.cellSpacing="2";}
}

/*
Name:   GetCalendarDateRange
Desc:   Returns the minimum and maximum
        date of the given calendar
Params: index - the index of the calendar
Returns: array containing start date and
         end date
*/
function GetCalendarDateRange( index ){
    var StartDate = null;
    var EndDate = null;
    for(var so=0;so<42;so++){
        var CurrentCell = document
            .getElementById("gwCalendar_" + index + "_cell"+so);
        // verify the cell exists
        if(CurrentCell){
            // calendar cell exists
            if(CurrentCell.className
                    .indexOf("selectable")>0){
                    
                // set the start date by the first cell
                if(StartDate==null){
                    StartDate = gwDynFareCalendar[index]
                        .getDateByCellId("gwCalendar_" + index + "_cell"+so); 
                } 
            }
        }
    }
    
    // determine the end date now
    for(var sr=0;sr<42;sr++){
        var CurrentCell = document
            .getElementById("gwCalendar_" + index + "_cell"+sr);
        // verify the cell exists
        if(CurrentCell){
            // calendar cell exists
            if(CurrentCell.className
                    .indexOf("selectable")>0){
                    
                // set the end date by the last cell
                EndDate = gwDynFareCalendar[index]
                    .getDateByCellId("gwCalendar_" + index + "_cell"+sr); 
            }
        }
    }
    
    return [ StartDate, EndDate ];
}

/*
Name: DownloadCalendarPrices
Desc: this function downloads
        the prices to be shown
        in the calendar by using
        the prototype/ajax class
*/
function DownloadCalendarPrices(){
    // quit this function directly
    // if any global server error
    // occured so that the application
    // will not end in a pending state
    if(ServerErrorOccured){return false;}

    // determine the current calendar
    // range for which we need to load
    // all prices from the system
    var outwardDates = GetCalendarDateRange( 0 );
    var returnDates = GetCalendarDateRange( 1 );   
    
    if ( outwardDates == null || returnDates == null ) { return false; }
    
    // build up the date string
    var OutwardPriceDateStart = PrependZero( outwardDates[0].getDate() )+"-"
                                +PrependZero( (outwardDates[0].getMonth()+1) )+"-"
                                +outwardDates[0].getFullYear();
                        
    var OutwardPriceDateEnd = PrependZero( outwardDates[1].getDate() )+"-"
                              +PrependZero( (outwardDates[1].getMonth()+1) )+"-"
                              +outwardDates[1].getFullYear();

    var ReturnPriceDateStart = PrependZero( returnDates[0].getDate() )+"-"
                                +PrependZero( (returnDates[0].getMonth()+1) )+"-"
                                +returnDates[0].getFullYear();
                        
    var ReturnPriceDateEnd = PrependZero( returnDates[1].getDate() )+"-"
                              +PrependZero( (returnDates[1].getMonth()+1) )+"-"
                              +returnDates[1].getFullYear();

    var Adults = $( 'AdultPaxCount' ).innerHTML;
                            
    // call the search form so we do have a valid
    // working form that can be serialized in before
    // we initiate the request to skysales.    
//    RequestPostForm = CreateFlightSearchForm
//                        (DepartureStation,ArrivalStation,PriceDateStart,PriceDateEnd,
//                         '2|2','1','0','0','R,F','RoundTrip');
    
    // send the price request to the server.
    var RequestUri = "/skysales/LowFareCalendar.aspx?Culture=de-DE";
    if(IsCMSEditMode){
      RequestUri = "http://192.168.43.100/skysales/LowFareCalendar.aspx?Culture=de-DE";
    }

    var PriceRequest = new Ajax.Request(RequestUri,{
                                    method: 'post',
                                    contentType: 'application/x-www-url-encoded',
                                    postBody: 'DEPSTA='+DepartureStation+'&ARRVSTA='+ArrivalStation+'&OBEGINDATE='+OutwardPriceDateStart+'&OENDDATE='+OutwardPriceDateEnd+
                                              '&RBEGINDATE='+ReturnPriceDateStart+'&RENDDATE='+ReturnPriceDateEnd+'&ADT='+Adults,
                                    onComplete: DrawCalendarPrices,
                                    onException: HandleServerError,
                                    onLoading: ShowDownloadStatus,
                                    onSuccess: ShowDownloadStatus,
                                    on404: HandleServerError,
                                    on500: HandleServerError});
    
}

/*
Name: ShowDownloadStatus
Desc: this function shows
        the current status of
        the price download from
        the server.
*/
function ShowDownloadStatus(ServerResponse){
    var StatusWindow = document.getElementById("LowFareSearchStatus");
    var CalendarContainerOutward = document.getElementById("LowFareCalendarContainerOutward");
    var CalendarContainerReturn = document.getElementById("LowFareCalendarContainerReturn");
    
    // by default set the status to downloading
    StatusWindow.style.visibility = "visible";
    CalendarContainerOutward.className = CalendarContainerOutward.className.replace
                    ("LowFareCalendarContainer ","LowFareCalendarContainerLight ");
    CalendarContainerReturn.className = CalendarContainerReturn.className.replace
                    ("LowFareCalendarContainer ","LowFareCalendarContainerLight ");
    
    try{    
        if(ServerResponse){
            if(ServerResponse.status==200){
                StatusWindow.style.visibility = "hidden";
                CalendarContainerOutward.className = CalendarContainerOutward.className.replace
                    ("LowFareCalendarContainerLight ","LowFareCalendarContainer ");
                CalendarContainerReturn.className = CalendarContainerReturn.className.replace
                    ("LowFareCalendarContainerLight ","LowFareCalendarContainer ");
                    
                
            }
        }
    }catch(ComponentError){
        // on some calls the ServerResponse
        // object does not allow to access
        // its status property.
    }
}

/*
Name: HandleServerError
Desc: this function handles
        all errors that are produced
        on the server-side and this
        also included XML proxy script
        exceptions or errors that might
        occur in the XML proxy (skysales).
*/
var ServerErrorOccured = false;
function HandleServerError(ServerResponse,Exception){    
    // this stops the download-requests
    ServerErrorOccured=true;
    
    window.status = "Calendar IF Response-code: " 
                          + ServerResponse.status;
  
    // immediately stop all downloads
    // and pending requests that exist
    DownloadProcessActive = false;
    DownloadRequestPending = false;
//    LoadedCalendarPart = 0;
    
    // close the download-status window first
    var StatusWindow = document.getElementById
                        ("LowFareSearchStatus");
    StatusWindow.style.visibility = "hidden";   
    
    // show the error window now
    var ErrorWindow = document.getElementById
                        ("LowFareSearchError");  
    ErrorWindow.style.visibility = "visible";   
    
    // reduce both calendars' opacity
    var CalendarContainerOutward = document
        .getElementById("LowFareCalendarContainerOutward");
    var CalendarContainerReturn = document
        .getElementById("LowFareCalendarContainerReturn");  
    CalendarContainerOutward.className 
        = "LowFareCalendarContainerLight";
    CalendarContainerReturn.className
         = "LowFareCalendarContainerLight";      
}

/*
Name: DrawCalendarPrices
Input: PriceResponse (prototype transport object)
Desc: is fired when the download is completed
        and can be written into the container
        element of each day in the calendar.
*/
// this function adds the prices
// to all calendar days/cells.
function DrawCalendarPrices(PriceResponse){           
    // check wether the response is good or not
    if(PriceResponse.status == 200){
        // request succeeded.
        // code for IE, parse the
        // result xml code now
        
        /* 1. Code for Internet Explorer*/
        if (window.ActiveXObject){
          var PriceResults=new ActiveXObject
                        ("Microsoft.XMLDOM");
          PriceResults.async="false";
          PriceResults.loadXML
            (PriceResponse.responseText);
        }
        /* 2. Code for Firefox, Safari, Opera*/
        else{
          var parser=new DOMParser();
          var PriceResults=parser.parseFromString
          (PriceResponse.responseText,"text/xml");
        }
        
        /* load all the prices from the 
            resultset into a readable object  */
        var Segments = PriceResults.getElementsByTagName('SEGMENT');
        
        // local variables required below
        var PriceList; var CurrentCellName; var CurrentCellObj; 
        var CurrentCellDate; var CurrentPriceDay; var CurrentPriceMonth;
        var CurrentPriceYear; var CurrentPriceDate; var ActiveCellPriceView;
        var CurrentPrice; var CurrencyCode;
        
        /* step thru each segment/calendar */
        for(var s=0;s<Segments.length;s++){
            /* step thru the price-list and 
                add them to the calendar */
            PriceList = Segments[s].getElementsByTagName('DATE');
            for(var p=0;p<PriceList.length;p++){
                // go thru all calendar elements and look
                // for the current day and if it matches
                // the active result day.
                for(var d=0; d<43; d++){
                    CurrentCellName = "gwCalendar_" + s + "_cell" + d;
                    CurrentCellObj = document.getElementById(CurrentCellName);
                    if(CurrentCellObj){
                        // get the current cell date
                        CurrentCellDate = gwDynFareCalendar[s].getDateByCellId(CurrentCellName);
                        CurrentPriceDay = PriceList[p].getElementsByTagName('DAY')[0].firstChild.nodeValue;
                        CurrentPriceMonth = PriceList[p].getElementsByTagName('MONTH')[0].firstChild.nodeValue;
                        CurrentPriceYear = PriceList[p].getElementsByTagName('YEAR')[0].firstChild.nodeValue;
                        CurrentPriceDate = new Date(CurrentPriceYear,(CurrentPriceMonth-1),CurrentPriceDay);
                        
                        // verify the current price is for the current day
                        if(CurrentCellDate.getDate()==CurrentPriceDate.getDate()
                            && CurrentCellDate.getMonth()==CurrentPriceDate.getMonth()
                            && CurrentCellDate.getFullYear()==CurrentPriceDate.getFullYear()){
                            
                            // now add the price to the day-container
                            if(PriceList[p].getElementsByTagName('PRICE')[0].firstChild){
                                // remove an older price from the container
                                ActiveCellPriceView = 
                                    document.getElementById(CurrentCellName)
                                    .getElementsByTagName('div')[0];
                                    
                                if(ActiveCellPriceView)
                                    {document.getElementById(CurrentCellName)
                                            .removeChild(ActiveCellPriceView)};
                                            
                                // determine the current price
                                CurrentPrice = PriceList[p]
                                    .getElementsByTagName('PRICE')
                                    [0].firstChild.nodeValue;
                                CurrencyCode = PriceList[p]
                                    .getElementsByTagName('CURRENCY')
                                    [0].firstChild.nodeValue;
                                
                                // verify that this is not a hidden day
                                if(CurrentCellObj.className.indexOf("selectable")>0){
                                    var PriceDisplayView = "<div style='float: right; '>"
                                                            + "<div class='LargePrice'>" 
                                                            + CurrentPrice.substring(0,CurrentPrice.indexOf(","))
                                                            + "</div><div class='SmallPrice'>" 
                                                            + CurrentPrice.substring(CurrentPrice.indexOf(",")) 
                                                            + "</div></div>";
                                                            
                                    // check if this is a true low fare
                                    // price and is under the limit that
                                    // is defined for this currency
                                    var PriceInteger = parseInt(CurrentPrice.substring(0,CurrentPrice.indexOf(",")));
                                    if(PriceInteger<LowFareLimits[CurrencyCode]){
                                        PriceDisplayView = "<div style='float: right; '>"
                                                            + "<div class='LargePrice'><b>" 
                                                            + CurrentPrice.substring(0,CurrentPrice.indexOf(","))
                                                            + "</b></div><div class='SmallPrice'>" 
                                                            + CurrentPrice.substring(CurrentPrice.indexOf(",")) 
                                                            + "</div></div>"; 
                                    }
                                
                                    // write the new price to the container
                                    document.getElementById(CurrentCellName).innerHTML 
                                    += "<div class='CalendarPrice'>"
                                    + "<div class='CurrencySymbol'>" 
                                    + CurrencySigns[CurrencyCode] + "</div>"
                                    + PriceDisplayView.replace(",00","")
                                    /*
                                        Info: adding this allows you to debug the calendar prices
                                                for QA to test that the correct prices are shown.
                                        
                                        Add this line, if you want to assure correct prices:        
                                        + CurrentPriceDate.getDate() + "." + (CurrentPriceDate.getMonth()+1)
                                    */
                                    + "&nbsp;</div>";
                                    + "</div>";
                                }
                            }
                        }
                    }
                }
            }
        }
    }
       
    DownloadRequestPending=false;
    DownloadProcessActive=false;
    MarkTimeSpanInCalendars();
}

/*
Name: MarkTimeSpanInCalendars
Desc: marks the trip's timespan in the
        calendar (both the outward
        and the return calendar)
*/
function MarkTimeSpanInCalendars(){
    // pick the current date selections
    // from both calendar objects.
    var OutwardDate = gwDynFareCalendar[0]
                        .getSelectedDates()[0];
    var ReturnDate = gwDynFareCalendar[1]
                        .getSelectedDates()[0];
    // terminate this function when 
    // on of the selections does not exist
    if(!OutwardDate){return false;}
    if(!ReturnDate){return false;}
    
    // set the timestamps for both dates
    var OutwardTimestamp = Date.UTC(OutwardDate.getFullYear(),
                                    OutwardDate.getMonth(),
                                    OutwardDate.getDate());
    var ReturnTimestamp = Date.UTC(ReturnDate.getFullYear(),
                                    ReturnDate.getMonth(),
                                    ReturnDate.getDate());
                        
    // first of all add the mark to the
    // timespan in the outward flight calendar
    var CurrentCellName; var CurrentCellObj;
    var CurrentCellDate; var CurrentCellTimestamp;
    for(var gc=0; gc<2; gc++){
        for(var c=0; c<42; c++){
            CurrentCellName = "gwCalendar_" + gc + "_cell" + c;
            CurrentCellObj = document.getElementById(CurrentCellName);
            
            // check that this cell really exists
            if(CurrentCellObj){
                CurrentCellDate = gwDynFareCalendar[gc].getDateByCellId(CurrentCellName);
                CurrentCellTimestamp = Date.UTC(CurrentCellDate.getFullYear(),
                                        CurrentCellDate.getMonth(),
                                        CurrentCellDate.getDate());
                                        
                // verify that the date is in the timeframe
                if(OutwardTimestamp<=CurrentCellTimestamp
                    && ReturnTimestamp>=CurrentCellTimestamp){
                    // dont mark the selected dates, they have their own mark
                    if(CurrentCellObj.className.indexOf("selectable")>0){
                        // mark the selectable cells only
                        CurrentCellObj.style.backgroundColor = "#fffbcc";
                    }
                }else{
                    // reset it, when its not in the timeframe
                    if(CurrentCellObj.className.indexOf("selectable")>0){
                        // this is valid, reset it now
                        CurrentCellObj.style.backgroundColor = "#ffffff";
                    }
                }
                
                // set the select-background for the selected cell,
                // but once again only if its selectable (cross-month border!)
                if(CurrentCellObj.className.indexOf("selectable")>0){
                    if(gc==0&&OutwardTimestamp==CurrentCellTimestamp){
                        CurrentCellObj.style.backgroundColor = "#ffec00";
                    }if(gc==1&&ReturnTimestamp==CurrentCellTimestamp){
                        CurrentCellObj.style.backgroundColor = "#ffec00";
                    }
                }
            }
        }
    }
    
    ShowTotalPriceOut();
    ShowTotalPriceIn();
}


/*
Name: TranslateCalendar
Input: reference to the active ycalendar object
Desc: defines the calendar's base properties
*/
function TranslateCalendar(CalendarObject, culture){
  var cult = culture || 'de-DE';
  
  // define the calendars configuration properties
	CalendarObject.cfg.setProperty("DATE_FIELD_DELIMITER", ".");

    CalendarObject.cfg.setProperty("START_WEEKDAY", 1);
	CalendarObject.cfg.setProperty("MDY_DAY_POSITION", 1);
	CalendarObject.cfg.setProperty("MDY_MONTH_POSITION", 2);
	CalendarObject.cfg.setProperty("MDY_YEAR_POSITION", 3);

	CalendarObject.cfg.setProperty("MD_DAY_POSITION", 1);
	CalendarObject.cfg.setProperty("MD_MONTH_POSITION", 2);
	CalendarObject.cfg.setProperty("HIDE_BLANK_WEEKS",false);

	// add the labels for the weekdays - use the localization here also!
	CalendarObject.cfg.setProperty("WEEKDAYS_SHORT", 
        ["<img src='/images/lowfarecalendar/" + cult + "/weekday_sunday.jpg' alt='Sunday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_monday.jpg' alt='Monday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_tuesday.jpg' alt='Tuesday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_wednesday.jpg' alt='Wednesday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_thursday.jpg' alt='Thursday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_friday.jpg' alt='Friday' />", 
        "<img src='/images/lowfarecalendar/" + cult + "/weekday_saturday.jpg' alt='Saturday' />"]);
        
	if(IsCMSEditMode){
 	  CalendarObject.cfg.setProperty("WEEKDAYS_SHORT", 
        ["<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_sunday.jpg' alt='Sunday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_monday.jpg' alt='Monday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_tuesday.jpg' alt='Tuesday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_wednesday.jpg' alt='Wednesday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_thursday.jpg' alt='Thursday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_friday.jpg' alt='Friday' />", 
        "<img src='http://192.168.43.100/images/lowfarecalendar/" + cult + "/weekday_saturday.jpg' alt='Saturday' />"]); 
  }
}

var error_code = "";

function ShowTotalPriceOut()
{
    var OutwardDate = gwDynFareCalendar[0].getSelectedDates()[0];

	if (!OutwardDate)
	{
		return;
	}

	error_code = "";
    
	var URL = "/skysales/LowFareCalendarGrossRequest.aspx";
	
	var params = "DAY=" + OutwardDate.getDate()
				+ "&MONTH=" + (OutwardDate.getMonth() + 1)
				+ "&YEAR=" + OutwardDate.getFullYear()
				+ "&REQTYPE=Outward";

	new Ajax.Request(URL,
		{
			parameters: params,
			onLoading: function() {},
			onSuccess: function(transport) {RenderGrossPrice(transport, "outward");},
			onFailure: function() {ShowGrossError("outward");},
			onException: function() {ShowGrossError("outward");},
			onComplete: function() {} 
		}
    );
}

function ShowTotalPriceIn()
{
    var ReturnDate = gwDynFareCalendar[1].getSelectedDates()[0];

	if (!ReturnDate)
	{
		return;
	}
    
	var URL = "/skysales/LowFareCalendarGrossRequest.aspx";
	
	var params = "DAY=" + ReturnDate.getDate()
				+ "&MONTH=" + (ReturnDate.getMonth() + 1)
				+ "&YEAR=" + ReturnDate.getFullYear()
				+ "&REQTYPE=Return";

	new Ajax.Request(URL,
		{
			parameters: params,
			onLoading: function() {},
			onSuccess: function(transport) {RenderGrossPrice(transport, "return");},
			onFailure: function() {ShowGrossError("return");},
			onException: function() {ShowGrossError("return");},
			onComplete: function() {} 
		}
    );
}

function RenderGrossPrice(transport, trip_direction)
{
    var localCurrency = "EUR";
    var grossPrice = "-- " + localCurrency;
    var farePrice =  "-- " + localCurrency;
    var charges = new Array();
    var chargeNames = new Array();

	if ( error_code != "outward" )
	{
		document.getElementById("gross_price_error_panel").style.display = "none";
		error_code = "";
	}

	if ( !transport || !transport.responseXML || transport.responseXML.childNodes[0].childNodes[0].childNodes[0].nodeValue == "" || transport.responseXML.childNodes[0].childNodes[0].childNodes[0].nodeValue == "0,00" )
	{
		ShowGrossError(trip_direction);
		return;
	}

    for ( var i = 0; i < transport.responseXML.childNodes[0].childNodes.length; i++ )
    {
        if ( transport.responseXML.childNodes[0].childNodes[ i ].nodeName == "GROSSPRICE" )
        {
            grossPrice = transport.responseXML.childNodes[0].childNodes[ i ].childNodes[0].nodeValue + " " + localCurrency;
        }
        else if ( transport.responseXML.childNodes[0].childNodes[ i ].nodeName == "FAREPRICE" )
        {
            farePrice = transport.responseXML.childNodes[0].childNodes[ i ].attributes[0].nodeValue + " " + localCurrency;
        }
        else //service charges
        {
            chargeNames.push( eval("fee" + transport.responseXML.childNodes[0].childNodes[ i ].attributes[0].nodeValue) );
            charges.push( transport.responseXML.childNodes[0].childNodes[ i ].attributes[1].nodeValue + " " + localCurrency );
        }
    }

    if ( transport.responseXML.childNodes[0].childNodes[0].childNodes[0].nodeValue == "-1,00" )
	{
	    if (trip_direction == "outward")
	    {
            WriteHTMLSegment(true, farePrice, "-- EUR", null, null, labelOutwardFlight, $("priceOutBox"));
	    }
	    else
	    {
            WriteHTMLSegment(true, farePrice, "-- EUR", null, null, labelReturnFlight, $("priceInBox"));
	    }
	}
	else
	{
	    if (trip_direction == "outward")
	    {
            WriteHTMLSegment(false, farePrice, grossPrice, charges, chargeNames, labelOutwardFlight, $("priceOutBox"));
	    }
	    else
	    {
            WriteHTMLSegment(false, farePrice, grossPrice, charges, chargeNames, labelReturnFlight, $("priceInBox"));
	    }
	}
	
	if (trip_direction == "outward")
	{
	    grossPriceOutward = grossPrice.replace(/EUR/g, "");
	    grossPriceOutward = grossPriceOutward.replace(/\-1\,00/g, "0.00");
	    grossPriceOutward = grossPriceOutward.replace(/\,/g, ".");
	    grossPriceOutward = parseFloat(grossPriceOutward);
	}
	else
	{
	    grossPriceReturn = grossPrice.replace(/EUR/g, "");
	    grossPriceReturn = grossPriceReturn.replace(/\-1\,00/g, "0.00");
	    grossPriceReturn = grossPriceReturn.replace(/\,/g, ".");
	    grossPriceReturn = parseFloat(grossPriceReturn);
	}
	
	WriteHTMLTotalPrice();
}

function WriteHTMLTotalPrice()
{
    var totalPricePosition = 0.00;
    
    totalPricePosition = grossPriceOutward + grossPriceReturn;
    totalPricePosition = totalPricePosition.toFixed(2);
    totalPricePosition = String(totalPricePosition);
    totalPricePosition = totalPricePosition.replace(/\./g, ",");
    
    $("GrossTotalPricePosition").innerHTML = labelTotalPrice + " " + totalPricePosition + " EUR";
}

function WriteHTMLSegment(isEmpty, farePrice, grossPrice, charges, chargeNames, tripDirection, targetElement)
{
    var innerHTMLSegment = "";

    innerHTMLSegment += "<table cellspacing=\"0\" cellpadding=\"0\">"
                     + "<tbody><tr><td><strong style=\"font-size: 12px;\">"
                     + tripDirection
                     + "</strong></td><td style=\"width: 25px;\"></td><td></td></tr>"
                     + "<tr><td style=\"height: 15px;\" colspan=\"3\"/></tr><tr><td><span style=\"font-size: 12px;\">"
                     + labelFarePrice
                     + "</span></td><td style=\"width: 25px;\"></td><td style=\"text-align: right;\"><span style=\"color:#76003D;\">"
                     + farePrice
                     + "</span></td></tr><tr><td style=\"height: 15px;\" colspan=\"3\"></td></tr>"
                     + "<tr><td><span style=\"font-size: 12px;\">"
                     + labelFeesAndTaxes
                     + "</span></td><td style=\"width: 35px;\"></td><td></td></tr>"
                     + RenderFeesAndTaxes(charges, chargeNames)
                     + "<tr><td style=\"height: 15px;\" colspan=\"3\"/></tr><tr><td><strong style=\"font-size: 12px;\">"
                     + labelGrossPrice
                     + "</strong></td><td style=\"width: 35px;\"></td><td><strong style=\"color:#76003D;\">"
                     + grossPrice
                     + "</strong></td></tr>"
                     + "</tbody>"
                     + "</table>";
                     
    targetElement.innerHTML = innerHTMLSegment;
}

function RenderFeesAndTaxes(charges, chargeNames)
{
    var result = "<tr><td style=\"height: 5px;\" colspan=\"3\"/></tr>";

    if (!charges || !chargeNames || charges.length == 0 || chargeNames.length == 0)
    {
        result += "<tr><td colspan=\"3\"><span style=\"font-size: 10px;\">&nbsp;&nbsp;--</span></td></tr>";
    }
    else
    {
        for (var i = 0; i < chargeNames.length; i++)
        {
            result += "<tr><td><span style=\"font-size: 10px;\">"
                   + "&nbsp;&nbsp;"
                   + chargeNames[i] + ":"
                   + "</span></td><td style=\"width: 25px;\"></td><td style=\"text-align: right;\"><span style=\"color:#76003D;\">"
                   + charges[i]
                   + "</span></td></tr>";
        }
    }
    
    return result;
}

function ShowGrossError(trip_direction)
{
	if (trip_direction == "outward")
	{
		document.getElementById("gross_price_error_panel").style.display = "block";
		error_code = "outward";
        WriteHTMLSegment(true, "-- EUR", "-- EUR", null, null, labelOutwardFlight, $("priceOutBox"));
	}
	else
	{
		document.getElementById("gross_price_error_panel").style.display = "block";
		error_code = "return";
        WriteHTMLSegment(true, "-- EUR", "-- EUR", null, null, labelReturnFlight, $("priceInBox"));
	}
}
