﻿if (!window.BlueHolidays)
	window.BlueHolidays = {};

BlueHolidays.Page = function() 
{
}

BlueHolidays.Page.prototype =
{
    kayakKey: null,
    airlineCollection: null,
    airportCollection: null,
    restProxyUrl: "/ProxyImpl.asmx/callProxy?url=",
    useRestProxy: false, // set to true if you wish to test Kayak real-time connectivity
    listBoxes: [],
    scrollPanes: [],
    flightSearchTextBoxes: [],
    calendars: [],
    // basket:
    basket: null,
    // drop rectangles:
    flightDropRect: null,
    hotelDropRect: null,
    carDropRect: null,
    
    handleResize: function()
    {
        for (var i=0; i<this.flightSearchTextBoxes.length; i++)
            this.flightSearchTextBoxes[i].updateLayout();
    },
    
	handleLoad: function(control, userContext, rootElement) 
	{
	    // to have the access from HTML:
	    window.__instance = this;
		this.control = control;
		this.rootElement = rootElement;
		this.basket = new Entities.Basket();
		this.createRESTProxyUrl();
	},
	createRESTProxyUrl: function()
	{
	    // construct the URL for ProxyImpl.asmx
	    var locationString = ""+document.location;
		if (locationString.indexOf("/index.html"))
		    locationString = locationString.substring(0,locationString.indexOf("/index.html"));
		this.restProxyUrl = locationString + this.restProxyUrl;
		// run 1st configuration step:
		this.createAccordionHeadersListeners();
	},
	createAccordionHeadersListeners: function()
	{
	    var items = [
	        {
	            element: "travelData",
	            events: {
	                MouseEnter: Silverlight.createDelegate(this, this.onTravelDataMouseOver),
	                MouseLeave: Silverlight.createDelegate(this, this.onTravelDataMouseOut),
	                MouseLeftButtonUp: Silverlight.createDelegate(this, this.onTravelDataClicked)
	            }
	        },
	        {
	            element: "chooseFlight",
	            events: {
	                MouseEnter: Silverlight.createDelegate(this, this.onChooseFlightMouseOver),
	                MouseLeave: Silverlight.createDelegate(this, this.onChooseFlightMouseOut),
	                MouseLeftButtonUp: Silverlight.createDelegate(this, this.onChooseFlightClicked)
	            }
	        },
	        {
	            element: "chooseHotel",
	            events: {
	                MouseEnter: Silverlight.createDelegate(this, this.onChooseHotelMouseOver),
	                MouseLeave: Silverlight.createDelegate(this, this.onChooseHotelMouseOut),
	                MouseLeftButtonUp: Silverlight.createDelegate(this, this.onChooseHotelClicked)
	            }
	        },
	        {
	            element: "chooseCar",
	            events: {
	                MouseEnter: Silverlight.createDelegate(this, this.onChooseCarMouseOver),
	                MouseLeave: Silverlight.createDelegate(this, this.onChooseCarMouseOut),
	                MouseLeftButtonUp: Silverlight.createDelegate(this, this.onChooseCarClicked)
	            }
	        }
	    ];
	    for ( var i=0; i<items.length; i++ )
	    {
	        for ( var key in items[i].events )
	            this.control.content.root.FindName( items[i].element+"Button" ).addEventListener(key, items[i].events[key]);
	    }
	    this.onAccordionTabChanged("travel");
	    this.initializeProgressBar();
	    this.calculateDropRegions();
	},
	initializeProgressBar: function()
	{
	    var pbST = this.control.content.root.FindName("ProgressBarWork");
	    pbST.addEventListener("Completed", Silverlight.createDelegate(this, this.onProgressBarWorkCompleted));
	    this.progressBarStop();
	    this.chainCommonLoad();
	},
	
	calculateDropRegions: function()
	{
	    // flight drop:
	    var fda = this.control.content.root.FindName("dropFlight");
		var pos = this.getAbsolutePosition( fda );
		this.flightDropRect = new Graphics.Rectangle( pos.X, pos.Y, fda.Width, fda.Height );
        // hotel drop:
        var hda = this.control.content.root.FindName("dropHotel");
		pos = this.getAbsolutePosition( hda );
		this.hotelDropRect = new Graphics.Rectangle( pos.X, pos.Y, hda.Width, hda.Height );
        // car drop:
        var cda = this.control.content.root.FindName("dropCar");
		pos = this.getAbsolutePosition( cda );
		this.carDropRect = new Graphics.Rectangle( pos.X, pos.Y, cda.Width, cda.Height );
	},
	
	onProgressBarWorkCompleted: function( sender, eventArgs )
	{
	    var pbST = this.control.content.root.FindName("ProgressBarWork");
	    pbST.Seek("0:0:0");
	    pbST.Begin();
	},
	progressBarStart: function()
	{
	    // change the cursor:
	    this.control.content.root.FindName("progressBar").Cursor = "Wait";
	    // get scroller ref:
	    var pbST = this.control.content.root.FindName("ProgressBarWork");
	    pbST.Seek("0:0:0");
	    pbST.Begin();
	},
	progressBarStop: function()
	{
	    // change the cursor:
	    this.control.content.root.FindName("progressBar").Cursor = "Arrow";
	    // get scroller ref:
	    var pbST = this.control.content.root.FindName("ProgressBarWork");
	    pbST.Stop();
	    pbST.Seek("0:0:0");
	},
	
	onTravelDataMouseOver: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("TravelDataMouseOver").Begin();
	},
	onTravelDataMouseOut: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("TravelDataMouseOut").Begin();
	},
	onTravelDataClicked: function( sender, eventArgs )
	{
	    // if other tabs are visible we have to hide them:
	    var tb2 = this.control.content.root.FindName("chooseFlight");
	    var tb3 = this.control.content.root.FindName("chooseHotel");
	    var tb4 = this.control.content.root.FindName("chooseCar");
	    if ( tb2.Tag+"" == "1" )
	    {
	        tb2.Tag = "0";
	        this.control.content.root.FindName("ChooseFlightSlideOut").Begin();
	    }
	    if ( tb3.Tag+"" == "1" )
	    {
	        tb3.Tag = "0";
	        this.control.content.root.FindName("ChooseHotelSlideOut").Begin();
	    }
	    if ( tb4.Tag+"" == "1" )
	    {
	        tb4.Tag = "0";
	        this.control.content.root.FindName("ChooseCarSlideOut").Begin();
	    }
	    this.onAccordionTabChanged("travel");
	},
	
	onChooseFlightMouseOver: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseFlightMouseOver").Begin();
	},
	onChooseFlightMouseOut: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseFlightMouseOut").Begin();
	},
	onChooseFlightClicked: function( sender, eventArgs )
	{
	    var __self = this.control.content.root.FindName("chooseFlight");
	    if ( __self.Tag+"" == "0" )
	    {
	        this.control.content.root.FindName("ChooseFlightSlideIn").Begin();
	        __self.Tag = "1";
	    }
	    else if ( __self.Tag+"" == "1" )
	    {
	        // is expanded: check if other tabs aren't hiding this one...
	        var tb3 = this.control.content.root.FindName("chooseHotel");
	        if ( tb3.Tag+"" == "1" )
	        {
	            this.control.content.root.FindName("ChooseHotelSlideOut").Begin();
	            tb3.Tag = "0";
	        }
	        var tb4 = this.control.content.root.FindName("chooseCar");
	        if ( tb4.Tag+"" == "1" )
	        {
	            this.control.content.root.FindName("ChooseCarSlideOut").Begin();
	            tb4.Tag = "0";
	        }
	    }
	    this.onAccordionTabChanged("chooseFlight");
	},
	
	onChooseHotelMouseOver: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseHotelMouseOver").Begin();
	},
	onChooseHotelMouseOut: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseHotelMouseOut").Begin();
	},
	onChooseHotelClicked: function( sender, eventArgs )
	{
	    var __self = this.control.content.root.FindName("chooseHotel");
	    if ( __self.Tag+"" == "0" )
	    {
	        // not expanded:
	        // check if prev tab is expanded:
	        var tb2 = this.control.content.root.FindName("chooseFlight");
	        if ( tb2.Tag+"" == "0" )
	        {
	            this.control.content.root.FindName("ChooseFlightSlideIn").Begin();
	            tb2.Tag = "1";
	        }
	        this.control.content.root.FindName("ChooseHotelSlideIn").Begin();
	        __self.Tag = "1";
	    }
	    else if ( __self.Tag+"" == "1" )
	    {
	        // is expanded: check if other tabs aren't hiding this one...
	        var tb4 = this.control.content.root.FindName("chooseCar");
	        if ( tb4.Tag+"" == "1" )
	        {
	            this.control.content.root.FindName("ChooseCarSlideOut").Begin();
	            tb4.Tag = "0";
	        }
	    }
	    this.onAccordionTabChanged("chooseHotel");
	},
	
	onChooseCarMouseOver: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseCarMouseOver").Begin();
	},
	onChooseCarMouseOut: function( sender, eventArgs )
	{
	    this.control.content.root.FindName("ChooseCarMouseOut").Begin();
	},
	onChooseCarClicked: function( sender, eventArgs )
	{
	    var __self = this.control.content.root.FindName("chooseCar");
	    if ( __self.Tag+"" == "0" )
	    {
	        // not expanded:
	        // check if prev tab is expanded:
	        var tb2 = this.control.content.root.FindName("chooseFlight");
	        if ( tb2.Tag+"" == "0" )
	        {
	            this.control.content.root.FindName("ChooseFlightSlideIn").Begin();
	            tb2.Tag = "1";
	        }
	        var tb3 = this.control.content.root.FindName("chooseHotel");
	        if ( tb3.Tag+"" == "0" )
	        {
	            this.control.content.root.FindName("ChooseHotelSlideIn").Begin();
	            tb3.Tag = "1";
	        }
	        
	        this.control.content.root.FindName("ChooseCarSlideIn").Begin();
	        __self.Tag = "1";
	    }
	    this.onAccordionTabChanged("chooseCar");
	},
	onAccordionTabChanged: function( tabId )
	{
	    var tabs = [
	        this.control.content.root.FindName("travelDataInner"),
	        this.control.content.root.FindName("chooseFlightDataInner"),
	        this.control.content.root.FindName("chooseHotelDataInner"),
	        this.control.content.root.FindName("chooseCarDataInner")
	    ];
	    for ( var i=0; i<tabs.length; i++ )
	        tabs[i].Visibility = "Collapsed";
	    this.control.content.root.FindName(tabId+"DataInner").Visibility = "Visible";
	    // if tab shown isn't travelData we need to hide textboxes:
   	    for ( var j=0; j<this.flightSearchTextBoxes.length; j++ )
   	    {
   	        this.flightSearchTextBoxes[j].set_inputVisible( tabId == "travel" );
   	        this.flightSearchTextBoxes[j].invalidateLayout();
   	    }
	},
	
	chainCommonLoad: function()
	{
	    this.renderersRegistry = new Utils.RenderersRegistry( this.control, this.rootElement );
        
	    // start progress bar:
	    this.progressBarStart();
	    // start loading:
	    var downloader = this.control.createObject("downloader");
	    downloader.addEventListener("Completed", Silverlight.createDelegate(this, this.onAirlinesLoaded));
	    downloader.open("GET", "common/airlines.txt");
	    downloader.send();
	},
	onAirlinesLoaded: function( sender, eventArgs )
	{
	    // store airlines:
	    this.airlineCollection = new Utils.AirlineCollection( sender.getResponseText("") );
	    // load airports:
	    var downloader = this.control.createObject("downloader");
	    downloader.addEventListener("Completed", Silverlight.createDelegate(this, this.onAirportsLoaded));
	    downloader.open("GET", "common/airports.txt");
	    downloader.send();
	},
	onAirportsLoaded: function(sender, eventArgs)
	{
	    // store airports:
	    this.airportCollection = new Utils.AirportCollection( sender.getResponseText("") );
	    // load Kayak key:
	    var downloader = this.control.createObject("downloader");
	    downloader.addEventListener("Completed", Silverlight.createDelegate(this, this.onKayakKeyLoaded));
	    downloader.open("GET", "common/kayakKey.txt");
	    downloader.send();
	},
	
	onKayakKeyLoaded: function(sender, eventArgs)
	{
	    this.kayakKey = new Entities.KayakKey( sender.getResponseText("") );
	    
        // instantiate Jamie Rodriguez controls:
		var app = new SLx.Application ( this.control );
		this._openloaders = [];
		var  ldr = new SLx.ResourceDownloader ();
		ldr.StartDownload ( SLx.Constants.makePackagePath ( "theme" ), $delegate( this, this._onCompletedAll ));
		Array.add ( this._openloaders, ldr );
		window.setTimeout ( $delegate( this, this._init ), 500);
	},
	
	doComplete: function()
	{
	    // this function is called after all controls are downloaded;
	    // here we can start displaying controls:
	    // load list box:
	    var downloader = this.control.createObject("downloader");
	    downloader.addEventListener("Completed", Silverlight.createDelegate(this, this.onListBoxLoaded));
	    downloader.open("GET", "Controls/ListBox.xaml");
	    downloader.send();
	},
	
	onListBoxLoaded: function( sender, eventArgs )
	{
	    var menuItems = [ this.control.content.FindName("chooseFlightDataInner"), this.control.content.FindName("chooseHotelDataInner"), this.control.content.FindName("chooseCarDataInner") ];
	    for ( var i=0; i<menuItems.length; i++ )
	    {
	        var lb = this.control.content.createFromXaml(sender.getResponseText(""), true);
	        var scv =  SLx.ControlFactory.ScrollViewer ();
	        scv.get_content().set_visual( lb );
	        SLx.VisualTreeHelper.reParent ( lb , scv.get_content().get_visual() );
            scv.set_clipToBounds( true );
            scv._horizontalScrollbar.set_visible( false );
            scv.set_size ( 500, 312 );
	        scv.set_left(23);
	        scv.set_top(40);
	        menuItems[i].children.add( scv.get_visual() );
	        scv.invalidateLayout();
	        this.scrollPanes[ this.scrollPanes.length ]  = scv;
	        this.listBoxes[ this.listBoxes.length ] = lb;
	    }
	    this.constructSearchButton();
	    this.constructTextBoxes();
	    this.constructDatePickers();
        // stop progress bar:
	    this.progressBarStop();
	},
	
	constructSearchButton: function()
	{
	    var btn = new SLx.Button (
	        null,
	        SLx.Application.Current.get_resources().findName("button_search"), 
	        [{ name : "button_dosearch" , ref : "_visualElement", type : "element" }]
	    ); 
        btn.move ( 300, 210 );
        btn.add_Click ( Silverlight.createDelegate ( this , this.onDoSearch ));
        this.control.content.FindName("travelDataInner").children.add( btn.get_visual() );
	},
	
	constructTextBoxes: function()
	{
	    var  edit = SLx.ControlFactory.TextEdit(); 
	    edit.set_inputVisible( true ); 
        edit.set_text("London"); 
        edit.move ( 210, 50 );
        edit.set_width( 200 ); 
        edit.updateLayout();
        this.flightSearchTextBoxes.push(edit);
        var  edit2 = SLx.ControlFactory.TextEdit(); 
	    edit2.set_inputVisible( true ); 
        edit2.set_text("Seattle"); 
        edit2.move ( 210, 72 );
        edit2.set_width( 200 ); 
        edit2.updateLayout();
        this.flightSearchTextBoxes.push(edit2);
        var  edit3 =  SLx.ControlFactory.TextEdit(); 
	    edit3.set_inputVisible( true ); 
        edit3.set_text( this.getFormattedDate( new Date() ) ); 
        edit3.move ( 210, 94 );
        edit3.set_width( 150 ); 
        edit3.updateLayout();
        this.flightSearchTextBoxes.push(edit3);
        var  edit4 =  SLx.ControlFactory.TextEdit(); 
	    edit4.set_inputVisible( true ); 
	    edit4.set_text( this.getFormattedDate( new Date() ) ); 
        edit4.move ( 210, 116 );
        edit4.set_width( 150 ); 
        edit4.updateLayout();
        this.flightSearchTextBoxes.push(edit4);
        var  edit5 =  SLx.ControlFactory.TextEdit(); 
	    edit5.set_inputVisible( true ); 
	    edit5.set_text( 1 ); 
        edit5.move ( 210, 138 );
        edit5.set_width( 50 ); 
        edit5.updateLayout();
        this.flightSearchTextBoxes.push(edit5);
	},
	
	constructDatePickers: function()
	{
	    var btn1 = new SLx.Button ( this.control.content.FindName("dPickerBtn1") );
        btn1.add_Click( Silverlight.createDelegate ( this , this.onDatePickerButtonClick ));
        var btn2 = new SLx.Button ( this.control.content.FindName("dPickerBtn2") );
        btn2.add_Click( Silverlight.createDelegate ( this , this.onDatePickerButtonClick ));
        
        // calendars:
        var cal = SLx.ControlFactory.Calendar();
        cal.setDate( new Date () ) ; 
        cal.add_dateSelectionChanged ( $delegate ( this, this.onDateChanged ));
        cal.set_visible( false );
        this.calendars[0] = cal;
        cal.get_visual()["Canvas.ZIndex"] = 30; 
        this.control.content.root.children.add( cal.get_visual() );
        cal.move( 395, 94 );
        cal.myName = "dateDepart";
        
        var cal2 = SLx.ControlFactory.Calendar();
        cal2.setDate( new Date() ) ; 
        cal2.add_dateSelectionChanged ( $delegate ( this, this.onDateChanged ));
        cal2.set_visible( false );
        this.calendars[1] = cal2;
        cal2.get_visual()["Canvas.ZIndex"] = 31; 
        this.control.content.root.children.add( cal2.get_visual() );
        cal2.move( 395, 116 );
        cal2.myName = "dateArrive";
	},
    
    onDateChanged: function( sender, eventArgs )
	{
	    switch( sender.myName )
	    {
	        case "dateDepart":
	            this.calendars[0].set_visible(false);
	            this.flightSearchTextBoxes[2].set_text( this.getFormattedDate( sender._date ) );
	            break;
	        case "dateArrive":
	            this.calendars[1].set_visible(false);
	            this.flightSearchTextBoxes[3].set_text( this.getFormattedDate( sender._date ) );
	            break;
	    }
	},
	onDatePickerButtonClick: function ( sender , args ) 
	{
	    switch ( sender.get_visual().Name )
	    {
	        case "dPickerBtn1":
	            this.calendars[1].set_visible(false);
	            this.calendars[0].set_visible( !this.calendars[0].get_visible() );
	            break;
	        case "dPickerBtn2":
	            this.calendars[0].set_visible(false);
	            this.calendars[1].set_visible( !this.calendars[1].get_visible() );
	            break;
	    }
	},

    
    onDoSearch: function(sender, eventArgs)
    {
        // this function runs our search...
        this.progressBarStart();
        this.doKayakFlightSearch();
    },
    onSearchFinished: function()
    {
        this.progressBarStop();
    },
    
    doKayakFlightSearch: function()
    {
        // construct search arguments:
        var departPlace = this.airportCollection.lookupAirport( this.flightSearchTextBoxes[0].get_text() );
	    var arrivePlace = this.airportCollection.lookupAirport( this.flightSearchTextBoxes[1].get_text() );
        // execute flight search:
	    var response = new Array();
	    response['c'] = 10;
	    var params = new Array();
	    params['oneway'] = "n";
	    params['origin'] = departPlace.getCode();
	    params['destination'] = arrivePlace.getCode();
	    params['destcode'] = "";
	    params['depart_date'] = this.flightSearchTextBoxes[2].get_text();
	    params['depart_time'] = "l";
	    params['return_date'] = this.flightSearchTextBoxes[3].get_text();
	    params['return_time'] = "a";
	    params['travelers'] = this.flightSearchTextBoxes[4].get_text();
	    params['cabin'] = "e";
	    params['action'] = "doflights";
	    params['apimode'] = 1;
	    new Net.KayakFlightSearch( params, response, this.kayakKey.getKey(), this );
    },
    doKayakHotelSearch: function()
    {
        // execute hotels search:
        var response = new Array();
	    response['c'] = 10;
        var params = new Array();
	    params['othercity'] = this.flightSearchTextBoxes[1].get_text();
	    params['checkin_date'] = this.flightSearchTextBoxes[2].get_text();
	    params['checkout_date'] = this.flightSearchTextBoxes[3].get_text();
	    params['guests1'] = this.flightSearchTextBoxes[4].get_text();
	    params['rooms'] = 1;
	    new Net.KayakHotelSearch( params, response, this.kayakKey.getKey(), this );
    },
    
    // ---------------------------------------
    // HANDLING THE RESULT HERE: -------------
    // ---------------------------------------
	onResult: function( items, type )
	{
	    //this.soundPlayer.FindName("SoundPlayback").Play();
	    var lb = null;
	    var finalIndex = null;
	    var pos = 0;
	    var i = 0;
	    var renderer = null;
	    
	    switch ( type )
	    {
	        case "flights":
	            
	            lb = this.listBoxes[0];
	            lb.children.Clear();
	            pos = 0;
	            finalIndex = ( ( items.length < 30 ) ? items.length : 30 );
	            
	            for ( i=0; i<finalIndex; i++ )
	            {
	                renderer = this.renderersRegistry.getAirlineRenderer();
	                renderer["Canvas.Top"] = pos;
	                renderer.FindName("AirlineLogo").addEventListener( "ImageFailed", Silverlight.createDelegate(this, this.onFlightImageFailed) );
	                renderer.FindName("AirlineLogo").Source = "images/airline_logos/unknown.png";
	                
	                renderer.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.onRendererMouseDown));
	                renderer.addEventListener("MouseLeftButtonUp", Silverlight.createDelegate(this, this.onRendererMouseUp));
	                renderer.addEventListener("MouseMove", Silverlight.createDelegate(this, this.onRendererMouseMove));
	                renderer.Tag = (new Utils.Serialization()).serialize( items[i] );
	                
	                lb.children.add( renderer );
	                
	                // time to set text values:
	                var ptb = renderer.FindName("PriceTextBox");
	                // one way:
	                var d1tb = renderer.FindName("Details1TextBox");
	                var d2tb = renderer.FindName("Details2TextBox");
	                var todtb = renderer.FindName("TimeOutDepartTextBox");
	                var toatb = renderer.FindName("TimeOutArriveTextBox");
	                
	                if ( items[i].getLegs().length > 0 )
	                {
	                    var leg1 = items[i].getLegs()[0];
	                    renderer.FindName("AirlineLogo").Source = "images/airline_logos/" + leg1.airline + ".png";
	                    d1tb.Text = leg1.getStops() + " stop(s); dur.: " + this.getCorrectDuration( parseInt(leg1.getDuration()) );
	                    todtb.Text = "D: " + leg1.getDepart();
	                    toatb.Text = "A: " + leg1.getArrive();
	                }
	                // two ways:
	                var tbdtb = renderer.FindName("TimeBackDepartTextBox");
	                var tbatb = renderer.FindName("TimeBackArriveTextBox");
	                if ( items[i].getLegs().length > 1 )
	                {
	                    var leg2 = items[i].getLegs()[1];
	                    d2tb.Text = leg2.getStops() + " stop(s); dur.: " + this.getCorrectDuration( parseInt(leg2.getDuration()) );
	                    tbdtb.Text = "D: " + leg2.getDepart();
	                    tbatb.Text = "A: " + leg2.getArrive();
	                }
	                ptb.Text = "$" + items[i].getPrice() + " (per person)";
	                pos += 60;
	            }
	            
	            lb.Height = pos;
	            this.scrollPanes[0].invalidateLayout();
	            
	            this.doKayakHotelSearch();
	            
	            break;
	        case "hotels":
	            
	            lb = this.listBoxes[1];
	            lb.children.Clear();
	            pos = 0;
	            finalIndex = ( ( items.length < 30 ) ? items.length : 30 );
	            
	            for ( i=0; i<finalIndex; i++ )
	            {
	                renderer = this.renderersRegistry.getHotelRenderer();
	                renderer["Canvas.Top"] = pos;
	                
	                renderer.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.onRendererMouseDown));
	                renderer.addEventListener("MouseLeftButtonUp", Silverlight.createDelegate(this, this.onRendererMouseUp));
	                renderer.addEventListener("MouseMove", Silverlight.createDelegate(this, this.onRendererMouseMove));
	                renderer.Tag = (new Utils.Serialization()).serialize( items[i] );
	                
	                lb.children.add( renderer );
	                
	                var ntb = renderer.FindName("NameTextBox");
	                var atb = renderer.FindName("AddressTextBox");
	                var phtb = renderer.FindName("PhoneTextBox");
	                
	                ntb.Text = items[i].getPrice() + " per night: " + items[i].getName();
	                atb.Text = items[i].getCity() + ((items[i].getAddress()=="") ? ", address unknown" : ", " + items[i].getAddress());
	                phtb.Text = (items[i].getPhone()=="") ? "N/A" : items[i].getPhone();
	                
	                for ( var j=1; j<=5; j++ )
                        renderer.FindName("ImageStar"+j).Visibility = (parseInt(items[i].getStars())>(j-1)) ? "Visible" : "Collapsed";
	            
	                pos += 60;
	            }
	            
	            lb.Height = pos;
	            this.scrollPanes[1].invalidateLayout();
	            
	            new Net.CarSearch( this );
	            
	            break;
	        case "cars":
	            
	            lb = this.listBoxes[2];
	            lb.children.Clear();
	            pos = 0;
	            finalIndex = ( ( items.length < 30 ) ? items.length : 30 );
	            
	            for ( i=0; i<finalIndex; i++ )
	            {
	                renderer = this.renderersRegistry.getCarRenderer();
	                renderer["Canvas.Top"] = pos;
	                
	                renderer.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.onRendererMouseDown));
	                renderer.addEventListener("MouseLeftButtonUp", Silverlight.createDelegate(this, this.onRendererMouseUp));
	                renderer.addEventListener("MouseMove", Silverlight.createDelegate(this, this.onRendererMouseMove));
	                renderer.FindName("CarhireLogo").Source = "images/carhire_logos/" + items[i].getCompany() + ".png";
	                renderer.Tag = (new Utils.Serialization()).serialize( items[i] );
	                
	                lb.children.add( renderer );
	                
	                var nntb = renderer.FindName("NameTextBox");
	                var cltb = renderer.FindName("ClassTextBox");
	                
	                nntb.Text = items[i].getPrice() + " per day: " + items[i].getBrand() + " " + items[i].getModel();
	                cltb.Text = "Car class: " + items[i].get_Class();
	                
	                pos += 60;
	            }
	            
	            lb.Height = pos;
	            this.scrollPanes[2].invalidateLayout();
	            
	            this.onSearchFinished();
	            break;
	    }
	},
    
	getCorrectDuration: function( minutes )
	{
	    var hours = Math.floor(minutes/60);
	    var mins  = ((minutes<60) ? minutes : minutes-(hours*60));
	    hours = (((hours+"").length==2) ? hours : "0" + hours );
	    mins  = (((mins+"").length==2) ? mins : "0" + mins );
	    return hours + ":" + mins;
	}, 
	getFormattedDate: function( date )
	{
	    var day = date.getDate();
	    var month = date.getMonth();
	    var year = date.getFullYear();
	    day = ( (""+day).length == 1 ) ? "0"+day : day;
	    month = ( (""+(month+1)).length == 1 ) ? "0"+(month+1) : month+1;
	    return [month,day,year].join("/");
	},
	onFlightImageFailed: function( sender, eventArgs )
	{
	    sender.Source = "images/airline_logos/unknown.png";
	},
	getAbsolutePosition: function( control )
	{
	    var obj = { X:0 , Y:0 };
	    obj.X += control["Canvas.Left"];
	    obj.Y += control["Canvas.Top"];
	    try
	    {
	        var parent = control.getParent();
	        var _obj = this.getAbsolutePosition( parent );
	        obj.X += _obj.X;
	        obj.Y += _obj.Y;
	    } catch (e) {}
	    return obj;
	},
	
	

	
	// Jamie Rodriguez controls code:
	maxDownloadTries: 4,
	_onCompletedAll: function ( sender, args ) 
	{
	    var manifest = null;
	    try 
	    {
	        manifest = sender.getResponseText( "manifest.xaml"); 
	    } catch ( ex ) { }
	    if ( manifest != null )
	    {
	        var files = manifest.split(",");
	        for ( var i = 0 ; i < files.length ; i++ ) 
	        {
	            var name = files[i].trim();
	            var str  = sender.getResponseText ( SLx.Constants.makeXAMLPath ( name )) ;
	            if ( str != null )
	                SLx.Application.Current.get_resources().add ( name ,  str ) ;
            }
	    }
	    else 
	    {
	        var str = sender.getResponseText ( ""); 
	        if  ( str != null ) 
	            SLx.Application.Current.get_resources().add ( SLx.Constants.removeXAMLPath ( sender.URI) ,  str ) ;   
		} 	   	    
	},
	
	_isDownloadComplete: function() 
	{ 
	    var done = true  ; 
	    for ( var x = 0 ; x < this._openloaders ; x++ ) 
	    { 
	        if ( this._openloaders[x].Status != 200 ) 
	        { 
	            done = false; 
	            break ; 
	        } 
	    } 
	    
	    if ( !done ) 
	    { 
	        if ( this._maxDownloadTries > 0 )
	            window.setTimeout ( $delegate( this, this._init) , 300);
	        else 
	            throw alert ( 'download failed') ;
	            
	    }
	    return done ;  	
	},
    _init: function ( sender ,args ) 
	{ 
	    if ( this._isDownloadComplete() )
	    {
	        this.doComplete();
	    }
	},
	
	
	// -------------------------
	// mouse handlers for list boxes renderers:
	onRendererMouseDown: function( sender, eventArgs )
	{
	    sender.captureMouse();
	    this.dragItem = sender;
	},
	onRendererMouseMove: function( sender, eventArgs )
	{
	    if ( this.dragItem != null )
	    {
	        if ( this.dragItemProxy == null )
	        {
	            var dragData = (new Utils.Serialization()).deserialize(sender.Tag);
	            if ( ( new Entities.Trip() ).isTrip( dragData ) )
	            {
    	            this.dragItemProxy = this.renderersRegistry.getAirlineRenderer();
    	            this.prepareDraggedItem_Flight(this.dragItemProxy, sender);
    	        }
    	        else if ( ( new Entities.Hotel() ).isHotel( dragData ) )
    	        {
    	            this.dragItemProxy = this.renderersRegistry.getHotelRenderer();
    	            this.prepareDraggedItem_Hotel(this.dragItemProxy, sender);
    	        }
    	        else if ( ( new Entities.Car() ).isCar( dragData ) )
    	        {
    	            this.dragItemProxy = this.renderersRegistry.getCarRenderer();
    	            this.prepareDraggedItem_Car(this.dragItemProxy, sender);
    	        }
	            this.dragItemProxy["Canvas.ZIndex"] = 99;
	            this.dragItemProxy.Tag = sender.Tag;
	            this.control.content.root.children.add( this.dragItemProxy );
	        }
	        this.dragItemProxy["Canvas.Top"] = eventArgs.GetPosition(this.control.content.root).Y;
	        this.dragItemProxy["Canvas.Left"] = eventArgs.GetPosition(this.control.content.root).X;
	    }
	},
	
	onRendererMouseUp: function( sender, eventArgs )
	{
	    if ( this.dragItemProxy != null )
	    {
	        this.control.content.root.children.remove( this.dragItemProxy );
	        var dragData = ( new Utils.Serialization() ).deserialize( this.dragItemProxy.Tag );
	        // check if the item may be dropped in that place:
	        this.allowDrop = false;
	        if ( ( new Entities.Trip() ).isTrip( dragData ) )
	            this.allowDrop = (
	                this.flightDropRect.hitTest(
	                    new Graphics.Point(
	                        eventArgs.GetPosition(this.control.content.root).X,
	                        eventArgs.GetPosition(this.control.content.root).Y
	                    )
	                )
	            );
	        else if ( ( new Entities.Hotel() ).isHotel( dragData ) )
	            this.allowDrop = (
	                this.hotelDropRect.hitTest(
	                    new Graphics.Point(
	                        eventArgs.GetPosition(this.control.content.root).X,
	                        eventArgs.GetPosition(this.control.content.root).Y
	                    )
	                )
	            );
	        else if ( ( new Entities.Car() ).isCar( dragData ) )
	            this.allowDrop = (
	                this.carDropRect.hitTest(
	                    new Graphics.Point(
	                        eventArgs.GetPosition(this.control.content.root).X,
	                        eventArgs.GetPosition(this.control.content.root).Y
	                    )
	                )
	            );
	        
	        if ( this.allowDrop )
	        {
	            
	            if ( ( new Entities.Trip() ).isTrip( dragData ) )
	            {
	                if ( this.basket.getFlight() != null )
	                {
	                    if ( confirm( "You have flight already in basket. Do you wish to replace it?" ) )
	                    {
	                        this.basket.setFlight( dragData );
    	                    this.onBasketUpdated();
	                    }
	                }
	                else
	                {
    	                this.basket.setFlight( dragData );
    	                this.onBasketUpdated();
    	            }
	            }
	            else if ( ( new Entities.Hotel() ).isHotel( dragData ) )
	            {
	                if ( this.basket.getHotel() != null )
	                {
	                    if ( confirm( "You have hotel already in basket. Do you wish to replace it?" ) )
	                    {
	                        this.basket.setHotel( dragData );
    	                    this.onBasketUpdated();
	                    }
	                }
	                else
	                {
    	                this.basket.setHotel( dragData );
    	                this.onBasketUpdated();
    	            }
	            }
	            else if ( ( new Entities.Car() ).isCar( dragData ) )
	            {
	                if ( this.basket.getCar() != null )
	                {
	                    if ( confirm( "You have car already in basket. Do you wish to replace it?" ) )
	                    {
	                        this.basket.setCar( dragData );
	                        this.onBasketUpdated();
	                    }
	                }
	                else
	                {
    	                this.basket.setCar( dragData );
	                    this.onBasketUpdated();
	                }
	            }
	        }
	        this.dragItemProxy = null;
	    }
	    this.dragItem = null;
	    sender.releaseMouseCapture();
	},
	
	prepareDraggedItem_Flight: function( control, source )
	{
	    var data = (new Utils.Serialization()).deserialize( source.Tag );
	    control.Opacity = 0.5;
	    control.FindName("AirlineLogo").addEventListener( "ImageFailed", Silverlight.createDelegate(this, this.onFlightImageFailed) );
	    control.FindName("AirlineLogo").Source = "images/airline_logos/" + data.legs[0].airline + ".png";
	    // time to set text values:
        var ptb = control.FindName("PriceTextBox");
        // one way:
        var d1tb = control.FindName("Details1TextBox");
        var d2tb = control.FindName("Details2TextBox");
        var todtb = control.FindName("TimeOutDepartTextBox");
        var toatb = control.FindName("TimeOutArriveTextBox");
        if ( data.legs.length > 0 )
        {
            var leg1 = data.legs[0];
            d1tb.Text = leg1.stops + " stop(s); dur.: " + this.getCorrectDuration( parseInt(leg1.duration) );
            todtb.Text = "D: " + leg1.depart;
            toatb.Text = "A: " + leg1.arrive;
        }
        // two ways:
        var tbdtb = control.FindName("TimeBackDepartTextBox");
        var tbatb = control.FindName("TimeBackArriveTextBox");
        if ( data.legs.length > 1 )
        {
            var leg2 = data.legs[1];
            d2tb.Text = leg2.steps + " stop(s); dur.: " + this.getCorrectDuration( parseInt(leg2.duration) );
            tbdtb.Text = "D: " + leg2.depart;
            tbatb.Text = "A: " + leg2.arrive;
        }
        ptb.Text = "$" + data.price + " (per person)";
	},
	
	prepareDraggedItem_Hotel: function( control, source )
	{
	    var data = (new Utils.Serialization()).deserialize( source.Tag );
	    control.Opacity = 0.5;
        var ntb = control.FindName("NameTextBox");
        var atb = control.FindName("AddressTextBox");
        var phtb = control.FindName("PhoneTextBox");
        
        ntb.Text = data.price + " per night: " + data.name;
        atb.Text = data.city + ((data.address=="") ? ", address unknown" : ", " + data.address);
        phtb.Text = (data.phone=="") ? "N/A" : data.phone;
        
        for ( var i=1; i<=5; i++ )
            control.FindName("ImageStar"+i).Visibility = (parseInt(data.stars)>(i-1)) ? "Visible" : "Collapsed";
	},
	
	prepareDraggedItem_Car: function( control, source )
	{
	    var data = (new Utils.Serialization()).deserialize( source.Tag );
	    control.Opacity = 0.5;
        control.FindName("CarhireLogo").Source = "images/carhire_logos/" + data.company + ".png";
        var nntb = control.FindName("NameTextBox");
        var cltb = control.FindName("ClassTextBox");
        nntb.Text = data.price + " per day: " + data.brand + " " + data.model;
        cltb.Text = "Car class: " + data._class;
	},
	
	onBasketUpdated: function( )
	{
	    var totalPrice = 0;
	    var summary = "";
	    
	    if ( this.basket.getFlight() != null )
	    {
	        totalPrice += parseInt(this.basket.getFlight().price);
	        // show flight in basket and display its summary:
	        this.control.content.root.FindName("dropFlightNoSelection").Visibility = "Collapsed";
	        this.control.content.root.FindName("dropFlightSelection").Visibility = "Visible";
	        
	        summary = "Flight from " + this.airportCollection[ this.basket.getFlight().legs[0].orig ].getCity();
	        summary += " to " + this.airportCollection[ this.basket.getFlight().legs[0].dest ].getCity() ;
	        this.control.content.root.FindName("flightSummary").Text = summary;
	    }
	    if ( this.basket.getHotel() != null )
	    {
	        totalPrice += parseInt(this.basket.getHotel().price.replace("$",""));
	        // show hotel in basket and display its summary:
	        this.control.content.root.FindName("dropHotelNoSelection").Visibility = "Collapsed";
	        this.control.content.root.FindName("dropHotelSelection").Visibility = "Visible";
	        
	        summary = "Hotel " + this.basket.getHotel().name + " (" + this.basket.getHotel().price + "/night)";
	        this.control.content.root.FindName("hotelSummary").Text = summary;
	    }
	    if ( this.basket.getCar() != null )
	    {
	        totalPrice += parseInt(this.basket.getCar().price.replace("$",""));
	        // show car in basket and display its summary:
	        this.control.content.root.FindName("dropCarNoSelection").Visibility = "Collapsed";
	        this.control.content.root.FindName("dropCarSelection").Visibility = "Visible";
	        
	        summary = this.basket.getCar().brand + " " + this.basket.getCar().model + " (" + this.basket.getCar().price + "/day)";
	        this.control.content.root.FindName("carSummary").Text = summary;
	    }
	    
	    this.control.content.root.FindName("txtTotalPrice").Text = "$"+totalPrice;
	}

}