var iselement = function(x){
	return (typeof x == 'object' && x.tagName && x.nodeType);
}

var getelements = function(x, p){
	var e = x.getElementsByTagName('*');
	var r = [];
	var s;
	
	for (var i = 0; i < e.length; i++){
		s = true;
		
		for (var a in p){
			if (e[i][a] != p[a]){
				s = false;
			}
		}
		
		if (s){
			r.push(e[i]);
		}
	}
	
	return r;
}

var getelement = function(x, p){
	var e = x.getElementsByTagName('*');
	var s = true;
	
	for (var i = 0; i < e.length; i++){
		s = true;
		
		for (var a in p){
			if (e[i][a] != p[a]){
				s = false;
			}
		}
		
		if (s){
			return e[i];
		}
	}
}

var setstyle = function(x, s){
	if (s['float']){
		if (typeof x.style.cssFloat != 'undefined'){
			s['cssFloat'] = s['float'];
		} else {
			s['styleFloat'] = s['float'];
		}
		delete s['float'];
	}
	
	if (s.opacity){
		if (!x.style.opacity){
			if (x.style.MozOpacity){
				s.MozOpacity = s.opacity / 100;
			} else {
				s.filter = 'alpha(opacity=' + s.opacity + ')';
			}
			delete s.opacity;
		} else {
			s.opacity = s.opacity / 100;
		}
	}
	
	_extend(x.style, s);
}

_extend(document, {
	_initialize : function(){
		var f = function(){
			if (isnumber(window.innerWidth) && isnumber(window.innerHeight)){
				document.extend({width: window.innerWidth, height: window.innerHeight});
			} else if (document.body && isnumber(document.body.clientWidth) && isnumber(document.body.clientHeight)){
				document.extend({width: document.body.clientWidth, height: document.body.clientHeight});
			} else if (document.documentElement && isnumber(document.documentElement.clientWidth) && isnumber(document.documentElement.clientHeight)){
				document.extend({width: document.documentElement.clientWidth,  height: document.documentElement.clientHeight});
			}
		}
		
		setInterval(f, 1);
	},
	
	extend : function(p){
		_extend(this, p);
	},
	
	_observer : new Observer({
		autostart: true,		
		properties: {width: 0, height: 0},		
		actions: {
			width: function(){ if (this.onresize){ this.onresize(); } },			
			height:	function(){ if (this.onresize){ this.onresize(); } }
		}
	}),
	
	width : 0,
	
	height: 0,
	
	redirect : function(u){
		window.location.href = u;
	},
	
	getelement : function(p){
		return getelement(this, p);
	},
	
	getelements : function(p){
		return getelements(this, p);
	},
	
	addlistener : function(e, f){
		addlistener(this, e, f);
	},
	
	removelistener : function(e, f){
		removelistener(this, e, f);
	},
	
	enableselection : function(){
		var x = this.getelement({tagName : 'BODY'});
		
		if (typeof x.onselectstart != 'undefined'){
			x.onselectstart = null;
		} else if (typeof x.style.MozUserSelect != 'undefined'){
			x.style.MozUserSelect = '';
		} else {
			x.onmousedown = null;
		}
	},
	
	disableselection : function(){
		var x = this.getelement({tagName : 'BODY'});
		
		if (typeof x.onselectstart != 'undefined'){
			x.onselectstart = function(){return false;}
		}else if (typeof x.style.MozUserSelect != 'undefined'){
			x.style.MozUserSelect = 'none';
		}else{
			x.onmousedown = function(){return false;}
		}
	},
	
	cookies : new Collection({
		types : ['cookie'],
		
		indexes : ['name'],
		
		readall : function(){
			this.cookies.clear();
			var c = document.cookie.split('; ');
			for (var i = 0; i < c.length; i++){
				this.cookies.add(new Cookie({name: c[i].substring(0, c[i].indexOf('=')), value: c[i].substring(c[i].indexOf('=') + 1)}));
			}
		},
		
		writeall : function(){
			for (var i = 0; i < this.cookies.length; i++){
				this[i].write();
			}
		}
	})
});
document._initialize();

var Mouse = new NameSpace({
	_initialize : function(){
		document.addlistener('mousemove', function(e){
			if (!e){ e = event; }
			
			if (e.clientX && e.clientY){
				Mouse.extend({
					x: (e.clientX + (document.documentElement ? document.documentElement.scrollLeft : document.body.scrollLeft)),
					y: (e.clientY + (document.documentElement ? document.documentElement.scrollTop : document.body.scrollTop))
				});
			} else if (e.pageX && e.PageY){
				Mouse.extend({
					x: e.pageX,
					y: e.pageY
				});
			}
		});
	},
	
	x : 0,
	
	y : 0
});

var Methods = new NameSpace({
	post : 'POST',
	
	get : 'GET'
});

var ContentTypes = new NameSpace({
	text : 'text/plain',
	
	html : 'text/html',
	
	css : 'text/css',
	
	xml : 'text/xml',
	
	png : 'image/png',
	
	gif : 'image/gif',
	
	jpeg : 'image/jpg',
	
	audio : 'audio/basic',
	
	mpeg : 'video/mpeg',
	
	multipart : 'multipart/form-data',
	
	application : 'application/x-www-form-urlencoded'
});

