/*
    .---------------.
    |   Cart class  |
    *---------------*
    
    Class: Cart
        Represents a ware cart in the course booking process.
    
    Author: 
        Marko Ristin
    
    Requires:
        - <Ware_class.js>
        - <utilities.js>
    
    Changelog:
        - 2007-02-09, mrstin, Initial Version, mristin
        - 2007-08-16, ahermann, reformatted comments
        - 2007-11-16, ahermann, adapted to takeoff-english
        - 2007-11-21, ahermann, added cookie saving/loading
*/    
function Cart ()
{
    /*extern dojo */
    
    /*extern a_money_exchange, a_price_calculator */
    
    /*extern format_string, attach_hidden_field_to_form */
    
    /*extern Ware */

    /*
        Properties:
    */
    this.wares = [];      /* wares in the cart, array of instances of Wares */                                
    
    this.table = dojoWrapper.getById('id_cart_table');     /* table with ware entries */
    this.cart_div = dojoWrapper.getById('id_div_cart');
    this.form = dojoWrapper.getById('id_cart_form');
    
    this.ware_description_template = dojoWrapper.getById('id_cart_ware_description_template');
    
    this.remove_image = dojoWrapper.getById('id_cart_ware_remove_from_cart_image' );
    this.remove_image_onmouseover = dojoWrapper.getById('id_cart_ware_remove_from_cart_image_onmouseover');
    this.remove_caption = dojoWrapper.getById('id_cart_ware_remove_from_cart_link_caption');
	
    this.warning_div = dojoWrapper.getById('id_cart_please_select_an_offer_warning');
    
    this.checkboxes          = [];
    this.selected_checkboxes = [];
    
    /*  Max. number of wares selected: */
    this.max_selected = 2;
	
	/* waiting dialog widget */
	var waiting_widget = dojoWrapper.getById('id_waiting_div');
    
    /**
     * Function: add_ware
     *   Adds the ware to the cart and display it in the table.
     *   If it is the first entry, it makes the div appear.
     *   
     *   Parameters:
     *       a_ware - json object
     * @param {Object} a_ware
     */
    this.add_ware = function(a_ware) 
    {	
        /*
            Add id:
        */
		
        a_ware.id = this.wares.length;
        this.wares.push(a_ware);

        var a_new_row = this.table.insertRow(this.table.rows.length);
        a_new_row.ware = a_ware;
       
        /*
            Fill in the formatted cells
            and process template:
        */
        var a_template = this.ware_description_template.innerHTML;                  
        a_template = a_template.replace(/^\s*<!--\s*/, '');                 
        a_template = a_template.replace(/-->\s*$/, '');

        var a_ware_description = format_string(a_ware, a_template);
		
		 var a_ware_description_cell = a_new_row.insertCell(0);
		 a_ware_description_cell.colSpan = "4";
		
		var a_second_new_row = this.table.insertRow(this.table.rows.length);
		a_second_new_row.className = 'second_row';
		
        var a_ware_remove_control_cell = a_second_new_row .insertCell(0);
        var a_ware_checkbox_control_cell = a_second_new_row .insertCell(0);	
        var a_ware_price_cell = a_second_new_row.insertCell(0);	
        var a_ware_currency_cell = a_second_new_row.insertCell(0);
        
        a_ware_description_cell.className 	= 'ware_description_cell';
        a_ware_currency_cell.className = 'ware_currency_cell';
        a_ware_price_cell.className = 'ware_price_cell';
        a_ware_checkbox_control_cell.className = 'ware_checkbox_control_cell';
        a_ware_remove_control_cell.className = 'ware_remove_control_cell';

        /*
                Fill in the description:
        */
        a_ware_description_cell.innerHTML = a_ware_description;
        
        // TODO: find a smarter solution
        // hide string if no accommodation is booked
        var acc_div = dojoWrapper.getById('id_cart_ware_'+a_ware.id);
        if (a_ware.accommodation_weeks == 0 && acc_div)
        {
            acc_div.style.display = 'none';
        }

        /*
            Fill in the price:
        */
        a_ware.price_cell = a_ware_price_cell;
        a_ware.currency_cell = a_ware_currency_cell;
        
        var an_update_function_for_ware_price = 
            function (a_self) // a_self is a_ware ! 
            {
                var a_ware_price = a_self.total_price;
				
				if (a_money_exchange.locale_currency)
				{    
                    var a_ware_locale_price = a_money_exchange.to_locale_currency(a_self.school_currency_abb, a_ware_price );
                    var a_ware_price_str = a_money_exchange.amount_to_str(a_ware_locale_price);
                    
                    a_self.currency_cell.innerHTML = a_money_exchange.locale_currency.abbreviation.toUpperCase();
				    a_self.price_cell.innerHTML = a_ware_price_str;
                }
                // the ware could have restored from a cookie, 
                // and no local currency is set yet in the price calculator
                else
                {
                    var a_ware_locale_price = a_money_exchange.exchange(a_self.school_currency_abb, a_self.locale_currency_abb, a_ware_price );
                    var a_ware_price_str = a_money_exchange.amount_to_str(a_ware_locale_price);
                    
                    a_self.currency_cell.innerHTML = a_self.locale_currency_abb;
				    a_self.price_cell.innerHTML = a_ware_price_str;
                }
            };
        
        a_money_exchange.sign_up_object_for_update( a_ware, an_update_function_for_ware_price );
		                   
        /*
            Update price cells content
            according to locale currency:            
        */
        a_money_exchange.update_signed_up_objects();
               
        /*
            Add checkbox to control cell:
        */
        var a_checkbox = document.createElement('input');
        a_checkbox.type = 'checkbox';
        a_checkbox.name = 'ware' + a_ware .id;
        
        // copy the ware, and edit
        var wareData = this.prepareWare(a_ware);
        a_checkbox.value = dojoWrapper.serializeToJson(wareData);
        a_checkbox.className = 'ware_checkbox';
        a_checkbox.a_self = this;
        this.checkboxes.push(a_checkbox);
        a_ware_checkbox_control_cell.appendChild(a_checkbox);
        		
        /*
            Attach checkbox to row as well:
        */        		
        a_new_row.checkbox = a_checkbox;

        /*
            Add remove button in control cell:
        */
        var a_remove_from_cart_button = document.createElement('img');
        a_remove_from_cart_button.corresponding_row = a_new_row;
        a_remove_from_cart_button.a_self = this;
        a_remove_from_cart_button.src = this.remove_image.src;
        a_remove_from_cart_button.title = 'Angebot löschen';
        a_ware_remove_control_cell.appendChild(a_remove_from_cart_button);

        /*
                Connect remove button and 
                checkbox with corresponding event handlers:
        */
		var agent1 = function ( evt )
		{
			evt.target.a_self.remove_row ( a_new_row ); 
		}
		
		var agent2 = function ( evt )
		{
			var a_self = evt.target.a_self;
                                
            evt.target.style.cursor = 'pointer';
        	evt.target.src = a_self.remove_image_onmouseover.src; 
		}
		
		var agent3 = function ( evt )
		{
			evt.target.a_self.handle_checkbox_change ( evt.target ); 
		}
        dojoWrapper.connect ( a_remove_from_cart_button, 'onclick', agent1 );
        
        dojoWrapper.connect( a_remove_from_cart_button, 'onmouseover', agent2 );                     
                                          
        dojoWrapper.connect ( a_checkbox, 'onclick', agent3 );
		
        /*
            Make the div appear if there are entries:
        */
        if ( this.wares.length )
        {
            this.cart_div.style.display = '';
        }
		
    };
    
    
    /*
        Function: remove_row
        Removes the row and the corresponding ware
        
        Parameters:
            a_row: The row to remove
    */
    this.remove_row = function ( a_row )
    {            
        /*
            Remove the checkbox from the selected_checkboxes:
        */
        var a_checkbox = a_row.checkbox;
        
        for ( var i = 0; i < this.selected_checkboxes.length; i ++ )
        {
            if ( this.selected_checkboxes[i] === a_checkbox )
            {
                this.selected_checkboxes.splice ( i, 1 );
            }
        }
        
        /*
            Remove the ware:
        */
        this.remove_ware( a_row.ware );
        
        /*
            Remove the row:
        */
        this.table.deleteRow( a_row.rowIndex );
		this.table.deleteRow ( a_row.rowIndex + 1);
        
    };
    
    /*
        Function: remove_ware
        Removes a ware from the cart and updates the table.
        If there are no wares in the cart, it hides the cart and 
        shows the book button of price calculator.
        
        Parameters:
            a_ware: The ware to remove
    */
    this.remove_ware = function ( a_ware )
    {
        /*
            Find the ware:
        */
        for ( var i = 0; i < this.wares.length; i ++ )
        {
            if ( this.wares[i] === a_ware )
            {
                /*
                    Remove the ware:
                */
                this.wares.splice ( i, 1 ); 
                break;
            }
        }
                                
        if ( !this.wares.length )
        {
			
            //a_price_calculator.book_button.setDisabled( false );
            this.cart_div.style.display = 'none';
        }
        
        // save the changes
        this.save();
    };
    
    
    /*
        Function: handle_checkbox_change
        	Handles clicks on a_checkbox.   
        	If there are more than max. selected checkboxes,
        	the last one will be deselected and this one will be selected.
        
        Parameters:
            a_checkbox - The current checkbox
    */
    this.handle_checkbox_change = function ( a_checkbox )
    {        
        if ( a_checkbox.checked )
        {                
            /*
                Checkbox is selected:
            */
            this.selected_checkboxes.push( a_checkbox );
            
            if ( this.selected_checkboxes.length > this.max_selected )
            {
                /*
                    We have to take the last checked out 
                    and add this one:
                */
                this.selected_checkboxes[0].checked = false;
                this.selected_checkboxes.splice ( 0, 1 );                                        
            }
            
            /*
                Make the warning disappear, if there's any:                    
            */
            this.warning_div.style.display = 'none';
        }
        else
        {
            /*
                Checkbox is deselected,
                take it out of selected checkboxes array:
            */
            for ( var i = 0; i < this.selected_checkboxes.length; i ++ )
            {
                if ( this.selected_checkboxes[i] === a_checkbox )
                {
                    this.selected_checkboxes.splice ( i, 1 );
                }
            }
        }
    };
    
    /*
        Function: show_the_booking
        	Redirects the user to the booking page.
        	If there are no wares selected, it warns the user.
    */
    this.show_the_booking = function ()
    {

        if ( !this.selected_checkboxes.length )
        {
            this.warning_div.style.display = '';
        }
        else
        {

            // create a json package out of all wares
            var a_package = [];
            for ( var i = 0; i < this.selected_checkboxes.length; i ++ )
            {
                var obj = dojoWrapper.evalFromJson (this.selected_checkboxes[i].value);
                a_package.push(obj);
            }

            var ware_pkg = dojoWrapper.serializeToJson(a_package);
            
            // save the selected currency
            var locale_currency_abb = null;
            if (a_money_exchange.locale_currency)
            {
                locale_currency_abb = a_money_exchange.locale_currency.abbreviation;
            }   
            else
            {
                locale_currency_abb = dojoWrapper.getCookie ("locale_currency_abb");
            }
            a_price_calculator.submit(ware_pkg, locale_currency_abb);
        }
    };
    
    /*
     * deletes unserialize properties 
     * -> dojo cannot serialize an object if it contains
     * references to html elements, td's, tr's...
    */
    this.prepareWare = function(a_ware)
    {
        var wareData = copy_an_object(a_ware, true);
        wareData.price_cell = null;
        wareData.currency_cell = null;
        return wareData;
    };
    
    /**
     * Restores the content of the cart from the last visit
     * by loading the data from a cookie
     */
    this.load = function()
    {
        var cookie = dojoWrapper.getCookie("wareData");
		

        if (cookie)
        {
            var wareData = dojoWrapper.evalFromJson(cookie);
            //this.wares = wareData;
            for (var i=0; i<wareData.length; i++)
            {
                if (typeof(wareData[i]) === 'object')
                {
                    this.add_ware(wareData[i]);
                }
            }
        }
    }
    
    /**
     * Saves the content of the cart into a cookie
     *
     */
    this.save = function()
    {
        // save all wares
        if (this.wares)
        {
            var wareData = [];
            for (var i=0; i<this.wares.length; i++)
            {
                var a_ware = this.wares[i];
                wareData.push(this.prepareWare(a_ware));
            }
            var wareDataStr = dojoWrapper.serializeToJson(wareData);
            dojoWrapper.setCookie ("wareData", wareDataStr, 30, '/sprachreisen/englischschulen/preisrechner');
        }
        
        // save the locale currency
        if (a_money_exchange.locale_currency)
        {
        	dojoWrapper.setCookie ("locale_currency_abb", a_money_exchange.locale_currency.abbreviation, 30);
        }
    }
    
    /*
        Function: init
        Initializes the cart
    */
    this.init = function ()
    {
        this.load();
    };
    
    this.init ();
}
