/*
    .---------------------------------.
    |    School demonstrator class    |
    *---------------------------------*
    
    Class: School Demonstrator
    	Takes care of displaying the school information received via a JSON package.   
    
    Requires:
        - <utility_functions.js> (in find_period_with_date, slugify)
        - <utility_functions_for_internationalization.js>
		- dojoWrapper
    
    Author: 
        Marko Ristin
    
    Changelog:s
        - 2007/01/27, mristin, initial version
        - 2007/08/15, ahermann, reformatted comments for automatic documentation
        - 2007/11/16, ahermann, adapted to takeoff-english needs
*/
function School_demonstrator(school_id, school_pkg, course_starting_date, HOST_FAMILY_TYPE, initial_tab, url_fetch_school)
{
    /*extern dojo, gettext, date_str_to_dd_mm,find_period_with_date, gettext, is_function, is_array */
    /*extern copy_an_object, add_cell, show_errors, clear_all_rows */
	/*extern date_str_to_i18n_date, date_to_str, intersect_periods_of_owners, create_and_add_option_to_select_box */
    /*extern a_wait_cursor_manager, a_money_exchange */
	/*extern MEDIA_URL */
	/*extern pkg_nationalities */
	/*extern slugify */

    /*  
        Variable: url_fetch_school
            URL for fetching schools
    */
    
	// New for yalea
	var self = this;
	
	
	
	this.url_fetch_school = null;

    
    /*
        Variable: school_information
            School information structure
    */
    this.school_information = null;
    
    /*  
        Variable: course_starting_date
            Course starting date:   
    */
    this.course_starting_date = course_starting_date;

       
    /*  
        Variable: school_demonstrator_div
            School demonstrator general div
    */
    this.school_demonstrator_div = dojoWrapper.getById('id_div_school_demonstrator');

    /*
        Variable: school_title_span
            School title
    */        
    this.school_title_span = dojoWrapper.getById('id_school_demonstrator_title');
     
        
    /*
        Variable: cached_responses
            Cached responses implemented as a hashed array, the school id serves as index
    */
    this.cached_responses = [];
    
    /*
        Variable: init_button
            Will be 'clicked' initially when the school loads
    */
    this.init_button = dojoWrapper.getById('id_school_demonstrator_' + initial_tab + '_cell_button');
                                     
    /*
        Variable: buttons
           Cells that act as buttons
           The order must correspond with this.content_spans array
    */
    this.buttons = [];
    this.buttons[0] = dojoWrapper.getById('id_school_demonstrator_comments_cell_button');
    this.buttons[1] = dojoWrapper.getById('id_school_demonstrator_introduction_cell_button');
    this.buttons[2] = dojoWrapper.getById('id_school_demonstrator_photo_cell_button');	
    this.buttons[3] = dojoWrapper.getById('id_school_demonstrator_facts_cell_button');
    this.buttons[4] = dojoWrapper.getById('id_school_demonstrator_courses_cell_button');
    this.buttons[5] = dojoWrapper.getById('id_school_demonstrator_accommodation_cell_button');
    
    /*  
        Variable: current_button
            The currently selected button
    */
    this.current_button = null;
    
    /*
        Variable: accommodation_price_rows
            Rows that should be cleared 
    */
    this.accommodation_price_rows = [];
    
    /*
        Variable: course_price_rows
            Rows that should be cleared 
    */
    this.course_price_rows = [];                                                                         

    /*    
        Variable: content_spans
            Spans to be linked with buttons (order matters):
            content_spans array must be at least as long as buttons array
    */
    this.content_spans = [];
    this.content_spans[0] = dojoWrapper.getById('id_school_demonstrator_comments_span');
    this.content_spans[1] = dojoWrapper.getById('id_school_demonstrator_introduction_span');
	this.content_spans[2] = dojoWrapper.getById('id_school_demonstrator_photo_span');	
    this.content_spans[3] = dojoWrapper.getById('id_school_demonstrator_facts_span');
    this.content_spans[4] = dojoWrapper.getById('id_school_demonstrator_courses_span');
    this.content_spans[5] = dojoWrapper.getById('id_school_demonstrator_accommodation_span');
    this.content_spans[6] = dojoWrapper.getById('id_school_demonstrator_loading_span');
    
    /* 
        Variable: loading_span
            Loading indicator
    */
    this.loading_span = this.content_spans[5];
    
    /*
        Host family type:
    */                   
    this.HOST_FAMILY_TYPE = HOST_FAMILY_TYPE;
    
    /**
     * Which weeks should be displayed in the price tables
     */
    this.displayed_weeks = ['week4', 'week8', 'week12', 'week16', 'week20'];
    
    /*   
              Interface functions:
    */    
    this.style_button_mouseover = function ( a_button )
    {
        a_button.className = 'school_demonstrator_menu_button_mouseover';
    }
    
	
	
    this.style_button_mouseout = function ( a_button )
    {
        a_button.className = 'school_demonstrator_menu_button_mouseout';
    }
    
    this.style_button_selected = function ( a_button )
    {
        a_button.className = 'school_demonstrator_menu_button_selected';
    }
    
    /* 
        Function: select_button
            Turns off all the other buttons except the given one and applies another style
            
            Shows the span to the user.
     */
    this.select_button = function(a_button)
    {

        if (this.current_button !== a_button)
        {
            /*
                "Style out" the old one:
            */
            if (this.current_button)
            {
                this.style_button_mouseout(this.current_button);
            }
            
            this.current_button = a_button;
            this.style_button_selected(a_button);
            this.show_content_span(a_button.corresponding_span);
        }        
    };
    
    /* 
        Function: handle_mouse_over_cell
            handles mouse over events
            triggered for a cell. 
	*/
	
    this.handle_mouse_over_cell = function ( evt ) 
    {
        var a_button = evt.target;
        if ( ! a_button.disabled && 
             self.current_button !== a_button )
        {
			 
            self.style_button_mouseover ( a_button );
        }        
    };
	
    /*
        Function: handle_mouse_out_cell
            handles mouse out events
            triggered for a cell.                
    */
    this.handle_mouse_out_cell = function ( evt )
    {
        var a_button = evt.target;
        
        if ( a_button !== self.current_button )
        {
            self.style_button_mouseout ( a_button );
        }
    };
    
    /* 
        Function: handle_mouse_click_cell
            handles mouse clicks on the cell.
            
            Corresponding span will be shown and 
            buttons will be properly styled.   
    */
    this.handle_mouse_click_cell = function ( evt )
    {
        var a_button = evt.target;
        self.select_button(a_button);        
    };
    
    /**
     *   Function: enable_buttons
     *       Enables all the buttons in the button_array
     *   
     *   Parameters:
     *       button_array - Array of buttons
     *       enable - Boolean, whether to enable them
     */
    this.enable_buttons = function( button_array, enable )
    {
        for (var i = 0; i < button_array.length; i++ )
        {
            var a_button = button_array[i];
            a_button.disabled = !enable;
        }
    };
    
    /**
     *   Function: show_loading
     *       lets the user know we are loading.    
     */
    this.show_loading = function()
    {
        this.school_title_span.innerHTML = '&nbsp;';
        
        a_wait_cursor_manager.push_pending_job_signal();
        
        if (this.current_button)
        {
            this.style_button_mouseout(this.current_button);
        }
        
        this.show_content_span(this.loading_span);
        this.enable_buttons(this.buttons, false);
        this.current_button = null;
    };
    
    /**
     *   Function: hide_loading
     *   	Lets the user know we stopped loading
     *       and received all the information.  
     */
    this.hide_loading = function()
    {                       
        this.select_button(this.init_button);
        this.enable_buttons( this.buttons, true);
        
        //a_wait_cursor_manager.pop_pending_job_signal();
		a_wait_cursor_manager.reset();
    };    

    /**
     * deletes all rows in a table
     * needed because IE cant handle table.innerHTML = ''
     */
    this.clear_table = function(table)
    {
     /* does not work flawlessly in firefox
      for (var i= table.rows.length-1; i>=0; i--)
      {
       table.deleteRow(i);
      }
     */
     while(table.hasChildNodes())
     {
         table.removeChild(table.firstChild);
     }
    };
     
	/**
	 * Function: show_help
	 * 		shows the help dialog, if it exists
	 */
	this.show_help = function()
	{
		var helpDiv = dojoWrapper.getById('id_div_school_demonstrator_help');
		if (helpDiv && helpDiv.style.display == 'none') {
			var fade_time = 500;
			var fadeIn = dojoWrapper.fadeIn (helpDiv, fade_time);
            fadeIn.play();
		}
	};
	
	/**
	 * Function: hide_help
	 * 		hides the help dialog, if it exists
	 */
	this.hide_help = function()
	{
		var helpDiv = dojoWrapper.getById('id_div_school_demonstrator_help');
		if (helpDiv && helpDiv.style.display != 'none') {
			var fade_time = 500;
			var fadeOut = dojoWrapper.fadeOut (helpDiv, fade_time);
            fadeOut.play();
		}
	};
	
	this.toggle_help = function()
	{
		var helpDiv = dojoWrapper.getById('id_div_school_demonstrator_help');
		if (helpDiv) {
			if (helpDiv.style.display == 'none') {
				this.show_help();
			}
			else {
				this.hide_help();
			}
		}
	};
	
	
    /**
     *   Function: show_content_span
     *   	shows the specified content
     *       span and makes sure that all the other spans are 
     *       invisible.
     */
    this.show_content_span = function ( a_content_span )
    {
        a_content_span.style.display = '';        
        
        for ( var i = 0; i < this.content_spans.length; i ++ )
        {
            if ( a_content_span !== this.content_spans[i] )
            {
                this.content_spans[i].style.display = 'none';
            }
        }
    };
    
    /**
     *   Function: show_volunteerings
     *       Shows/hides more detailed information about volunteerings programmes.
     *       
     *   Parameters:
     *       show - Boolean; true means show, false means hide
     */
    this.show_volunteerings = function(bool)
    {
        var volunteering_div = dojoWrapper.getById('id_volunteering_content');
        var show_link = dojoWrapper.getById('id_school_info_volunteering_show_link');
        var hide_link = dojoWrapper.getById('id_school_info_volunteering_hide_link');
        
        if (volunteering_div !== null)
        {
            if (bool)
            {
                volunteering_div.style.display = '';
                show_link.style.display = 'none';
                hide_link.style.display = '';
            }
            else
            {
                volunteering_div.style.display = 'none';
                show_link.style.display = '';
                hide_link.style.display = 'none';    
            }    
        }
    };
    
    /**
     *   Function: fill_fields
     *       Function:fills the school spans with information
     *   
     *   See Also:
     *       <fill_sidebar>, <fill_city_comment>, <fill_high_seasons>, <fill_festivity_dates>, <fill_other_chain_school_cities>,
     *       
     *       <fill_courses>, <fill_activities>, <fill_volunteerings>, 
     *       
     *       <fill_all_simple_fields>, <fill_simple_field>
     */                
    this.fill_fields = function ()
    {       
        /*
            Fill simple fields:
        */                            
        this.fill_all_simple_fields(this.school_information.school);                      
        
                        
        /*
         * 	 Tab Comment
         */
        this.fill_city_comment();
		this.fill_facts(this.school_information.fact_set, 'comment');
		var num_comment_facts = this.count_facts(this.school_information.fact_set, 'comment');
		var divider = dojoWrapper.getById('id_comment_hr');
		if (divider)
		{
			showElement(divider, num_comment_facts > 0);
		}
		
		/*
		 * 	 Tab School
		 */
		// fill school text
        this.fill_a_field('school_size', gettext(this.school_information.school.school_size));
        this.fill_high_seasons();
		this.fill_other_chain_school_cities();
		this.fill_facts(this.school_information.fact_set, 'school');
		
		/*
		 * Tab Photos
		 */
		
		var countryUrlName = this.school_information.country.url_name_english;
        var cityUrlName = this.school_information.city.url_name_english;
		var schoolUrlName = this.school_information.school_url_name_english;
		
		var galleryUrl = "/site_media/location_media/country/" + countryUrlName + "/city/" + cityUrlName + "/school/" + schoolUrlName + "/media/flash/gallery.xml";
		
		
		fo.addVariable("xmlURL", galleryUrl );
		fo.write("flashcontent");
		
		/*
		 * 	 Tab Facts
		 */
		this.fill_facts(this.school_information.fact_set, 'facts');
        this.fill_festivity_dates();
		this.fill_age_composition(this.school_information.age_composition_set);
		this.fill_language_composition(this.school_information.language_composition_set, this.school_information.nationality_composition_set);
		
        /*
         *   Tab Courses:
         */
        this.fill_a_field('course_recommendation', this.school_information.school.course_recommendation);
        this.fill_courses();
        this.fill_inscription_fee();
		this.fill_facts(this.school_information.fact_set, 'courses');
		this.fill_facts(this.school_information.fact_set, 'courses_list');
        this.fill_volunteerings();
        
        /*
         *   Tab Accommodation forms:
         */
        this.fill_a_field('accommodation_recommendation', this.school_information.school.accommodation_recommendation);
        this.fill_accommodation_forms();
		this.fill_facts(this.school_information.fact_set, 'accommodation');
		this.fill_facts(this.school_information.fact_set, 'accommodation_list');
		
		/*
		 * 	 Tab Prices
		 */
		this.fill_facts(this.school_information.fact_set, 'prices');
		var priceSeasons = this.prepare_seasons();
        this.fill_seasons(priceSeasons);
		this.fill_school_material_fees();
        this.fill_transfer();
        this.fill_accommodation_inscription_fees();
        this.fill_a_field('exam_fee', this.school_information.school.exam_fee);
		
    };       
    
    /**
     *   Function: fill_sidebar
     *       Fills the panel (right side of school demonstrator).
     */
    this.fill_sidebar = function()
    {   
		var sidebarLinks = dojoWrapper.getById ( 'sidebar_links');
		
		sidebarLinks.style.display = "";
	
        // fill the country, city link buttons
        var countryButton = dojoWrapper.getById('id_country_button');
		var countryButtonImage = dojoWrapper.getById  ( 'id_country_button_image' );
		var countryButtonCaption = dojoWrapper.getById ( 'id_country_button_caption' );
		
        if (countryButton !== null) {
            var countryName = this.school_information.country.name;
            var countryUrlName = this.school_information.country.url_name;
			var countryUrlNameEnglish = this.school_information.country.url_name_english;
			countryButtonImage.src = MEDIA_URL + "location_media/country/" + countryUrlNameEnglish + "/media/images/thumb_icon_menu_icon.png";
            countryButtonCaption.innerHTML = countryName;
            countryButton.href = '/' + COUNTRY_URL_PREFIX + countryUrlName;

        }
        var cityButton = dojoWrapper.getById('id_city_button');
		var cityButtonImage = dojoWrapper.getById  ( 'id_city_button_image' );
		
        if (cityButton !== null) {
            var cityName = this.school_information.city.name;
            var cityUrlName = this.school_information.city.url_name;
			var cityUrlNameEnglish = this.school_information.city.url_name_english;
			cityButtonImage.src = MEDIA_URL + "location_media/country/" + countryUrlNameEnglish + "/city/" + cityUrlNameEnglish + "/media/images/thumb_caption.jpg";
            //cityButton.innerHTML = cityName;
            cityButton.href = '/' + COUNTRY_URL_PREFIX + countryUrlName + "/"+ CITY_URL_PREFIX + cityUrlName;

        }
        
        // set map, photos button urls
        var schoolName = this.school_information.school.name;
        var schoolUrlName = this.school_information.school_url_name;
		
        var a_self = this;
		
		var receive_gmap_data = this.receive_gmap_data;
		
		var agent = function ( aData, aArgs )
		{
			receive_gmap_data ( aData, a_self );
		}
		
		dojoWrapper.ajaxRequestPost ( "fetch_gmap_data/", { city_name: this.school_information.city.name },  agent );
			
    
		// fill links
        var school_links_span = dojoWrapper.getById('id_school_demonstrator_school_links_span');
		if (school_links_span !== null) {
	        school_links_span.innerHTML = '';
	        
	        for ( var i = 0; i < this.school_information.school_link_set.length; i++ )
	        {                                                                      
	            var newLine = document.createElement('br');
	            var a_link = document.createElement('a');
	            
	            a_link.href = this.school_information.school_link_set[i].link;
	            a_link.target = '_blank';
	            
	            var a_caption = document.createTextNode(this.school_information.school_link_set[i].caption);
	            
	            a_link.appendChild(a_caption);
	            
	            school_links_span.appendChild(a_link);
	            school_links_span.appendChild(newLine);
	        }
			
			var school_links_div = dojoWrapper.getById('school_links');
			if (school_links_div)
			{
			    if (this.school_information.school_link_set.length > 0)
			    {
	                school_links_div.style.display = '';
	            }
	            else
	            {
	                school_links_div.style.display = 'none';
	            }
	        }
		}
		
		// fill school images
		var school_images_div = dojoWrapper.getById('id_school_info_images');
		if (school_images_div)
		{
		    school_images_div.innerHTML = '';
		    for (var j=0; j<this.school_information.school_image_set.length; j++)
		    {
		        var schoolImage = this.school_information.school_image_set[j];
		        
		        var image = new Image();
		        image.src = schoolImage.url;
                
                if (schoolImage.link && schoolImage.link != '')
                {
		            var link = document.createElement('a');
		            link.href = schoolImage.link;
		            link.target = '_blank';
		            link.title = schoolImage.caption;
		            link.appendChild(image);
		            school_images_div.appendChild(link);
                }
                else
                {
		            school_images_div.appendChild(image);
                }
		    }
		}
    };
       
    /**
     *   Function: fill_city_comment
     *       Fills the fields concerning city and not school information (e.g. city comment).
     */
    this.fill_city_comment = function ()
    {
        dojoWrapper.getById('id_school_info_city_comment_span').style.display = 'none';
		
        if ( this.school_information.city.comment &&
             this.school_information.city.comment !== '')
        {
            dojoWrapper.getById('id_school_info_city_comment_span').style.display = '';
            
            this.fill_a_field('city_comment', this.school_information.city.comment);
            this.fill_a_field('city_name', this.school_information.city.name);
        }                  
        
    };
    
    /**
     *   Function: fill_high_seasons
     *       Fills the high seasons field with the high seasons received from server.
     */
    this.fill_high_seasons = function ()
    {
        var month_names = gettext('Januar Februar März April Mai Juni Juli August September Oktober November Dezember').split(' ');
        var high_seasons_str = '';
        
        for ( var i = 0; 
              i < this.school_information.school_high_season_set.length; 
              i++ )
        {
            var a_high_season = this.school_information.school_high_season_set[i];
            
            high_seasons_str += month_names[ a_high_season.from_month - 1 ];
            
            if ( a_high_season .to_month )
            {
                high_seasons_str += ' - ' + month_names [ a_high_season .to_month - 1 ];
            }
            
            if ( i !== this.school_information.school_high_season_set.length - 1 )
            {
                high_seasons_str += ', ';
            }
        }
                
        this.fill_a_field ( 'high_seasons', high_seasons_str );     
    };    
       
    /**
     *   Function: fill_festivity_dates
     *       fills the festivity dates field with the festivity dates received from server.
     */
    this.fill_festivity_dates = function()
    {    
        var festivity_date_strs = [];
        var a_festivity_date = null;             
        var a_festivity_date_str = '';
        var yyyy_mm_dd = [];
        var a_from_date, a_to_date;
		var i;
        
		var festivity_dates_span = dojoWrapper.getById('id_school_info_festivity_dates');
		festivity_dates_span.innerHTML = '';
		
        for (i = 0; i < this.school_information.school_festivity_date_set.length;  i++)
        {
            a_festivity_date = this.school_information.school_festivity_date_set[i];
            a_from_date = a_festivity_date.from_date;
            a_to_date   = a_festivity_date.to_date;
            a_festivity_date_str = date_str_to_i18n_date( a_from_date, 'd.m.Y');
            
            if (a_to_date)
            {
                a_festivity_date_str += ' - ' + date_str_to_i18n_date( a_to_date, 'd.m.Y');
            }
            
            festivity_date_strs.push( a_festivity_date_str );
			//festivity_dates_span.innerHTML += festivity_date_strs.join(', ');     
        }
        
        if (festivity_date_strs.length > 0)
        {
			// TODO: group dates by year.
			// e.g.: 2007: 25.12., 31.12.
			festivity_dates_span.innerHTML = festivity_date_strs.join(', ');
        }
        else
        {
			festivity_dates_span.innerHTML = gettext('keine');
        }
    };
       
    /**
     *   Function: fill_other_chain_school_cities
     *       Fills the other chain school cities row.
     */
    this.fill_other_chain_school_cities = function()
    {     
        var other_chain_cities_row = dojoWrapper.getById('id_school_info_other_chain_cities_row');
        
        if (this.school_information.other_chain_cities &&
            this.school_information.other_chain_cities.length )
        {       
            var other_chain_cities_strs = [];
            for (var i = 0; i < this.school_information.other_chain_cities.length; i++)
            {
                var a_chain_city = this.school_information.other_chain_cities[i]; 
                var a_chain_city_str = [a_chain_city.city_name, ' (', a_chain_city.country_name, ')'].join('');
                
                other_chain_cities_strs.push(a_chain_city_str);                                    
            }                              
            
            this.fill_a_field('other_chain_cities', other_chain_cities_strs.join(', ') );
            other_chain_cities_row.style.display = '';
        }
        else
        {
            /*
                Hide other chain cities row:
            */                   
            other_chain_cities_row.style.display = 'none';
        }        
    };       
       
	/**
	 * Function: fill_inscription_fee
	 * 		Fills the inscription fee span with the fee.
	 */
    this.fill_inscription_fee = function()
    {
		var inscriptionFeeCaption = dojoWrapper.getById ( 'id_school_info_school_inscription_fee_caption');
		
		var schoolMaterialFee = this.school_information.school_material_fee_set;
		
		if ( schoolMaterialFee[0].week1 != "0")
		{
			inscriptionFeeCaption.innerHTML = gettext ( "Einschreibungsgegühr" );
		}
		else
		{
			inscriptionFeeCaption.innerHTML = gettext ( "Einschreibungsgebühr & Kursmaterial" );
		}
		
        var an_inscription_fee = find_period_with_date( this.course_starting_date,
                                                        this.school_information.school_inscription_fee_set );
        if (an_inscription_fee !== null)
        {
            var inscription_fee_str = a_money_exchange.repr_amount_in(this.school_information.school.currency_abb, 
                                                                  an_inscription_fee.fee );
            this.fill_a_field('school_inscription_fee', inscription_fee_str );
        }
        else
        {
            this.fill_a_field('school_inscription_fee', '');
        }
    };
    
	/**
	 * Function: fill_transfer
	 * 		fills the transfer span with the given cost.
	 */
    this.fill_transfer = function()
    {
        var table = dojoWrapper.getById('id_school_demonstrator_transfer_table');
        
        if (table)
        {
            //table.innerHTML = '';
            this.clear_table(table);
			var tableBody = document.createElement('tbody');
			table.appendChild(tableBody);

	    	var currencyAbb = this.school_information.school.currency_abb.toUpperCase();
            var shownTransfers = {};
            
            for (var j=0; j<this.school_information.school_transfer_set.length; j++)
            {
                var a_transfer = this.school_information.school_transfer_set[j];
                if (a_transfer)
                {
                    var transfer_price_list = this.school_information.school_transfer_price_set[a_transfer.id];
                    var transfer_price = find_period_with_date(this.course_starting_date, transfer_price_list);
                    
                    if (transfer_price)
                    {
                        var row = document.createElement('tr');
                        tableBody.appendChild(row);
                        
                        var titleCell = document.createElement('td');
                        row.appendChild(titleCell);
                        titleCell.className = 'title_cell';
                        titleCell.innerHTML = a_transfer.name;
                        
                        var textCell = document.createElement('td');
                        row.appendChild(textCell);
                        textCell.className = 'text_cell';
                        textCell.innerHTML = currencyAbb + ' ' + transfer_price.cost +  ' - ' + a_transfer.description;
                    }
                }
            }
            
            var transferDiv = dojoWrapper.getById('id_school_demonstrator_transfer_div');
            if (transferDiv)
            {
                if (this.school_information.school_transfer_set.length > 0)
                {
                    transferDiv.style.display = '';
                }
                else
                {
                    transferDiv.style.display = 'none';
                }
            }
        }
    };
       
    /**
     *   Function:fills the accommodation
     *   form table with prices.
     */      
    this.fill_accommodation_forms = function()
    {         
        var table = dojoWrapper.getById('id_school_demonstrator_accommodation_table');
        if (table)
        {
            this.hideTableBodies(table);
            
            /*
                Clear all the rows that should be reset:        
            */
            clear_all_rows( this.accommodation_price_rows );
            this.accommodation_price_rows = [];
            
            var only_students_table = dojoWrapper.getById('id_accommodation_only_students_table');
    		if (only_students_table !== null)
    		{
    	        only_students_table.style.display = 'none';
    		}
            
            var accommodationTypes = this.school_information.accommodation_form_set.accommodation_types_ordered;
            var accommodationFormSet = this.school_information.accommodation_form_set;
            
            for (var i = 0; i < accommodationTypes.length; i++)
            {
                var a_type = accommodationTypes[i];                        
                
                //
                //    Do we have at least one host family
                //    accommodation form? -> show/hide host famliy specific info
                //
                if (a_type === this.HOST_FAMILY_TYPE &&
                    accommodationFormSet[a_type].length &&
    				only_students_table !== null)
                {
                    only_students_table.style.display = '';
                }
                
                var tbody = dojoWrapper.getById('id_school_info_accommodation_type_' + a_type + '_tbody');
                
                for (var j = this.school_information.accommodation_form_set[a_type].length - 1; 
                      j >= 0;
                      j -- )
                {
                    var accommodation = accommodationFormSet[a_type][j];
                                                                                                                                                   
                    //  Find current price set:
                    var price = find_period_with_date(this.course_starting_date, accommodation.accommodation_price_set);  
                    
                    if (price)
                    {
                        // insert price row
                        var className = 'accommodation_price_cell';
                        
                        var row = tbody.insertRow(this.school_information.accommodation_form_set[a_type].length - j);
                        
        				// insert the course name
                        var name_cell = document.createElement('td');
                        name_cell.setAttribute('id', 'id_accommodation_link_'+ i + '_' + j);
                        row.appendChild(name_cell);
                        
                        this.fillRow(row, price, this.displayed_weeks, className);
                        //tbody.appendChild(row);
                        this.accommodation_price_rows.push(row); 
                        
                        // apply alternating row colors (itunes-like)
                        if (j % 2 === 0)
                        {
                            row.setAttribute('class', 'row1'); 
                        }
                        else
                        {
                            row.setAttribute('class', 'row2'); 
                        }                  
                        
        				// create the tooltip link
                        var contentCell = document.createElement('a');
                        name_cell.appendChild(contentCell);
                        contentCell.innerHTML = accommodation.name;
                        contentCell.setAttribute('class', 'school_link');
        				var targetId = name_cell.getAttribute('id');
        				this.create_tooltip(targetId, accommodation.description);
                    }
                    tbody.style.display = '';
                }                                                                                                                                       
            }
            
            // fill currency
            this.fill_a_field('school_currency_accommodation', this.school_information.school.currency_abb.toUpperCase());
        }
    };                  
    
    /**
     * Hides all tbody elements
     */
    this.hideTableBodies = function(table)
    {
        for ( var k = 0; k < table.tBodies.length; k ++ )
        {
            table.tBodies[k].style.display = 'none';       
        }
    };
    
    /**
     *   Function: fill_courses
     *       Fills the courses table.
     */   
    this.fill_courses = function()
    {
        var course_table = dojoWrapper.getById('id_school_demonstrator_courses_table');
        if (course_table)
        {
            this.hideTableBodies(course_table);
            
            /*
                Clear all the rows that should be reset:        
            */
            clear_all_rows(this.course_price_rows);
            this.course_price_rows = [];

			
            var courseTypes = this.school_information.course_set.course_types_ordered;
			

            for (var i = 0; i < courseTypes.length; i++)
            {
                var a_course_type = courseTypes[i];
                var tbody = dojoWrapper.getById('id_school_info_course_type_' + a_course_type +'_tbody');
                
                for (var j = (this.school_information.course_set[a_course_type].length - 1); j >= 0; j-- )
                {
                    var a_course = this.school_information.course_set[a_course_type][j];
					
                    var a_course_price = find_period_with_date(this.course_starting_date, a_course.course_price_set); 
                   
                    if (a_course_price)
                    {
                        var row = tbody.insertRow(this.school_information.course_set[a_course_type].length - j);
                        
                        // create the table cell
                        var name_cell = document.createElement('td');
                        name_cell.setAttribute('id', 'id_course_link_'+ i + '_' + j);
                        row.appendChild(name_cell);
                        
                        // insert price row
                        var className = 'course_price_cell';
                        this.fillRow(row, a_course_price, this.displayed_weeks, className);
                        this.course_price_rows.push(row);
                        //tbody.insertBefore(tbody.childNodes[0], row);
                        
                        // apply alternating row colors (itunes-like)
                        if (j % 2 === 0)
                        {
                            row.setAttribute('class', 'row1'); 
                        }
                        else
                        {
                            row.setAttribute('class', 'row2'); 
                        }
                        
        				// create the tooltip link
                        var contentCell = document.createElement('a');
                        contentCell.innerHTML = a_course.name;
                        contentCell.className = 'school_link';
                        name_cell.appendChild( contentCell );
        				var targetId = name_cell.getAttribute('id');
        				this.create_tooltip(targetId, a_course.description);                                          
                    }
                    
                    tbody.style.display = '';
                }
            }
            
            // fill currency
            this.fill_a_field('school_currency_course', this.school_information.school.currency_abb.toUpperCase());
        }                       
    };

    /**
     *   Fills the course material fees table with values
     *   
     *   Creates a single row with fees that apply to all courses
     */
    this.fill_school_material_fees = function()
    {
        var table = dojoWrapper.getById('id_school_demonstrator_material_fee_table');
        if (table)
        {
            // clear table rows 3 to n
            for (var i=2; i<table.rows.length; i++)
            {
                var a_row = table.rows[i];
                a_row.parentNode.removeChild(a_row);
            }
            
            var feeSet = find_period_with_date(this.course_starting_date, this.school_information.school_material_fee_set);
                 
            if (feeSet)
            {
                var row = document.createElement('tr');
                var titleCell = document.createElement('td');
                row.appendChild(titleCell);
                row.className = 'row1'; 
                titleCell.innerHTML = gettext('Alle Kurse');
                
                var className = 'course_price_cell';
                this.fillRow(row, feeSet, this.displayed_weeks, className);
                table.tBodies[0].appendChild(row);
            }
            
            // fill currency
            this.fill_a_field('material_fee_currency', this.school_information.school.currency_abb.toUpperCase());
            
//            table.style.display = '';
        }
    };
    
    /**
     * Fills the accommodation fees as a composed text
     */
    this.fill_accommodation_inscription_fees = function()
    {
        var text = '';
        
        var accommodationTypes = this.school_information.accommodation_form_set.accommodation_types_ordered;
        var set = this.school_information.accommodation_form_set;
        var currencyAbb = this.school_information.school.currency_abb.toUpperCase();
        
        for (var i = 0; i < accommodationTypes.length; i++)
        {
            var aType = accommodationTypes[i];
            
            // only use the first example for each accommodation type
            if (set[aType].length > 0)
            {
                //  Find current price set:
                var accommodationPriceSet = set[aType][0].accommodation_price_set;
                var price = find_period_with_date(this.course_starting_date, accommodationPriceSet);
                
                if (price)
                {
                    text += gettext(aType) + ': '+currencyAbb+' '+price.inscription_fee+', ';
                }
            }
        }
        
        this.fill_a_field('accommodation_inscription_fee', text);
    };
    
    /**
     *   Function: fill_volunteerings
     *       fills the volunteering table with apropriate infos.
     */
    this.fill_volunteerings = function() 
    {
        var volunteering_content = dojoWrapper.getById('id_volunteering_content');      
        var volunteering_not_available_text = dojoWrapper.getById('id_school_info_volunteering_not_available_text');
        var volunteering_available_text = dojoWrapper.getById('id_school_info_volunteering_available_text');
        
		if (volunteering_content)
		{
	        /*
	            Choose text in theader to display:
	        */
	        if (this.count_facts(this.school_information.fact_set, 'volunteering') == 0)
	        {
	            /*
	                No volunteering programmes:
	            */
	            volunteering_not_available_text.style.display = '';
	            volunteering_available_text.style.display = 'none';
	        }
	        else
	        {
	            /*
	                Display 'more infos' caption:
	            */
	            volunteering_not_available_text.style.display = 'none';
	            volunteering_available_text.style.display = '';            
	        }
	
		    this.fill_facts(this.school_information.fact_set, 'volunteering');
		}
    };
  
    /**
     * 	 Functin: fill_acts
     * 		  fills each facts category table with its items
     * @param {Object} school_fact_set
     * @param {String} facts_category
     */
	this.fill_facts = function(school_fact_set, category_name)
	{
		
		var table = dojoWrapper.getById('id_school_facts_' + category_name);
		if (table)
		{
			// delete all rows of the table
			//table.innerHTML = '';
			this.clear_table(table);
			table.style.display = '';
			var tableBody = document.createElement('tbody');
			table.appendChild(tableBody);
			
			for (var i=0; i<school_fact_set.length; i++)
			{
				var a_fact = school_fact_set[i];
				if (a_fact.category == category_name)
				{
					var row = document.createElement('tr');
					tableBody.appendChild(row);
					
					var titleCell = document.createElement('td');
					titleCell.innerHTML = a_fact.title;
					titleCell.className = 'title_cell';
					row.appendChild(titleCell);
					
					var textCell = document.createElement('td');
					textCell.innerHTML = a_fact.text;
					textCell.className = 'text_cell';
					row.appendChild(textCell);
				}
			}
			
			if (school_fact_set.length == 0)
			{
				table.style.display = 'none';
			}
		}
	};
    
    /**
     * Counts the number of facts
     * @param {Object} school_fact_set
     * @param {String} category_name
     */
    this.count_facts = function(school_fact_set, category_name)
    {
        var num = 0;
        for (var i=0; i<school_fact_set.length; i++)
		{
			if (school_fact_set[i].category == category_name)
            {
                num += 1;
            }
        }
        return num;
    };
	
	/**
	 * Fills the language composition table 
	 * on the tab "facts"
	 * @param {Object} language_set
	 * @param {Object} nationality_set
	 */
	this.fill_language_composition = function(language_set, nationality_set)
	{
		var table = dojoWrapper.getById('id_language_composition');
		if (table)
		{
			// delete all rows of the table
			//table.innerHTML = '';
			this.clear_table(table);
			var tableBody = document.createElement('tbody');
			table.appendChild(tableBody);
			
			for (var i=0; i<language_set.length; i++)
			{
				var lang = language_set[i];
				
				var row = document.createElement('tr');
				tableBody.appendChild(row);
					
				// title e.g. "Deutsch"
				var titleCell = document.createElement('td');
				row.appendChild(titleCell);
				titleCell.innerHTML = lang.name;
				titleCell.className = 'text_cell';
				
				// percentage e.g. "15%"
				var totalCell = document.createElement('td');
				row.appendChild(totalCell);
				totalCell.innerHTML = lang.percentage + '%';
				totalCell.className = 'percentage_cell';
				
				// languages e.g. "de 1%, at 2%, ch 4%"
				var languageCell = document.createElement('td');
				row.appendChild(languageCell);
				languageCell.className = 'language_cell';
				
				// language table
				var langTable = document.createElement('table');
				var langTableBody = document.createElement('tbody');
				var langRow = document.createElement('tr');
				languageCell.appendChild(langTable);
				langTable.appendChild(langTableBody);
				langTableBody.appendChild(langRow);
				
				// for each nationality in the language group insert the flag image and the percentage
				for (var j=0; j<nationality_set.length; j++)
				{
					if (nationality_set[j].language_id == lang.id)
					{
						// insert a new row every 3 flags
						if (langRow.childNodes.length == 3)
						{
							langRow = document.createElement('tr');
							langTableBody.appendChild(langRow);
						}
						
						var countryCell = document.createElement('td');
						langRow.appendChild(countryCell);
						
						var countryCode = nationality_set[j].nationality_code;
						var percentage = nationality_set[j].percentage;
						var countryName = countryCode;
						if (pkg_nationalities && pkg_nationalities[countryCode]) {
							countryName = pkg_nationalities[countryCode];
						}
						
						var countryFlag = new Image();
						countryFlag.title = countryName;
						countryFlag.src = MEDIA_URL + 'price_calculator/images/small_flags/'+ countryCode + '.gif';
						countryCell.appendChild(countryFlag);
						countryCell.appendChild(document.createTextNode(percentage + '%'));
					}
				}
			}
			
		}
	};
	
	/**
	 * Fills the age composition table
	 * on the tab "facts"
	 * @param {Object} age_set
	 */
	this.fill_age_composition = function(age_set)
	{
		
		var table = dojoWrapper.getById('id_age_composition');
		if (table)
		{
			// delete all rows of the table
			//table.innerHTML = '';
			this.clear_table(table);
			var tableBody = document.createElement('tbody');
			table.appendChild(tableBody);
			
			for (var i=0; i<age_set.length; i++)
			{
				var row = document.createElement('tr');
				tableBody.appendChild(row);
					
				var titleCell = document.createElement('td');
				titleCell.innerHTML = age_set[i].age;
				titleCell.className = 'text_cell';
				row.appendChild(titleCell);
				
				var textCell = document.createElement('td');
				textCell.innerHTML = age_set[i].percentage + '%';
				textCell.className = 'percentage_cell';
				row.appendChild(textCell);
			}
		}
	};
	
    /**
     * Finds the course season intersections
     * Currently only uses course price dates for season calculation
     * Returns array of price periods that can be used to fill select box
     */
    this.prepare_seasons = function()
    {
        var ignorePast = true;
        var today = date_to_str(new Date());
        var course = null;
        
        var intersectionSets = [];
        
        // extract course price information
        for (var i=0; i<this.school_information.course_set.course_types_ordered.length; i++)
        {
            // iterate over each course
            var courseType = this.school_information.course_set.course_types_ordered[i];
            var courses = this.school_information.course_set[courseType];
			
            for (var j=0; j<courses.length; j++)
            {
                var prices = courses[j].course_price_set;
                intersectionSets.push(prices);
            }
        }
        // find the seasons
        var pricePeriods = intersect_periods_of_owners(intersectionSets, ignorePast, today);
        for (var i=0; i < pricePeriods.length; i++)
        {
            var from_date_text = date_str_to_i18n_date(pricePeriods[i].from_date, 'd.My');
            var to_date_text = date_str_to_i18n_date(pricePeriods[i].to_date, 'd.My');
            pricePeriods[i].interval_text = from_date_text + ' - ' + to_date_text;
        }
        return pricePeriods;
    };
    
    /**
     * Fills the course price select box
     * attributes used of array pricePeriods: from_date, interval_text
     * This function is also called from the Price Calculator class
     */
    this.fill_seasons = function(pricePeriods)
    {
		
        var pricePeriodsSelectBox = dojoWrapper.getById('id_school_demonstrator_select_course_season');
        if (pricePeriodsSelectBox !== null)
        {
            pricePeriodsSelectBox.options.length = 0;
            for (var i = 0; i < pricePeriods.length; i++)
            {
                create_and_add_option_to_select_box(
                    pricePeriodsSelectBox, 
                    pricePeriods[i].interval_text, 
                    pricePeriods[i].from_date);
            }
        }
		this.set_course_starting_date ( pricePeriods[0].from_date );
    };
	
    /**
     *   Function: fill_all_simple_fields
     *       fills all fields (taken as properties of a_structure), 
     *       if there is a corresponding span with id:
     *       - 'id_school_info_' + a property name + '_simple'
     *       - 'id_school_info_' + a property name + '_yes' / '_no'
     *       Boolean field implies that the corresponding span will be displayed.
     *   
     *   @param {Object} a_structure
     */
    this.fill_all_simple_fields = function(a_structure)
    {
        var the_corresponding_span_simple;
        var the_corresponding_span_yes, the_corresponding_span_no;
        
        for (a_property in a_structure)
        {
            var an_obj = a_structure[a_property];
            
            if ( is_function(an_obj) )
            {
                /*
                    Just ignore if it's a function:
                */
                continue;
            }
            
            if ( !is_array(an_obj) )
            {
                the_corresponding_span_simple = dojoWrapper.getById('id_school_info_' + a_property + '_simple');
                
                if (the_corresponding_span_simple)
                {
                    var text_for_simple_field = '';
                    
                    if (an_obj !== null)
                    {
                        text_for_simple_field = an_obj;
                    }
                    
                    the_corresponding_span_simple.innerHTML = text_for_simple_field;
                }

                the_corresponding_span_yes = dojoWrapper.getById('id_school_info_' + a_property + '_yes');
                the_corresponding_span_no  = dojoWrapper.getById('id_school_info_' + a_property + '_no');

                if (the_corresponding_span_yes ||
                    the_corresponding_span_no)
                {
                    if (an_obj)
                    {
                        if (the_corresponding_span_yes)
                        {
                            the_corresponding_span_yes.style.display = '';
                        }
                            
                        if (the_corresponding_span_no)
                        {
                            the_corresponding_span_no.style.display  = 'none';
                        }
                    }
                    else
                    {
                        if (the_corresponding_span_yes)
                        {
                            the_corresponding_span_yes.style.display = 'none';
                        }

                        if (the_corresponding_span_no)
                        {
                            the_corresponding_span_no.style.display  = '';
                        }
                    }
                }
                
            }
        }
    };
    
    /**
     *   Function: fill_simple_field
     *       For the given structure fills the span with 
     *       id = 'id_school_info_' + a_field_name with the a_structure [ a_field_name ]
     *       
     *   @param {Object} a_structure
     *   @param {String} a_field_name
     */          
    this.fill_simple_field = function ( a_structure, a_field_name )
    {
		var element = dojoWrapper.getById('id_school_info_' + a_field_name);
		
		if (element !== null) {
			element.innerHTML = a_structure[a_field_name];
		}
    };
    
    /**
     *	Function: fill_a_field
     *		fills the given span with a string.
     *       
     *       Span's name will be: 'id_school_info_' + a_field_name
     *  
     *  @param {String} a_field_name
     *  @param {String} a_string
     */
    this.fill_a_field = function ( a_field_name, a_string )
    {
        var element = dojoWrapper.getById('id_school_info_' + a_field_name);
		
		if (element !== null) {
			element.innerHTML = a_string;
			
		}
    };
	
	/**
	 * Creates a price tooltip
	 * @param {String} targetId The node identifier where to attach the tooltip
	 * @param {String} content The content of the tooltip
	 */
	this.create_tooltip = function(targetId, content)
	{
		// remove previously attached tooltips
        var tooltipWidget = dojoWrapper.getById('tt_'+targetId);
		
        if (tooltipWidget)
        {
            dojoWrapper.removeNode(tooltipWidget);
        }
			
        // add the new tooltip 
        if (content && content !== '')
        {
			var tooltipWidget = dojoWrapper.createElement ( "div" );
			tooltipWidget.setAttribute ( "class", "price_tooltip" );
			tooltipWidget.id = 'tt_'+targetId;
			tooltipWidget.innerHTML = content;
			
			var parent = dojoWrapper.getById  ( targetId );
			parent.appendChild ( tooltipWidget );
			
			tooltipWidget = dojoWrapper.getById ('tt_'+targetId );
			
			var agent1 = function ( )
			{
				dojoWrapper.setStyle ( tooltipWidget, "display", "block" );
			}
			
			var agent2 = function ( )
			{
				dojoWrapper.setStyle ( tooltipWidget, "display", "none" );
			}
			
			dojoWrapper.connect ( parent, "onmouseover", agent1 );
			dojoWrapper.connect ( parent, "onmouseout", agent2 );
        }    
	};

    /**
     * Creates cells in the row filled with structure properties
     * 
     * @param {Object} row Row template
     * @param {Object} data Data
     * @param {Array} fieldNames Insert only specified fields (optional)
     * @param {Object} className Class name that should be added to each cell
     * 
     * @return {Object} Filled row
     */
    this.fillRow = function(row, data, fieldNames, className)
    {
        add_cell = function(row, value, className)
                   {
                       var textNode;
                       var cell = document.createElement('td');
                       
                       if (value !== null && typeof(value) !== undefined)
                       {
                           textNode = document.createTextNode(value);
                       }
                       else
                       {
                           textNode = document.createTextNode('');
                       }
                       cell.appendChild(textNode);
                                       
                       if (className)
                       {
                           cell.className = className;                            
                       }
                       
                       row.appendChild(cell);                                              
                   };
        
        if (!fieldNames)
        {
            for(var key in data)
            {
                /*
                    Ignore functions
                */
                if ( is_function( data[key] ) )
                {
                    continue;
                }
                
                add_cell(row, data[a_property], className);    
            }
        }
        else
        {    
            for ( var i = 0; i < fieldNames.length; i ++ )
            {
                var field = fieldNames[i];
                add_cell(row, data[field], className);
            }
        }
                
        return row;
    };                                    
    
    
/*****************************************************************
    Communication functions:                            
******************************************************************/
    

    /**
     *   Function: show_school
     *       Displays the specified school
     *       sends a request to the server asking for a school information for the school defined by a_school_id.
     *       If a school didn't change, don't fetch it again!
     *       
     *   Parameters:
     *       a_school_id - Integer, school identifier
     *       school_pkg - Object, school package
     */
    this.show_school = function(a_school_id, school_pkg)
    {
    	this.hide_help();
        var data = null;
        
        /*
            Have we changed the school?
        */
        if ( this.school_information && this.school_information.school.id === a_school_id)
        {
            return;
        }
        
        /*
            Try to synchronize things:            
        */
        this.school_information = null;
        
        /*
            Let the user know we are loading:
        */
        this.show_loading();
	    this.school_demonstrator_div.style.display = 'none';
        
        if ( school_pkg )
        {
            /*
                Just forward it:                
            */                
            var data = school_pkg;                
            this.receive_school_info(data, this);
        }
        else
        {
            /*
                Do we have a cached response?
            */
            if ( this.cached_responses[a_school_id] )
            {
        		var a_cached_response = this.cached_responses[a_school_id];
        		data = copy_an_object(a_cached_response);
        		
        		this.receive_school_info(data, this);
            }
            else
            {
                /*
                    We have to request the package:                
                */
    
                /*
                    We have to make receive school info somehow global:                
                */
                var receive_school_info = this.receive_school_info;
                var a_self = this;
    
    			/*
                    Send a request:            
                */            
				
				var agent = function ( aData, aArgs )
				{
					receive_school_info( aData, a_self );
				}           
				
				dojoWrapper.ajaxRequestPost ( this.url_fetch_school, { school_id: a_school_id },  agent );
            }              	
        }             
    };                          
    
    /**
     *   Function: handle_transmit_errors
     *       Function object to use as asynchronous error function
     */
    this.handle_transmit_errors = function(type, error)
    {            
        show_errors([error]);
		if (a_wait_cursor_manager)
		{
			a_wait_cursor_manager.reset();
		}
    };
    
    /**
     *   Function: receive_school_info
     *       Processes school information requested and invokes the GUI update functions. 
     */
    this.receive_school_info = function(data, a_self)
    {
        /*
            Unpack the package:            

            if data is already an object and not a string, don't decode it -  just pass it
        */

        // avoid evaluation of existing objects
        var a_package = null;
        if (data.school !== undefined)
        {
            a_package = data;
        }
        else
        {
            a_package = dojoWrapper.evalFromJson( data );
        }

        /*
            Check for errors:    
            FIXME: replace != operator by !==        
        */                       
        if ( a_package.errors != undefined 
          && a_package.errors !== null 
          && a_package.errors != '' )
        {
            show_errors ( a_package.errors );
        }
        else
        {
            /* 
                save the package in the cache 
            */
            if (! a_self.cached_responses [ a_package.school.id ])
            {
                a_self.cached_responses [ a_package.school.id ] = data;
            }

            a_self.update_school_info( a_package );
        }
    };

	this.receive_gmap_data = function(data, a_self)
    {
        /*
            Unpack the package:            
            
            if data is already an object and not a string, don't decode it -  just pass it
        */
        
        // avoid evaluation of existing objects
        var a_package = null;
        
        a_package = dojoWrapper.evalFromJson( data );
       
                       
        /*
            Check for errors:    
            FIXME: replace != operator by !==        
        */                       
        if ( a_package.errors != undefined 
          && a_package.errors !== null 
          && a_package.errors != '' )
        {
            show_errors ( a_package.errors );
        }
        
		gMapPackage = dojoWrapper.evalFromJson ( a_package.json_package );
		
		var overlay = dojoWrapper.getById ( 'overlay_menu' );
		overlay.innerHTML = a_package.code;
		
		gMapWidget.update ( gMapPackage );
		gMapWidget.initialize ();

    }
    
    /**
     *   Function: update_school_info
     *       unpacks the package and fills in content information in the spans.
     *   
     *   Parameters:
     *       a_package - school information package
     */
    this.update_school_info = function(a_package)
    {
        /*
            Reset school information:            
        */
        this.school_information = {};            
        
        for ( a_property in a_package )
        {                
            /*
                Ignore if it's a function:
            */
            if ( is_function( a_package[a_property] ) )
            {
                continue; 
            }
            
			
            this.school_information[a_property] = a_package[a_property];
        }
        
        /*
            Fill the demonstrator with the content:            
        */
		var countryLink = document.createElement('a');
        var countryUrlName = this.school_information.country.url_name;
		var countryUrlNameEnglish = this.school_information.country.url_name_english;
        var cityUrlName = this.school_information.city.url_name;
		var cityUrlNameEnglish = this.school_information.city.url_name_english;
		var schoolUrlName = this.school_information.school_url_name;
		var schoolUrlNameEnglish = this.school_information.school_url_name_english;
		countryLink.href = '/'+ COUNTRY_URL_PREFIX + countryUrlName;
		countryLink.innerHTML = this.school_information.country.name;
		
		var cityLink = document.createElement('a');
		cityLink.href = '/' + COUNTRY_URL_PREFIX +countryUrlName+ '/' + CITY_URL_PREFIX + cityUrlName;
		cityLink.innerHTML = this.school_information.city.name;
		
		var schoolName = document.createTextNode(this.school_information.school.name);
		
        // create the school title
		this.school_title_span.innerHTML = '';
		this.school_title_span.appendChild(schoolName);
		this.school_title_span.appendChild(document.createTextNode(', '));
		this.school_title_span.appendChild(cityLink);
		this.school_title_span.appendChild(document.createTextNode(', '));
		this.school_title_span.appendChild(countryLink);
        //this.school_title_span.innerHTML = schoolName+', '+cityLink+', '+countryLink;
		
        
        // load the school image
        var schoolImageDiv = dojoWrapper.getById('id_school_collage');
		
        if (schoolImageDiv) {
            var schoolImage = new Image();
            schoolImageDiv.innerHTML = '';
            schoolImageDiv.appendChild(schoolImage);
            schoolImage.src = MEDIA_URL + 'location_media/country/' + countryUrlNameEnglish +'/city/' + cityUrlNameEnglish + '/school/' + schoolUrlNameEnglish + '/media/images/collage.jpg';
		}
        
        this.fill_fields();
        this.fill_sidebar();
                
        /*
            Let the user know we are finished:           
        */
        this.hide_loading();

	    /*   Show the div: */
	    this.school_demonstrator_div.style.display = '';
    };
    
	/**
	 * Function: set_course_starting_date
	 * 		sets the current course starting date and updates all the prices.
	 * 
	 * Must be public -> is called by price_calculator
	 * 
	 * @param {Object} a_course_starting_date
	 */
    this.set_course_starting_date = function(a_course_starting_date)
    {
        this.course_starting_date = a_course_starting_date;
                          
        /*
            Update all the fields, where there
            is a posibility that price change occured:
        */                                                    
        this.fill_courses();
        this.fill_accommodation_forms();
        this.fill_inscription_fee();        
        this.fill_transfer();            
		
		        
    };
	
	
    
    /**
     * Function: set_displayed_weeks
     *
     * Must be public: is called by school_demonstrator
     *
     * @param {String} Json array of the displayed weeks. 
     * The array ength must equal the number of available columns in the html template.
     * Example String: "['week2', 'week4', 'week6', 'week8', 'week10']";
     */
    this.set_displayed_weeks = function(displayed_weeks_str)
    {
        var new_displayed_weeks = dojoWrapper.evalFromJson(displayed_weeks_str);
        this.displayed_weeks = new_displayed_weeks;
        
        // updates the price tables to display the weeks defined in the variable
        // 'displayed_weeks'
        // parse the weeks as numbers
        var numWeeks = [];
        var i,j,tds;
        for (i = 0; i < this.displayed_weeks.length; i++) {
            numWeeks.push(this.displayed_weeks[i].substring(4)); // cut off 'week'
        }
        
        // courses table & material fee
        var titleRows = dojoWrapper.getElementsByClass ('course_table_title_row');
        for (i = 0; i < titleRows.length; i++) {
            tds = titleRows[i].getElementsByTagName("TD");
            for (j = 0; j < 5; j++) {
                tds[j+1].innerHTML = numWeeks[j];
            }
        }
        
        // accommodation table
        titleRows = dojoWrapper.getElementsByClass('accomodation_table_title_row');
        for (i = 0; i < titleRows.length; i++) {
            tds = titleRows[i].getElementsByTagName("TD");
            for (j = 0; j < 5; j++) {
                tds[j+1].innerHTML = numWeeks[j];
            }
        }
        
        // update the displayed information
        this.fill_courses();
        this.fill_accommodation_forms();
        this.fill_inscription_fee();
        this.fill_transfer();
    };
    
    /**
     *   Function: init
     *       Initializes the School demonstrator.                
     */  
    this.init = function()
    {
        /*
            Set the URL for fetching school information:
        */
        this.url_fetch_school = url_fetch_school;
        
        /*
             buttons with the events
            and link them with corresponding span:                           
        */
		for ( var i = 0; i < this.buttons.length; i ++ )
        {
            var a_button       = this.buttons[i];
            var a_content_span = this.content_spans[i];
            
            dojoWrapper.connect(a_button, 'onmouseover', this.handle_mouse_over_cell ); 
            dojoWrapper.connect(a_button, 'onmouseout', this.handle_mouse_out_cell );
            dojoWrapper.connect(a_button, 'onclick', this.handle_mouse_click_cell );

			a_button.corresponding_span = a_content_span;   
            a_content_span.corresponding_button = a_button;
            
            /*
                Make it more button-like with disabled property:                
            */                     
            a_button.disabled = false;
        }
        
        /*
            Make sure the init button is defined:
        */
        this.init_button = this.init_button ? this.init_button : this.buttons[0];
        
        /*
            Do we have a prefetched school?
        */
		
        if ( school_id )
        {            
            /*
                Load prefetched school:            
            */
            this.show_school(school_id, school_pkg);
        }                                 
		                    
    };
    
    this.init();
}
