
var FormComplete = new Class({

    Implements: Options,

    str_form_id: null,
    str_submit_selector: null,
    str_message_selector: null,
    obj_required: null,
    
    options: {
        str_button_disabled_class: 'button_disabled',           // class to apply to disabled submit elements
        str_highlight_colour: '#ff6767'                         // colour to highlight the error message for
    },



    /**
     * Constructor
     *
     * Applies listeners to the elements we're interested in in order to monitor whether or not the form
     * is valid etc.
     *
     * @param str str_form_id           ID of the form to monitor
     * @param str str_submit_selector   CSS selector for submission elements (to disable/enable)
     * @param str str_message_selector  CSS selector for the error message elements
     * @param obj obj_required          Object representing (as keys) the IDs of the input fields to monitor
     * @param obj obj_options           Object of overwritable options
     * @return void
     */
    initialize: function(str_form_id, str_submit_selector, str_message_selector, obj_required, obj_options) {
    
        this.setOptions(obj_options);
    
        this.str_form_id = str_form_id;
        this.str_submit_selector = str_submit_selector;
        this.str_message_selector = str_message_selector;
        this.obj_required = obj_required;
        
        // bind ourselves to each required component so we can validate the
        // form anytime an input changes
        for(var i in obj_required) {
            $(str_form_id).getElement('#' + i).addEvent('change', this._event_field_change.bindWithEvent(this));
        }
        
        // bind ourselves to the form submission event so we can show the warning message if the form isn't
        // submittable 
        $(str_form_id).addEvent('submit', this._event_submit.bindWithEvent(this));
        
        // hide warning message initially
        $(document.body).getElement(this.str_message_selector).fade('hide');
        
        // trigger a check now
        this._event_field_change();
    },
    
    
    
    /**
     * Event fired whenever a form field we're monitoring changes
     * Validation check is performed here.
     *
     * @return void
     */
    _event_field_change: function() {

        if(this._check_valid() == true) {
        
            this._set_submit_state(true);
        }
        else {
            
            this._set_submit_state(false);
        }
    },
    
    _check_valid: function() {
    
        var boo_all_valid = true;
    
        // check each specified element
        for(var str_id in this.obj_required) {
        
            var elm_field = $(str_id);
            var boo_valid = false;
            
            switch(elm_field.get('tag')) {
            
                case 'select':
                    boo_valid = elm_field.selectedIndex != -1 ? true : false;
                    break;
                    
                case 'input':
                    boo_valid = elm_field.value ? true : false;
                    break;
                    
                default:
                    break;
            }
            
            // break at this point for efficiency if we've found one non-completed field
            if(boo_valid == false) {
                return false;
            }
        }
        
        return true;
    },
    
    _set_submit_state: function(boo_active) {
    
        var arr_submits = $(this.str_form_id).getElements(this.str_submit_selector);
        
        for(var i = 0, ilen = arr_submits.length; i < ilen; i++) { 
            
            // flag form as invalid
            $(this.str_form_id).store('valid', boo_active);
            
            // show/fade button
            if(boo_active) {
                
                arr_submits[i].removeClass(this.options.str_button_disabled_class);
                
                // get rid of any warning message now the form is valid
                $(document.body).getElement(this.str_message_selector).fade('hide'); 
                $(document.body).getElement(this.str_message_selector).setStyle('display', 'none');
            }
            else {
                arr_submits[i].addClass(this.options.str_button_disabled_class);
            }
        }
    },
    
    
    
    /**
     * Event fired whenever the user attempts to submit the form. If it is invalid,
     * the error message is shown.
     *
     * @param obj obj_event  The event object
     * @return void
     */
    _event_submit: function(obj_event) {
        
        if($(this.str_form_id).retrieve('valid') == false) {
        
            var elm_message = $(document.body).getElement(this.str_message_selector);

            // show the message immediately
            elm_message.setStyle('display', 'block');
            elm_message.fade('show');
            elm_message.highlight(this.options.str_highlight_colour);

            // cancel the event
            obj_event.stop();
            
            return false;
        }
    }

});