var JsonRPCForm = Class.create({
    initialize: function(form, options) {
        this.options = Object.extend({
            method: 'post',
            onSuccess: function(){},
            onFailure: function(){},
			onErrors: function (){},
            msgLoading: 'Saving...',
            msgError: 'An unexpected error occurred. Please try again.',
            msgFailure: 'Failed!',
            msgComplete: 'Complete.'
        }, options || {});

        this.form = $(form);
		if (!this.form) {
			return null;
		}
        this.form._RPC_HANDLER_ = this;

        /* below also found in  FormHandler */
        
        if (!this.form.messages) {
            if( this.form.down('.error_messages') ){
                this.form.messages = this.form.down('.error_messages');
            } else if ( $(document.body).down('.error_messages') ) {
                this.form.messages = $(document.body).down('.error_messages');
            } else {
                this.form.messages = undefined;
            }
        }  
        if (!this.form.progress) {
            if (this.form.down('.progress')){
                this.form.progress = this.form.down('.progress');
            } else {
                this.form.progress = undefined;
            }
        }
		
        this.form.observe(
            'submit',
            function(evt){
                evt.stop();
                var form = evt.element();
                var rpc_handler = form._RPC_HANDLER_;
                
                var action = '/rpc' + form.action.parseUri().path;
				var params = form.serialize(true);
				
                var form_handler = form.findDefinition('FormHandler');
                if (form_handler) {
                    var validator = form_handler.validation;
                    var valid = validator.validate();
                    if (!valid) return;
                }
                
		        new Ajax.Request(
							action,
							{
								method: rpc_handler.options.method,
								parameters: params,
                                
								onLoading: function (transport) {
					                if (form.progress) {
					                    form.progress.innerHTML = rpc_handler.options.msgLoading;
					                }
									rpc_handler._clearErrors();				
								},
                        
								onFailure: function (transport) {
					                if (form.progress) {
					                    form.progress.innerHTML = rpc_handler.options.msgError;
					                }
                                    rpc_handler._handleErrors( [{
                                        key: '_BOOM_',
                                        text: rpc_handler.options.msgError
                                    }] );
									rpc_handler.options.onFailure();
								},
                        
								onComplete: function (transport){
									var result = transport.responseText.evalJSON()[0];
									if (result.error && result.error.messages.length) {
										// error condition
										rpc_handler._handleErrors( result.error.messages );
										rpc_handler.options.onErrors();
									} else {
										// success condition
						                if (form.progress) {
						                    form.progress.innerHTML = rpc_handler.options.msgComplete;
                                        }
                                        rpc_handler.options.onSuccess(result);
									}									
								}
                                
							}
				);
                
            }

        );

    },
    
	_clearErrors: function () {
		var form = this.form;
        form.messages.select('li').each(function(e){e.hide()});
	},
    
	_handleErrors: function (a_mes) {
        var form = this.form;

        if (form.progress) {
            form.progress.innerHTML = this.options.msgError;
        }	
        	
		if (form.messages) {
			a_mes.each(function(m){
				var k=m.key.split(/\./);
				switch (k.length)
				{
					case 1:
					// no form or field passed - generic error
						var _id = k[0];
						var _text = m.text;
						if ($(_id)) {
							$(_id).show();
						} else {
							form.messages.insert('<li id="' + _id + '">' + _text + '</li>');
						}
                        form.messages.show();
						break;
					
					case 3:
					// got form and field name with key - specific error
						var _id = 'advice--' + k[0].toLowerCase() + '--form--' + k[2] + '--field--' + k[1];
						var _text = m.text;
						if ($(_id)) {
							$(_id).show();
						} else {
                            form.messages.insert('<li id="' + _id + '">' + _text + '</li>');            
						}
                        form.messages.show();					
						break;
					
					default:
					// what ?!?!
						alert('You got a really strange result.. punting!');
				}
				
			});
		} else {
			alert(' Please add a error message block for ' + form.id );
		}
	}
});
