errortimeout = null;
function Ajaxable(css){
	var self = this;
	var css = css;
	var type = null;
	
	this.error = function(o){
		alert('You need to do form.seterror(function(data){}) to override me!');
	}
	this.aftersuccess = function(){
	}
	this.aftererror = function(){
	}
	this.setdata = function(data){
		self.data = data;
	}
	this.data = function(){
	}
	this.settype = function(type){
		self.type = type;
	}
	this.seterror = function(error){
		self.error = error;
	}
	this.success = function(o){
		alert('Success!');
	}
	this.setsuccess = function(success){
		self.success = success;
	}
	this.setaftersuccess = function(success){
		self.aftersuccess = success;
	}
	this.setaftererror = function(error){
		self.aftererror = error;
	}
	this.ajaxstart = function(){
	}
	this.setajaxstart = function(ajaxstart){
		self.ajaxstart = ajaxstart;
	}
	this.ajaxend = function(){
	}
	this.setajaxend = function(ajaxend){
		self.ajaxend = ajaxend;
	}
	
	this.showerror = function(o){
		var buffer = [];
		buffer.push('<ul>');
		if (o.isstring) {
			buffer.push("<li>"+o.data+"</li>");
		}
		else {
			for (var key in o.data) {
				for (var i = 0; i < o.data[key].length; i++) {
					buffer.push("<li>" + o.data[key][i] + "</li>");
				}
			}
		}
		buffer.push('</ul>');
		buffer = buffer.join('');

		$('.error').clearQueue().html(buffer).slideDown().queue(function(){
			$(this).delay(2500).fadeOut();
			$(this).dequeue();
		});
	}
	this.register = function(){
		if(!$(css).size()) return
		$(css + ' input[type=submit]').attr('disabled', false);
		var self = this;
		var tagname = $(css).get(0).tagName.toLowerCase();
		switch(tagname)
		{	
			case 'form':
				$(css).submit(function(){
					$(css + ' input[type=submit]').attr('disabled', true);
					self.ajaxstart();			
					if ($(css).attr('enctype') == 'multipart/form-data') {
						$.ajaxFileUpload({
							'url': $(css).attr('action'),
							'secureuri': false,
							'fileElementId': $(css + ' input[type=file]').attr('id'),
							'dataType': "json",
							'error': function(){
								self.ajaxend();
							},
							'success': function(o, s){
								self.ajaxend();
								self.ajaxsuccess(o);
							}
						});
					}
					else {
						if(self.type==null) type="post";
						else				type=self.type;
						
						$.ajax({
							'url': $(css).attr('action'),
							'type': type,
							'data': $(css).serialize(),
							'dataType': 'json',
							'error': function(){
								self.ajaxend();						
								self.ajaxerror();
							},
							'success': function(o){
								self.ajaxend();
								self.ajaxsuccess(o);
							}
						});
					}
					return false;
				});
				self.seterror(function(o){self.showerror(o)});
			break;
			case 'a':
				if(type==null) type="get";
				$(css).live('click', function(){
					self.ajaxstart();
					$.ajax({
						'url': $(this).attr('href'),
						'type': type,
						'data': self.data(),
						'dataType':'json',
						'error': function(){
							self.ajaxend();
							self.error();
						},
						'success': function(o){
							self.ajaxend();
							self.ajaxsuccess(o);
						}
					});
					return false;
				});
			break;
		}
	}
	this.ajaxsuccess = function(o){
		$(css + ' input[type=submit]').attr('disabled', false);		
		if (o.error) {
			self.aftererror();
			self.error(o);
		}
		else {
			self.aftersuccess();
			switch(o.action)
			{
				case 'redirect':
					self.redirect(o.url);				
				break;
				case 'append':
					self.append(o.id,o.data);
				break;
				case 'update':
					self.update(o.id,o.data);
				break;
				case 'remove':
					self.remove(o.id);
				break;
				case 'replace':
					self.replace(o.id,o.data);
				break
				case 'msg':
					errordisplay('.error',o.msg);
				break
				default:
					self.success(o);
				break;			
			}
		}
	}
	this.ajaxerror = function(){
		alert('Error!');
	}
	this.redirect = function(url){
		window.location.href = url;
	}
	this.append = function(id,data){
		$(id).append(data);
	}
	this.remove = function(id){
		$(id).fadeOut(function(){$(this).remove();});
	}
	this.update = function(id,data){
		$(id).html(data);
	}	
	this.replace = function(id,data){
		$(id).replaceWith(data);
	}

	self.register();
}
