function ajaxForm2(form,onAjaxSuccess,indicator,beforeRequest) {
	form = $(form);
	Event.observe(form,'submit',function(e){
		var form = this;
		if( indicator ) $(indicator).show();
		
		//clear previous entries
		form.select('div.error-message').each(Element.remove);
		form.select('.form-error').invoke('removeClassName','form-error');
		
		if( beforeRequest && !beforeRequest()) {
			if( indicator ) $(indicator).hide();
			return;
		}
		
		new Ajax.Request(form.action,{
			method: form.method,
			parameters: form.serialize(),
			onSuccess: function(reply) {
				var res = reply.responseText;
				if( res.isJSON()) {
					var json = res.evalJSON();
					if( json[0] && json[0] == 'r' ) {
						switch(json[1][0]) {
						case 'good':
							if( onAjaxSuccess ) onAjaxSuccess(json[1][0]);
							form.reset();
							break;
						case 'dberr':
							alert('Error: Database error');
							break;
						case 'validation':
							for( var name in json[1][1] ) {
								var t = form.select('*[name^="'+name+'"]');
								if( t.length > 0 ) {
									t.invoke('addClassName','form-error');
									t.last().up(1).down().insert(new Element('div').addClassName('error-message').update(json[1][1][name]));
								}
								else alert('error: validation failed, but no fields match: '+res);
							}
							break;
						case 'no_data':
							alert('No data was sent');
							break;
						default:
							alert('Error: '+res);
							break;
						}
					}
					else alert('Error: '+res);
				}
				else alert('Error: '+res);
			},
			onFailure: function(reply) {
				alert('HTTP Error on ajax call: '+reply.status+' '+reply.responseText);
			},
			onComplete: function() {
				if( indicator ) $(indicator).hide();
			}
		});
		Event.stop(e);
	});
}

/**
 * Fill a select box by quering using Ajax
 * @param select the object or id of the select box
 * @param options the key,value array of the options to fill it with
 */
function ajaxSelectOptions(selectBox, url) {
	selectBox = $(selectBox);
	
	new Ajax.Request(url,{
		method: 'GET',
		onSuccess: function(reply) {
			var res = reply.responseText;
			if( res.isJSON()) {
				var json = res.evalJSON();
				if( json[0] && json[0] == 'r' ) {
					Element.childElements(selectBox).each(Element.remove);
					if(!isArray(json[1])) {
						for( var value in json[1] ) {
							selectBox.insert(new Element('option',{value:value}).update(json[1][value]));
						}
					}
				}
				else alert('Error: '+res);
			}
			else alert('Error: '+res);
		},
		onFailure: function(reply) {
			alert('HTTP Error on ajax call: '+reply.status+' '+reply.responseText);
		}
	});
}

/**
* onchange function for the calendar_date_select
*/
Event.observe(document, 'dom:loaded', function(){
	$$('.datePopup').each(function(obj){
		if( obj )
			obj.observe('click',function(){
				//update the date first
				var date = new Date().set({
					year:parseInt(this.previous().getValue()),
					day:parseInt(this.previous(1).getValue()),
					month:parseInt(this.previous(2).getValue())-1
				});
				this.next().setValue(date.toString());			
				
				//display the calendar
				new CalendarDateSelect( this.next(), {onchange:datePopup_change} );
			});
	});
	
	//put the cursor in the first input box, if there is one
	var firstInput = $$('textarea:first-of-type,input[type=text]:first-of-type');
	if( firstInput && (firstInput = firstInput.first()) ) firstInput.focus();
	
	//if there were validation errors, scroll to the first one
	var error = $$('.error-message:first-of-type');
	if( error = error.first()) error.up('form').scrollTo();
});

function datePopup_change() {
	var date = new Date(this.getValue());
	this.previous(1).setValue(date.toString('yyyy'));
	this.previous(2).setValue(date.toString('dd'));
	this.previous(3).setValue(parseInt(date.toString('MM')));
}

var Popup = {
	initialize: function(options) {
		this.options = {
			url: '#',
			width: 400,
			height: 500,
			scrollbars: 'no',
			menubar: 'no',
			resize: 'yes',
			toolbar: 'yes'
		};
		Object.extend(this.options, options || {});
		window.open(this.options.url, '',
			'width='+this.options.width+
			', height='+this.options.height+
			', scrollbars='+this.options.scrollbars+
			', resize='+this.options.resize+
			', menubar='+this.options.menubar+
			', toolbar='+this.options.toolbar
		);
	}
};