

Orderform = {
    
    init: function() {

        //////////////////
        // Setup Tables //
        //////////////////
        
        var tables = $$('table.Theme');
        var table;
        for (var i = 0, u = tables.length; i < u; ++i)
        {
            table = tables[i];
            table.total = 0;
            table.calculateTotal = this.calculateTableTotal;   
        }
    
    
        //////////////////////////
        // Setup Totalbale Rows //
        //////////////////////////
        
        var rows = $$('table.Theme tbody tr');
        var row;
        for (var i = 0, u = rows.length; i < u; ++i)
        {
            row = rows[i];
            row.total = 0;
            row.calculateTotal = this.calculateRowTotal;
        }

    
        ///////////////////////////
        // Setup Quantity Fields //
        ///////////////////////////
        
        var fields = $$('table.Theme input.Qty');
        var field;
        for (var i = 0, u = fields.length; i < u; ++i)
        {
            field = fields[i];
            field.lastValid = 0;
            field.observe('change', this.handleQtyUpdate);   
        }
    
    
        ///////////////////////////
        // Do a full calculation //
        ///////////////////////////
    
        this.calculateGrandTotal(true);
    
    },
    
    
    // -------------------------------------------------------------------------
    
    currency: function(num) {
        
        num = num + '';
        
        var formatted = '';
        var nextChar;
        
        for (var i = 0, u = num.length; i < u; ++i)
        {
            nextChar = num.charAt(u - i - 1);
            if ( (i + 1 < u) && ( (i + 1) % 3 == 0) )
                formatted = ',' + nextChar + formatted;
            else
                formatted = nextChar + formatted;
        }
        
        formatted = '$' + formatted;
        
        return formatted;
            
    },
    
    
    
    
    // -------------------------------------------------------------------------
    
    // Perform a top-down total calculation.
    calculateGrandTotal: function(full) {

        // Perform a full calculation.
        if (full)
        {
            // Calculate the rows.
            var rows = $$('table.Theme tbody tr');
            for (var i = 0, u = rows.length; i < u; ++i)
                rows[i].calculateTotal();
                
            // Calculate the tables.
            var tables = $$('table.Theme');
            for (var i = 0, u = tables.length; i < u; ++i)
                tables[i].calculateTotal();
        }
                                
        var grandTotal = 0;
        
        var tables = $$('table.Theme');
        for (var i = 0, u = tables.length; i < u; ++i)
            grandTotal += tables[i].total;
        
        
        $('GrandTotal').value = this.currency(grandTotal);
        
    },
    
    
    
    
    
    // -------------------------------------------------------------------------
    
    // BINDING:
    // this = table.Theme tbody tr
    //
    // Caluclates the total cost for a row based on the number of units filled
    // in inside the text fields and the unit price provided in the .Price td.
    //
    // Updates the .total member and displays the new total for the row.
    // 
    calculateRowTotal: function() {
        
        // Determine the price for the row.
        var priceCell = this.select('td.Price')[0];
        var unitPrice = parseFloat(priceCell.innerHTML);
        
        // Sum the units in each field.
        var units = 0;
        var fields = this.select('input.Qty');
        
        for (var i = 0, u = fields.length; i < u; ++i)
            if (fields[i].value != '')
                units += parseInt(fields[i].value);
            
        // Multiply the total (number of units) by the unit price.
        this.total = units * unitPrice;
        
        // Update the display.
        var totalCell = this.select('td.Total').last();
        totalCell.update(Orderform.currency(this.total));
        
    },
    
    // BINDING:
    // this = table.Theme
    //
    // Caluclates the total cost for a row based on the number of units filled
    // in inside the text fields and the unit price provided in the .Price td.
    //
    // Updates the .total member and displays the new total for the row.
    //
    calculateTableTotal: function() {

        // Sum the totals of the rows.
        this.total = 0;
        var rows = this.select('tbody tr');
        for (var i = 0, u = rows.length; i < u; ++i)
            this.total += rows[i].total;    

        // Update the display.
        var totalCell = this.select('tfoot .Total')[0];
        totalCell.update(Orderform.currency(this.total));        

    },
    
    
    // -------------------------------------------------------------------------
    // Event Handlers
    
    handleQtyUpdate: function(e) {
    
        var elem = Event.element(e);
        
        // Value is an integer.
        if (elem.value == '' || elem.value == parseInt(elem.value))
        {
            if (elem.value == '' || elem.value < 0)
                elem.value = '0';
            
            // Store this as a valid value.
            elem.lastValid = elem.value;
            
            // Calculate the row's total.
            var row = elem.up('tr');
            row.calculateTotal();
            
            // Calculate this table's total.
            var table = row.up('table');
            table.calculateTotal();
            
            // Calculate the grand total.
            Orderform.calculateGrandTotal();
            
        }
        else
            elem.value = elem.lastValid;
                       
    }
    
        
};



// -----------------------------------------------------------------------------

document.observe('dom:loaded', function() {
    Orderform.init();
});

