// standard form handler is attached to all forms with a class of stdform
Event.observe(document, 'dom:loaded', function(){
  // find all forms that want us to look after the validation
  $$('.form-std').each(function(frm){
    if (!frm.hasClassName('form-self-manage')) {
      // use ajax to send the form?
      if (frm.hasClassName('form-ajax')) {
  	    ajaxOnSubmitEvent(frm);
      } else {
  	    standardOnSubmitEvent(frm);
      }
    }
  });
});



// standard on submit function used 
function standardOnSubmitEvent(frm) {
  frm = $(frm);

	frm.onsubmit = function() {
		// do all the validation
    if (!form_presubmit_ok(frm)) {
      // something's not happy to continue for some reason - stop the form submission
		  return false;
    }
		
		// otherwise we just let it slip through to a normal submit
		return true;
	};
}


// submit the form using ajax request
function ajaxOnSubmitEvent(frm) {
  frm = $(frm);
  
	Event.observe(frm, 'submit', function(e) {
		// stop the normal submit
		Event.stop(e);

		// is everything ok with the fields
		if (form_presubmit_ok(frm)) {
      // is this a form only for use by logged in members?
      if (frm.hasClassName('form-login-required') && !logged_in()) {
        // throw-up the login form
        request_login( function(){ finishAjaxSubmit(frm); } );
      } else {
        // we can drop straight into the submit now
        finishAjaxSubmit(frm);
      }
		}
	});
};

function finishAjaxSubmit(frm) {
  frm = $(frm);

  var params = Form.serialize(frm);

  // do the async submit
  var request = new Ajax.Request(frm.action,
  {
    asynchronous  : true, 
    parameters    : params, 
    onSuccess     : function(t) { window[frm.name+'_onSuccess'](t, frm); },
    onFailure     : function(t) { window[frm.name+'_onFailure'](t, frm); }
  });
}


function form_presubmit_ok(frm) {
  // check the form is ok to be sumbitted according to the form sepecifc validation
  if (window[frm.name+'_onSubmit'] && !window[frm.name+'_onSubmit'](frm)) {
    // nope, validation failed
    return false;
  }

  // check the required fields (unless they don't want us to)
  if (!frm.hasClassName('form-no-required')) {
    
    var requiredCheck = {};
    
    requiredCheck = check_required(frm);
    
	  // all required fields need to be filled in
		if ($H(requiredCheck).keys().length) {
		  if (window[frm.name+'_onValidationFailed'])
		    window[frm.name+'_onValidationFailed'](frm);
      else
  		  display_errors(requiredCheck);

		  return false;
		}
  }

  // everything must be ok
  return true;
}



/*
  validation helpers
*/

// attached to all forms by default
function check_required(frm) {
  frm = $(frm);
  
  // assume its all good to start with
  var response = {};

	// process the radio buttons first (if required one of them of each name needs to be checked)
	var radios = new Hash();  
	$$('#'+frm.name+' .required *').each( function(r) {
	  if (r.value != null && r.type && r.type == 'radio') {
      var last = radios.get(r.name);
      if (!last)
        radios.set(r.name, false);
      if (r.checked)
        radios.set(r.name, true);
	  }
	});
	
	// are all required fields complete?
	$$('#'+frm.name+' .required *').each( function(r) 
	{	   
	  if (r.value != null && r.type) 
	  {
	    if (r.type == 'radio' && !radios.get(r.name)) 
	    {
	      // already know this radio button has failed
	      vailidation_failed(response, r.name, 'required');
  		  error_field(r);
      // stuid fck
	    } 
	    else if (r.id.indexOf('__Config') == -1) 
	    {
	      if (Element.hasClassName(r, 'fck-field'))
	      {
	        if (FCKeditorAPI.GetInstance(r.id).GetData() == '') {
	          vailidation_failed(response, r.name, 'required');
	          error_field(r);
	        } else
	          unerror_field(r);
	      }
    		else if ('' == r.value.strip()) {
    		  vailidation_failed(response, r.name, 'required');
    		  error_field(r);
    		} else {
    		  unerror_field(r);
    		}
	    }
	  }
	});

	return response;
}

function vailidation_failed(errors, full_field_name, error_type) {
  // need to spilt the name into the model and the field name components
	if (full_field_name.split('.').size() == 1) {
		// sometimes we don't have a model
	  var model = 'default';
	  var field = full_field_name;
	} else {
	  var model = full_field_name.split('.')[0];
	  var field = full_field_name.split('.')[1];
	}

  if (!errors[model])
    errors[model] = {};

  if (!errors[model][field])
    errors[model][field] = new Array();

  errors[model][field].push(error_type);
}

// useful for registration forms
function passwords_match(frm) {
  frm = $(frm);
  // check that the password fields are identical in the given form
  passwords = frm.getInputs("password");
  // passwords must match
  if (passwords[0].value != passwords[1].value) {
    display_notification('The passwords you entered do not match.');
    // highlight the fields
    passwords.each( function (element) {
      error_field(element);
    });
    return false;
  }
  return true;
}

// standard error highlighting code - just override these if you want
function error_field(fld) {
  fld = $(fld);
  if (fld.up && fld.up('.field'))
    fld.up('.field').addClassName('error');
}
function unerror_field(fld) {
  fld = $(fld);
  if (fld.up && fld.up('.field'))
    fld.up('.field').removeClassName('error');
}

