/**
 * UI support for the Program Book form - responsible for price
 * calculations and custom validation
 */
Site.ProgramBook = Class.create(
    {
    
        /**
        * Creates a new instance of the ProgramBook
        * support object
        *
        * @param string formId the ID of the form to which this object
        *       will be attached
        *
        * @param Array formats a list of supported formats 
        */
        initialize : function(formId, formats) {
            this.formId = formId;
            this.form = $(formId);
            this.form.programBook = this;
            this.formats = formats;
            this.attachEvents();
            this.form.form.addValidator(
                this.validate.bind(this)
            );            
        },
        
        /**
        * Sets up event handlers
        */
        attachEvents : function() {
            $A(this.formats).each(
                function(format) {
                    Event.observe(
                        this.getFormatCheckbox(format.id),
                        'click',
                        this.updatePrice.bindAsEventListener(this)
                    );                    
                }.bind(this)
            );
        },
        
        /**
        * Returns the element into which the price will be output
        *
        * @return HTMLElement
        */
        getPriceElement : function() {
            return $(this.form.id + '-calculated-price');
        },
        
        /**
        * Returns the checkbox for the specified format ID
        *
        * @param Number formatId a format ID
        *
        * @return HTMLElement
        */
        getFormatCheckbox : function(formatId) {
            return $(this.form.id + '-formats-' + formatId);
        },
        
        /**
        * Determines whether the user has checked off the checkbox for
        * the specified format
        *
        * @param Number formatId the format ID to check
        *
        * @return Boolean
        */
        isFormatSelected : function(formatId) {
            var checkbox = this.getFormatCheckbox(formatId);
            
            var isSelected = false;
            if (checkbox) {
                isSelected = checkbox.checked;
            } 
            
            return isSelected;
        },
        
        /**
        * Recalculates the price based on the
        * checkbox selections and displays it
        */
        updatePrice : function() {
            var price = this.getPrice();
            var formattedPrice = Site.Format.currency(price);
            this.getPriceElement().update(formattedPrice);
        },
        
        
        /**
        * Calculates the price based on checkbox
        * selections
        *
        * @return Number
        */
        getPrice: function() {
            var price = 0.0;
            
            $A(this.formats).each(
                function(format) {
                    if (this.isFormatSelected(format.id)) {
                        price += parseFloat(format.price);
                    }
                }.bind(this)
            );
            
            return price;
        },
        
        /**
        * Returns the selected ad formats as an array
        *
        * @return Array
        */
        getSelectedFormats : function() {
            var selectedFormats = [];
            var formatElements = this.form.elements['formats[]'];
            $A(formatElements).each(
                function(element) {
                    if (element.checked) {
                        selectedFormats.push(element.value);
                    }
                }
            );
            
            return selectedFormats;
        },
        
        /**
        * Returns the selected ad option
        */
        getAdOption : function() {
            var optionElements = this.form.elements['ad_option'];
            var adOption = null;
            
            $A(optionElements).each(
                function(button) {
                    if (button.checked) {
                        adOption = button.value;
                        throw $break;
                    }
                }
            );
            
            return adOption;
        },
        
        /**
        * Validates the aspects of the form not handled by
        * validation (ad size, ad content)
        */
        validate : function() {
            var selectedFormats = this.getSelectedFormats();
            var valid = true;
            
            if (selectedFormats.length == 0) {
                $(this.formId + '-no-format-selected-message').show();
                valid = false;
            } else {
                $(this.formId + '-no-format-selected-message').hide();
            }            
            
            var adOption = this.getAdOption();
            if (adOption === null) {
                $(this.formId + '-no-ad-option-selected-message').show();
                valid = false;
            } else {
                $(this.formId + '-no-ad-option-selected-message').hide();
            }
            
            return valid;
        }
        
    }
);