/*******************************************************************
 ** RUBY FORM
 ******************************************************************/
(function ($) { // protect the baby!

$.widget( "ui.rubyForm", {

    _init: function () {
	var self = this;
	
	self.element.ajaxForm( {
	    dataType     : 'json',
	    beforeSubmit : function () { 
		self._beforeSubmit.apply( self, arguments );
	    },
	    success  : function () {
		self._success.apply( self, arguments );
	    },
	    error : function () {
		self._error.apply( self, arguments );
	    }
	} );
	
	self.isInDialog = self.element.parents( '.ui-dialog' ).length > 0;	

	return;
    }, // _init

    destroy: function () {
	var self = this;

	// TODO: destroy ajaxForm ?

	$.widget.prototype.destroy.apply( this, arguments );
    }, // destroy

    _error: function () {
	var self = this;

	// Call any passed in "error" function
	self._trigger( 'error' );

	return;
    }, // _error

    _beforeSubmit: function () {
	var self = this;

	// Clear Ruby header message
	if( !self.isInDialog ) {
            self.options.set_header_message( '' );
	}

	// Clear form errors
	self._clearErrors();

	// Call any passed in beforeSubmit function
	self._trigger('beforeSubmit');

	return;
    }, // _beforeSubmit
    
    _success: function (rsp) {
	var self = this;

	if( rsp.status == 'failure' ) {
	    if( !self.isInDialog ) {
		var msg = 'Please review your information and try again.';
                self.options.set_header_message( msg, 'error' );
	    }

	    self._setErrors( rsp.errors );

            // Reload any captcha's
            if( typeof Recaptcha !== "undefined" )
                Recaptcha.reload();

	    // Trigger a "Ruby" failure
	    self._trigger( 'rubyFailure', null, { 'rsp' : rsp } );
	} // if failure
	else {
	    if( self.options.clear_form_on_success ) {
		self._clearForm();
	    }

            if( !self.isInDialog && rsp.success_msg != '' ) {
                self.options.set_header_message( rsp.success_msg, 'success' );
            }

	    // Trigger a "Ruby" success
	    self._trigger( 'rubySuccess', null, { 'rsp' : rsp } );
	}

	// Trigger a general success
	self._trigger('success');

	return;
    }, // success

    _clearForm : function () {
	this.element.map(function(){
	    return this.elements ? jQuery.makeArray(this.elements) : this;
	})
	.filter(function(){
	    return this.name && !this.disabled &&
		   (this.checked || /select|textarea/i.test(this.nodeName) ||
		    /text|password|search/i.test(this.type)); // Let's ignore hiddens so that action isn't set
	})
        .map(function(i, elem) {
            if( elem.checked ) {
                elem.checked = false;
            }
            else {
	        $(this).val( '' ).change();
            }
	});

	return;
    }, // _clearForm

    _clearErrors : function () {
	var self = this;

	$( '.ui-state-error', self.element ).html( '' ).hide();
    }, // clearErrors

    _setErrors : function (errs, prefix) {
	if( !prefix )
	    prefix = '';

	for( var key in errs ) {
	    var err = errs[key];

	    if( typeof err === 'object' ) {
		this._setErrors( err, prefix + key + '.' );
	    }
	    else {
		// id could have "." which will not work with jQuery
		var id    = prefix + key + '-field';
		var field = $( document.getElementById( id ) ); 

		var errBox = $( '.ui-state-error', field );
		if( errBox.length <= 0 ) {
		    field.append( '<dd class="ui-state-error"></dd>' );

		    errBox = $( '.ui-state-error', field );
		}
		
		errBox.html( err ).show();
	    } // if string
	} // foreach error
    } // _setErrors

}); // $.widget

$.extend( $.ui.rubyForm, { 
    version: "1.0",
    defaults: {
	clear_form_on_success : false,
        set_header_message : function (msg, type) { 
            $(window).ruby( 'headerMsg', msg, type );
        }
    }
});

})(jQuery); // function($)

