var Ajax = new NameSpace({
	isavailable : function(){
		return (XMLHttpRequest || new ActiveXObject('Msxml2.XMLHttp') || new ActiveXObject('Microsoft.XMLHttp')) ? true : false;
	}
});

var Request = new Class({
	_initialize : function(p){
		if (p){
			this.extend(p);
		}
		
		var n;
		if (window.XMLHttpRequest){
			n = new XMLHttpRequest();
		} else {
			try {
				n = new ActiveXObject('Msxml2.XMLHttp');
			} catch (e){	
				try {
					n = new ActiveXObject('Microsoft.XMLHttp');
				} catch (e){
					n = new Object();
				}
			}
		}
		
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
		} catch (e){}
		
		this.extend({
			headers: new Collection({
				types : ['htmlheader'],
				
				indexes : ['name']
			}),
			
			parameters: new Collection({
				types : ['htmlparameter'],
				
				indexes : ['name'],
				
				tostring : function(){
					var s = '';
					for (var i = 0; i < this.length; i++){
						s += this[i].tostring() + ((i < this.length - 1) ? '&' : '');
					}
					
					return s;
				}
			})
		});
		
		return n;
	},
	
	_type : 'request',
	
	method : Methods.get,
	
	url : '',
	
	async : true,
	
	perform : function(){
		if (this.onrequest){
			this.onrequest();
		}
		
		this.open(this.method, this.url, this.async);		
		for (var i = 0; i < this.headers.length; i++){
			this.setRequestHeader(this.headers[i].name, this.headers[i].value);
		}
		this.send(this.parameters.tostring());
	},
	
	cancel : function(){
		this.abort();
	},
	
	onreadystatechange : function(){
		if ((this.readyState == 4 || this.readyState == 0) && this.onresponse){
			this.onresponse();
		}
	}
});

var Updater = new Class({
	_initialize : function(p){
		if (p){
			this.extend(p);
		}
		
		if (this.autostart){
			this.start();
		}
		
		this.extend({
			headers : new Collection({
				types : ['htmlheader'],
				
				indexes : ['name']
			}),
			
			parameters : new Collection({
				types : ['htmlparameter'],
				
				indexes : ['name'],
				
				tostring : function(){
					var s = '';
					for (var i = 0; i < this.length; i++){
						s += this[i].tostring() + ((i < this.length - 1) ? '&' : '');
					}
					
					return s;
				}
			})
		});
	},
	
	_type : 'updater',
	
	url : '',
	
	interval : 1000,
	
	indicator : null,
	
	start : function(){
		var x = this;
		var f = new function(){
			var r = new request({
				_owner: x,
				url: x.url,
				onrequest: function(){
					if (this._owner.indicator){
						this._owner.indicator.style.display = '';
					}
				},
				onresponse: function(){
					if (this._owner.onupdate){
						this._owner.onupdate();
					}
					if (this._owner.indicator){
						this._owner.indicator.style.display = '';
					}
				}
			});
			for (var i = 0; i < x.headers.length; i++){
				r.headers.add(x.headers[i]);
			}
			for (var i = 0; i < x.parameters.length; i++){
				r.parameters.add(x.parameters[i]);
			}
			r.perform();
		}
		this.intervalid = setInterval(f, this.interval);
	},
	
	stop : function(){
		clearInterval(this.intervalid);
	}
});

var FormStates = new NameSpace({
	ready : 'ready',
	
	busy : 'busy'
});

var FormElement = new Class({
	_initialize : function(e, p){
		if (p){ this.extend(p); }
		
		var n = new Element(e, {
			onsubmit: function(){
				this.send();
				
				return false;
			}
		});
		
		return n;
	},
	
	_state : FormStates.ready,
	
	elementnames : [],
	
	send : function(){
		if (this._state == FormStates.ready){
			this._state = FormStates.busy;
			
			var e = new Event({
				type: 'formsendevent',
				cancel: false
			});
			
			if (this.onsend){
				this.onsend(e);
			}
			
			if (!e.cancel){
				var r = new Request({
					_owner: this,
					url: this.action,
					method: this.method,
					onresponse: function(){
						if (this._owner.onpostback){
							this._owner.onpostback(this.responseText);
						}
						
						this._owner._state = FormStates.ready;
					}
				});
				r.headers.add(new HTMLHeader({name: 'Content-Type', value: contenttypes.application + '; charset=' + charsets.utf8}));
				var p = this.toparameters();
				for (var i = 0; i < p.length; i++){
					r.parameters.add(p[i]);
				}
				r.perform();
			}
		}
	},
	
	toparameters : function(){
		var e;
		var p = [];
		var v;
		for (var i = 0; i < this.elementnames.length; i++){
			v = '';
			if (e = this.getelements({name: this.elementnames[i]})){
				for (var j = 0; j < e.length; j++){
					if ((_indexof(['radio', 'checkbox'], e[j].type) > -1 && e[j].checked) || _indexof(['radio', 'checkbox'], e[j].type) < 0){						
						if (v != ''){ v += ','; }
						v += e[j].value;
					}
				}
				p.push(new HTMLParameter({name: this.elementnames[i], value: v}));
			}
		}
		
		return p;
	},
	
	tostring : function(){
		var a = this.toparameters();
		var s ='';
		for (var i = 0; i < a.length; i++){
			s += a[i].ToString();
			if (i < a.length - 1){ s += '&'; }
		}
		
		return s;
	}
});
