/*
    .---------------------------------.
    |    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>
        - dojo
        - dijit.Tooltip
    
    Author: 
        Marko Ristin
        Andreas Hermann
*/
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
    */
    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 = dojo.byId('id_div_school_demonstrator');

    /*
        Variable: school_title_span
            School title
    */        
    this.school_title_span = dojo.byId('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 = dojo.byId('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] = dojo.byId('id_school_demonstrator_comments_cell_button');
    this.buttons[1] = dojo.byId('id_school_demonstrator_introduction_cell_button');
    this.buttons[2] = dojo.byId('id_school_demonstrator_facts_cell_button');
    this.buttons[3] = dojo.byId('id_school_demonstrator_courses_cell_button');
    this.buttons[4] = dojo.byId('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] = dojo.byId('id_school_demonstrator_comments_span');
    this.content_spans[1] = dojo.byId('id_school_demonstrator_introduction_span');
    this.content_spans[2] = dojo.byId('id_school_demonstrator_facts_span');
    this.content_spans[3] = dojo.byId('id_school_demonstrator_courses_span');
    this.content_spans[4] = dojo.byId('id_school_demonstrator_accommodation_span');
    this.content_spans[5] = dojo.byId('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 = 'button_mouseover';
    };
    
    this.style_button_mouseout = function ( a_button )
    {
        a_button.className = 'button_mouseout';
    };
    
    this.style_button_selected = function ( a_button )
    {
        a_button.className = '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 && 
             this.current_button !== a_button )
        {
            this.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 !== this.current_button )
        {
            this.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;
        this.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 = dojo.byId('id_div_school_demonstrator_help');
		if (helpDiv && helpDiv.style.display == 'none') {
			//var fade_time = 500;
            //var fadeIn = dojo.fadeIn({ node: helpDiv, duration: fade_time});
            //fadeIn.play();
            dojo.style(helpDiv, "display", "");
		}
	};
	
	/**
	 * Function: hide_help
	 * 		hides the help dialog, if it exists
	 */
	this.hide_help = function()
	{
		var helpDiv = dojo.byId('id_div_school_demonstrator_help');
		if (helpDiv && helpDiv.style.display != 'none') {
			//var fade_time = 500;
			//var fadeOut = dojo.fadeOut({ node: helpDiv, duration: fade_time});
            //fadeOut.play();
            dojo.style(helpDiv, "display", "none");
		}
	};
	
	this.toggle_help = function()
	{
		var helpDiv = dojo.byId('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 = dojo.byId('id_volunteering_content');
        var show_link = dojo.byId('id_school_info_volunteering_show_link');
        var hide_link = dojo.byId('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 = dojo.byId('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 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_facts(this.school_information.fact_set, 'courses_list');
		this.fill_facts(this.school_information.fact_set, 'courses');
        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_inscription_fee();
        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()
    {   
        // fill the country, city link buttons
        var countryButton = dojo.byId('id_country_button');
        if (countryButton !== null) {
            var countryName = this.school_information.country.name;
            var countryUrlName = this.school_information.country.url_name;
            countryButton.innerHTML = countryName;
            countryButton.href = '/sprachreisen/'+countryUrlName;
            countryButton.style.display = '';
        }
        var cityButton = dojo.byId('id_city_button');
        if (cityButton !== null) {
            var cityName = this.school_information.city.name;
            var cityUrlName = this.school_information.city.url_name;
            cityButton.innerHTML = cityName;
            cityButton.href = '/sprachreisen/'+countryUrlName+'/destination/'+cityUrlName;
            cityButton.style.display = '';
        }
        
        // set map, photos button urls
        var schoolName = this.school_information.school.name;
        var schoolUrlName = this.school_information.school_url_name;
        var mapButtonLink = dojo.byId('id_map_button_link');
        if (mapButtonLink !== null) {
            mapButtonLink.href = '/sprachreisen/'+countryUrlName+'/destination/'+cityUrlName+'/landkarte/?layers=schools';
            mapButtonLink.style.display = '';
        }
        var photosButtonLink = dojo.byId('id_photos_button_link');
        if (photosButtonLink !== null) {
            photosButtonLink.href = '/sprachreisen/'+countryUrlName+'/destination/'+cityUrlName+'/'+schoolUrlName+'/schulfotos';
            photosButtonLink.style.display = '';
        }
    
		// fill links
        var school_links_span = dojo.byId('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 = dojo.byId('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 = dojo.byId('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 ()
    {
		var comment_span = dojo.byId('id_school_info_city_comment_span');
		if (comment_span !== undefined && comment_span !== null) {
			comment_span.style.display = 'none';
		}
        if ( this.school_information.city.comment &&
             this.school_information.city.comment !== '')
        {
            dojo.byId('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('January February March April May June July August September October November December').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 = dojo.byId('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('none');
        }
    };
       
    /**
     *   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 = dojo.byId('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(', ') );
            if (other_chain_cities_row !== undefined && other_chain_cities_row !== null) {
				other_chain_cities_row.style.display = '';
			}
        }
        else
        {
            // Hide other chain cities row
			if (other_chain_cities_row !== undefined && other_chain_cities_row !== null) {
            	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 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 = dojo.byId('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 = dojo.byId('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 = dojo.byId('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 = dojo.byId('id_accommodation_only_students_table');
    		if (only_students_table !== undefined && 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 !== undefined &&
    				only_students_table !== null)
                {
                    only_students_table.style.display = '';
                }
                
                var tbody = dojo.byId('id_school_info_accommodation_type_' + a_type + '_tbody');
                
                for (var j = 0; 
                      j < this.school_information.accommodation_form_set[a_type].length;
                      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 row = tbody.insertRow(j+1);
                        var rowClass = (j % 2 == 0) ? 'row1' : 'row2'; 
 		                var className = rowClass + ' accommodation_price_cell'; 
 		                 
        				// insert the course name
                        var nameCell = this.addCell(row, '', rowClass); 
 		                nameCell.innerHTML = ''; 
 		                nameCell.setAttribute('id', 'id_accommodation_link_'+ i + '_' + j); 
 		                nameCell.setAttribute('class', rowClass); 
 		                var linkCell = document.createElement('a'); 
 		                linkCell.setAttribute('class', 'school_link'); 
 		                nameCell.appendChild(linkCell); 
 		                var textCell = document.createTextNode(accommodation.name); 
 		                linkCell.appendChild(textCell); 
 		                row.appendChild(nameCell);  
                        this.fillRow(row, price, this.displayed_weeks, className);
                        this.accommodation_price_rows.push(row); 
                        
        				// create the tooltip link
        				var targetId = nameCell.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 = dojo.byId('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 = dojo.byId('id_school_info_course_type_' + a_course_type +'_tbody');
                
                for (var j = 0; j < this.school_information.course_set[a_course_type].length; 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(j+1);
                        var rowClass = (j % 2 === 0) ? 'row1' : 'row2'; 
 		                var bgColor = (j % 2 == 0) ? '#eee' : '#fff';       
 		                var className = 'course_price_cell ' + rowClass;
 
                        // create the table cell
                        var nameCell = this.addCell(row, '', rowClass); 
 		                nameCell.innerHTML = ''; 
 		                nameCell.setAttribute('id', 'id_course_link_'+ i + '_' + j); 
 		                nameCell.setAttribute('class', rowClass); 
 		                nameCell.setAttribute('bgcolor', bgColor);  
 		                var contentCell = document.createElement('a'); 
 		                contentCell.setAttribute('class', 'school_link'); 
 		                var textCell = document.createTextNode(a_course.name); 
 		                contentCell.appendChild(textCell); 
 		                nameCell.appendChild(contentCell); 
 		                row.appendChild(nameCell); 
 
                        // insert price row
                        this.fillRow(row, a_course_price, this.displayed_weeks, className);
                        this.course_price_rows.push(row);
                        
        				// create the tooltip link
        				var targetId = nameCell.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 = dojo.byId('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('All courses');
                
                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 = dojo.byId('id_volunteering_content');      
        var volunteering_not_available_text = dojo.byId('id_school_info_volunteering_not_available_text');
        var volunteering_available_text = dojo.byId('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 = dojo.byId('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 = dojo.byId('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 + 'global/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 = dojo.byId('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 dateOptions = {"datePattern": "d. MMM yy", "selector": "date"};
            var from_date_text = dojo.date.locale.format(parse_date_str(pricePeriods[i].from_date), dateOptions);
            var to_date_text = dojo.date.locale.format(parse_date_str(pricePeriods[i].to_date), dateOptions);
            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 = dojo.byId('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);
            }
        }
    };
	
    /**
     *   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 = dojo.byId('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 = dojo.byId('id_school_info_' + a_property + '_yes');
                the_corresponding_span_no  = dojo.byId('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 = dojo.byId('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 = dojo.byId('id_school_info_' + a_field_name);
		
		if (element !== null) {
			element.innerHTML = a_string;
		}
    };
	
	/**
	 * Creates a new tooltip and destroys an possibly existing tt on the same node
	 * @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 = dijit.byId('tt_'+targetId);
        if (tooltipWidget)
        {
            if (tooltipWidget.state === "displayed") {
                tooltipWidget.hide();
            }
            dojo.dom.removeNode(tooltipWidget.domNode);
            tooltipWidget.destroy();
        }
			
        // add the new tooltip 
        if (content && content !== '')
        {
            // create the tooltip content
            var tooltipDiv = document.createElement('div');
            tooltipDiv.setAttribute('class', 'price_tooltip');
            tooltipDiv.style.display = 'none';
            tooltipDiv.innerHTML = content;
	        document.body.appendChild(tooltipDiv);
            
            var options = {
                widgetId:  'tt_' + targetId,
                connectId: targetId,
                label: content
            };
            var tt = new dijit.Tooltip(options, tooltipDiv);
            tt.startup();
        }    
	};

	this.addCell = function(row, value, className)  
 	{ 
        var textNode; 
        var cell = document.createElement('td'); 
 		 
        if (value == undefined || value === null) 
        { 
            value = ''; 
        } 
        textNode = document.createTextNode(value); 
        cell.appendChild(textNode); 
               
        if (className) 
        { 
            cell.className = className; 
        } 
                 
        row.appendChild(cell); 
        return cell; 
    }; 

    /**
     * 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)
    {
        if (!fieldNames)
        {
            for(var key in data)
            {
                /*
                    Ignore functions
                */
                if ( is_function( data[key] ) )
                {
                    continue;
                }
                
                this.addCell(row, data[a_property], className);    
            }
        }
        else
        {    
            for ( var i = 0; i < fieldNames.length; i ++ )
            {
                var field = fieldNames[i];
                var val = data[field];
				this.addCell(row, val, 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 = '';
        
        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:            
                */                        
                dojo.xhrPost ( 
                {
                    url: this.url_fetch_school, /*'/price_calculator/fetch_school/',*/
                    content: { school_id: a_school_id },
                    handle: function( type, data, evt )
                            {                            
                                receive_school_info( data, a_self );
                            },
                    handleAs: 'text',
                    error: this.handle_transmit_errors
                } );
            }              	
        }              
    };                          
    
    /**
     *   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
        {
            if (typeof(data) == "string")
            {
                a_package = dojo.fromJson(data);
            }
            else if (typeof(data) == "object" && data.xhr != undefined)
            {
                a_package = dojo.fromJson(data.xhr.responseText);
            }
            else if (typeof(data) == "object")
            {
                a_package = data;
            }
            else
            {
                console.error("price_calculator_class.receive_response(): data format not recognized" + 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 );
        }
    };
    
    /**
     *   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 countryName = this.school_information.country.name;
        var cityName = this.school_information.city.name;
		countryLink.href = '/sprachreisen/'+slugify(countryName);
		countryLink.innerHTML = countryName;
		
		var cityLink = document.createElement('a');
		cityLink.href = '/sprachreisen/'+slugify(countryName)+'/destination/'+slugify(cityName);
		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 = dojo.byId('id_school_collage');
        if (schoolImageDiv) {
            var schoolImage = new Image();
            schoolImageDiv.innerHTML = '';
            schoolImageDiv.appendChild(schoolImage);
			schoolImage.width = '565';
            schoolImage.src = MEDIA_URL + 'price_calculator/images/school/'+slugify(cityName)+'_' + slugify(this.school_information.school.name) + '.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_school_material_fees();
        this.fill_inscription_fee();
        this.fill_accommodation_forms();
        this.fill_accommodation_inscription_fees();
        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 = dojo.fromJson(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'
        }
        
        // update week numbers in course & material fee elements
        var titleRows = dojo.query('.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];
            }
        }
        
        // update week numbers in accommodation table
        titleRows = dojo.query('.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_school_material_fees();
        this.fill_inscription_fee();
        this.fill_accommodation_forms();
        this.fill_accommodation_inscription_fees();
        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;
        
        /*
            Connect 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];
            
            dojo.connect(a_button, 'onmouseover', this, 'handle_mouse_over_cell'); 
            dojo.connect(a_button, 'onmouseout', this, 'handle_mouse_out_cell');
            dojo.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();
}