var Charsets = new NameSpace({
	utf8 : 'UTF-8',
	
	utf16 : 'UTF-16',
	
	windows1254 : 'windows-1254',
	
	iso88591 : 'iso-8859-1'
});

var HTMLHeader = new Class({
	_initialize : function(p){
		if (p){
			this.extend(p);
		}
	},
	
	_type : 'htmlheader',
	
	name : '',
	
	content : ''
});

var HTMLParameter = new Class({
	_initialize : function(p){
		if (p){
			this.extend(p);
		}
	},
	
	_type : 'htmlparameter',
	
	name : '',
	
	value : '',

	tostring : function(){
		return escape(this.name) + '=' + escape(this.value);
	}
});

var Cookie = new Class({
	_initialize : function(p){
		if (p){
			this.extend(p);
		}
		
		this.extend({
			parameters : new Collection({
				types : ['htmlparameter'],
				
				indexes : ['name'],
				
				read : function(){
					this.prameters.clear();
					var p = this.value.split('&');
					for (var i = 0; i < p.length; i++){
						this.parameters.add(new htmlparameter({name: p[i].substring(0, p[i].indexOf('=')), value: p[i].substring(p[i].indexOf('=') + 1)}));
					}
				},
				
				write : function(){
					this.value = this.tostring();
				},
				
				tostring : function(){
					var s = '';
					for (var i = 0; i < this.length; i++){
						s += this[i].tostring() + ((i < this.length - 1) ? '&' : '');
					}
					
					return s;
				}
			}),
			
			_observer : new observer({
				autostart: true,
				
				properties: {value: ''},
				
				actions: {
					value: function(){
						this.parameters.read();
					}
				}
			})
		});
		
		this.read();
		this.parameters.read();
	},
	
	_type : 'cookie',
	
	name : '',
	
	value : '',
	
	expires : null,
	
	path: '/',
	
	domain : '',
	
	secure : false,
	
	read :function(){
		var c = document.cookie.split('; ');
		
		for (var i = 0; i < c.length; i++){
			if (c[i].substring(0, this.name.length) == this.name){
				this.value = c[i].substring(this.name.length + 1);
			}
		}
	},
	
	write : function(){		
		document.cookie = this.tostring();
	},
	
	remove : function(){
		var x = this.expires;
		this.expires = new Date(1900, 0, 1, 2, 0, 0);
		document.cookie = this.tostring();
		this.expires = x;
	},
	
	tostring : function(){
		return this.name + '=' + this.value + (this.expires ? '; expires=' + this.expires.toGMTString() : '') + (this.path != '' ? '; path=' + this.path : ''); // + (this.domain != '' ? '; domain=' + this.domain : '') + (this.secure ? '; secure' : '');
	}
});

var NodeTypes = new NameSpace({
	element: 1,
	attribute: 2,
	text: 3,
	comment: 8,
	document: 9
});

var Element = new Class({
	_initialize : function(t, p){
		if (p){
			this.extend(p);
		}
		
		this.extend({
			classnames : new Collection({
				types : ['string'],
				
				indexes : [],
				
				onlengthchanged : function(){
					var s = '';
					
					for (var i = 0; i < this.classnames.length; i++){
						s += this.classnames[i];
						
						if (i < this.classnames.length - 1){
							s += ' ';
						}
					}
					
					this.className = s;
				},
				
				swap : function(x, y){
					var i = this.classnames.indexof(x);
					if (i > -1){
						this.remove(this[i]);
						this.add(y);
					}
				}
			})
		});
		
		if (this.className){
			var s = this.className.split(' ');
			
			for (var i = 0; i < s.length; i++){
				if (s[i] != ''){
					this.classnames.add(s[i]);
				}
			}
		}
		
		return (iselement(t) ? t : document.createElement(t));
	},
	
	_type : 'element',
	
	create : function(x, i){
		if (x && x.appendChild && x.insertBefore){
			if (this.oncreate){
				this.oncreate();
			}
			
			if (i && i > 0 && i < x.childNodes.length){
				x.insertBefore(this, getelements(x, {nodeType: NodeTypes.element})[i]);
			} else {
				x.appendChild(this);
			}
		}
	},
	
	addlistener : function(e, f){
		addlistener(this, e, f);
	},
	
	removelistener : function(e, f){
		removelistener(this, e, f);
	},
	
	getelement : function(p){
		return getelement(this, p);
	},
	
	getelements : function(p){
		return getelements(this, p);
	},
	
	setstyle : function(s){
		setstyle(this, s);
	},
	
	remove : function(){
		if (this.parentNode){
			if (this.onremove && type(this.onremove) == 'function'){
				this.onremove();
			}
			
			this.parentNode.removeChild(this);
			dispose(this);
		}
	}
});

var XMLDocument = new Class({
	_initialize : function(p){
		if (p){ this.extend(p); }
		
		return new element('xml');
	},
	
	_type : 'xmldocument',
	
	getnodes : function(n){
		return this.getElementsByTagName(n);
	},
	
	getnode : function(n, i){
		return (i ? this.getElementsByTagName(n)[0] : this.getElementsByTagName(n)[i]);
	}
});
