var Env = {
	query: function(k) {
		var q = unescape(window.location.search.substr(1)).split("&"), r = {};
		for(var i = 0, l = q.length, p, v; i < l; i++) {
			p = q[i];
			if(p === '') continue;
			p = p.split('=');
			v = p[1];
			r[p[0]] = (v) ? v : null;
		}
		if(k && r[k]) return r[k];
		return r;
	},
	openWindow: function(u, o) {
		if(!o) o = {};
		var a = '', n = o.name, w = o.width, h = o.height, f = o.fullscreen, c = o.center,
		s = o.scrollbars, m = o.menubar, l = o.locationbar, r = o.resizable, x, y,
		aw = screen.availWidth, ah = screen.availHeight, sw = screen.width, sh = screen.height;
		if(!n) n = 'win_' + Tools.randomString(8);
		if(f) a += 'width=' + aw + ',height=' + ah + ',';
		else {
			if(h) a += 'height=' + h + ',';
			if(w) a += 'width=' + w + ',';
		}
		if(!c) a += 'screenx=0,screeny=0,left=0,top=0,';
		else if(!f) {
			y = Math.floor((ah - (h || sh)) / 2) - (sh - ah);
			x = Math.floor((aw - (w || sw)) / 2) - (sw - aw);
			a += 'screenx=' + x + ',screeny=' + y + ',left=' + x + ',top=' + y + ',';
		}
		if(s) a += 'scrollbars=1,';
		if(m) a += 'menubar=1,';
		if(l) a += 'location=1,';
		if(r) a += 'resizable=1,';
		return window.open(u, n, a);
	},
	focusFrame: function(o) {
		o = I(o);
		if(o.contentWindow) o.contentWindow.focus();
		else o.focus();
	},
	clientSizes: function() {
		var s = self, d = document, e = d.documentElement, o = d.body, w = s.innerWidth, h;
		if(w || w === 0) h = s.innerHeight;
		else if(e.clientWidth || e.clientHeight) { // Explorer 6 Strict Mode
			w = e.clientWidth;
			h = e.clientHeight;
		} else if(o) {
			w = o.clientWidth;
			h = o.clientHeight;
		}
		return [w, h];
	},
	pageScroll: function() {
		var s = self, d = document, e = d.documentElement, o = d.body, x = s.pageXOffset, y;
		if(x || x === 0) y = s.pageYOffset;
		else if(e.scrollLeft || e.scrollTop) { // Explorer 6 Strict Mode
			x = e.scrollLeft;
			y = e.scrollTop;
		} else if(o) { // all other Explorers
			x = o.scrollLeft;
			y = o.scrollTop;
		}
		return [x, y];
	},
	pageSizes: function() {
		var o = document.body, n = window, a, b;
		if(n.innerHeight && n.scrollMaxY) {
			a = n.innerWidth + n.scrollMaxX;
			b = n.innerHeight + n.scrollMaxY;
		// all but Explorer Mac
		} else if(o.scrollHeight > o.offsetHeight) {
			a = o.scrollWidth;
			b = o.scrollHeight;
		// Explorer Mac;
		//would also work in Explorer 6 Strict, Mozilla and Safari
		} else {
			a = o.offsetWidth;
			b = o.offsetHeight;
		}
		return [a, b];
	},
	viewSizes: function() {
		var c = Env.clientSizes(), p = Env.pageSizes(), w = c[0], h = c[1], a = p[0], b = p[1];
		a = (a < w) ? w : a;
		b = (b < h) ? h : b;
		return [a, b];
	},
	viewCenter: function(w, h) {
		if(!w) w = 0;
		if(!h) h = 0;
		var c = Env.clientSizes(), s = Env.pageScroll();
		return [Math.round((c[0] - w) / 2) + s[0], Math.round((c[1] - h) / 2) + s[1]];
	},
	gridPosition: function(x, y, o) {
		if(!o) o = {};
		var s = Env.clientSizes(), c = o.cols, r = o.rows, w, h, i = 0, xc = 0, yc = 0;
		w = (c) ? s[0] / c : o.width || 50;
		h = (r) ? s[1] / r : o.height || 50;
		while((w * i) <= x) {
			i++;
			xc = i;
		}
		i = 0;
		while((h * i) <= y) {
			i++;
			yc = i;
		}
		return [xc, yc];
	},
	pause: function(t) {
		var n = new Date();
		t = n.getTime() + (t * 1000);
		while(true) {
			n = new Date();
			if(n.getTime() > t) return;
		}
	},
	execute: function(c) {
		var g = this;
		if(window.execScript) {
			window.execScript(c);
			return null;
		}
		return g.eval ? g.eval(c) : eval(c);
	},
	tries: function() {
		for(var i = 0, a = arguments, l = a.length, r = null; i < l; i++) {
			try {
				r = a[i].apply();
				break;
			} catch(e) {}
		}
		return r;
	},
	refresh: function() {
		location.reload();
	}
};

var Cookie = {
	set: function(n, v, o) {
		var e = o.expire, p = o.path, d = o.domain, s = o.secure;
		v = escape(v);
		if(!e) e = 0;
		e = new Date((new Date().getTime()) + (e * 1000)).toGMTString();
		document.cookie = n + '=' + v + '; expires=' + e + ((p) ? '; path=' + p : '') +
			((d) ? '; domain=' + d : '') + ((s) ? '; secure' : '');
	},
	get: function(n) {
		var e = new RegExp('(^|;)\\s*' + n + '=([^;]*)'), m = document.cookie.match(e);
		if(m && m[1]) return unescape(m[1]);
		return null;
	},
	unset: function(n, o) {
		if(!o) o = {};
		o.expire = -(365 * 24 * 3600);
		Cookie.set(n, '', o);
	}
};

var _GET = Env.query();

var Event = {
	mousePosition : function(e, o) {
		if(!e) e = window.event;
		var x = 0, y = 0, a = e.pageX, b = e.clientX, c, d, p, g;
		if(a) {
			x = a;
			y = e.pageY;
		} else if(b) {
			c = document.body;
			d = document.documentElement;
			if(c && d) {
				x = b + c.scrollLeft + d.scrollLeft;
				y = e.clientY + c.scrollTop + d.scrollTop;
			}
		}
		if(o) {
			if(typeof o == 'boolean') {
				p = Env.pageScroll();
				return [x - p[0], y - p[1]];
			}
			o = I(o);
			p = Element.position(o);
			return [x - p[0], y - p[1]];
		}
		return [x, y];
	},
	fromElement: function(e) {
		if(!e) e = window.event;
		var r = e.relatedTarget || e.fromElement;
		return r;
	},
	toElement: function(e) {
		if(!e) e = window.event;
		var r = e.relatedTarget || e.toElement;
		return r;
	},
	exitElement: function(e, o) {
		if(!e) e = window.event;
		var t = e.target || e.srcElement, r = Event.toElement(e);
		while(r != t && r.nodeName != 'BODY') r = r.parentNode;
		if(r == t) return false;
		return true;
	},
	cancelBubble: function(e) {
		if(!e) e = window.event;
		e.cancelBubble=true;
	},
	getKey: function(e) {
		if(!e) e = window.event;
		var n = e.keyCode || e.which, k = String.fromCharCode(n),
		s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {code: n, key: k, shift: s, ctrl: c, alt: a};
	},
	checkKey: function(k) {
		var v = 0, n = k.code, m = Event.keysMap;
		if(n >= 13 && n <= 20) return false;
		v = ((k.shift) ? 4 : 0) + ((k.ctrl) ? 2 : 0) + ((k.alt) ? 1 : 0);
		for(var i = m.length - 1; i >= 0; i--) {
			var c = m[i];
			if(c[0] === n && c[1] == v) return c[2];
		}
		return false;
	},
	keysMap: [
		[8, 0, 'BackSpace'],
		[9, 0, 'Tab'],
		[9, 4, 'Btab'],
		[12, 0, 'CursorCenter'],
		[13, 0, 'Enter'],
		[19, 0, 'Pause'],
		[20, 0, 'CapsLock'],
		[27, 0, 'Escape'],
		[33, 0, 'PageUp'],
		[34, 0, 'PageDown'],
		[35, 0, 'End'],
		[35, 2, 'GoToBottom'],
		[36, 0, 'CursorHome'],
		[36, 2, 'ControlHome'],
		[37, 0, 'CursorLeft'],
		[38, 0, 'CursorUp'],
		[39, 0, 'CursorRight'],
		[40, 0, 'CursorDown'],
		[44, 0, 'Print'],
		[45, 0, 'Insert'],
		[46, 0, 'Delete'],
		[46, 4, 'EraseField'],
		[46, 2, 'EraseEOP'],
		[46, 1, 'ClearScreen'],
		[91, 0, 'LeftWin'],
		[92, 0, 'RightWin'],
		[144, 0, 'NumLock'],
		[145, 0, 'ScrollLock']
	],
	getButton: function(e) {
		if(!e) e = window.event;
		var n = e.button, l = false, m = false, r = false;
		if(n) {
			if(n & 1) l = true;
			if(n & 2) r = true;
			if(n & 4) m = true;
		} else {
			n = e.which;
			if(n == 1) l = true;
			if(n == 2) r = true;
			if(n == 3) m = true;
		}
		var s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {button: n, left: l, middle: m, right: r, shift: s, ctrl: c, alt: a};
	},
	getWheel: function(e) {
		if(!e) e = window.event;
		var d = e.detail;
		if(d) d = -d / 3;
		else {
			d = e.wheelDelta / 120;
			if(window.opera) d = -d;
		}
		var s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {wheel: d, shift: s, ctrl: c, alt: a};
	},
	preventDefault: function(e) {
		if(!e) e = window.event;
		if(e.preventDefault) e.preventDefault();
		else e.returnValue = false;
	},
	stopPropagation: function(e){
		if(!e) e = window.event;
		if(e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	},
	stop: function(e) {
		if(!e) e = window.event;
		Event.stopPropagation(e);
		Event.preventDefault(e);
	},
	target : function(e) {
		if(!e) e = window.event;
		return e.target || e.srcElement;
	},
	add : function(o, t, f) {
		f = Types.getFunction(f);
		if(typeof f !== 'function') throw new TypeError('Not a function');
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		if(t == 'domloaded') {
			if(o == window) Event._onDomLoaded.add(f);
		} else {
			var u = ['clickout', 'dblclickout', 'mousemoveout'];
			if(u.indexOf(t) >= 0) {
				var of = f, oo = o;
				o = document;
				t = t.replace(/out$/, '');
				f = function(e) {
					var p = Event.target(e), g = p;
					do { if(p === oo) return; } while((p = p.parentNode));
					of.call(g, e);
				};
			}
			if(!o._events) o._events = {};
			var e = o._events;
			if(!e[t]) e[t] = [];
			e[t].push(f);
			if(o.attachEvent) {
				o['e'+t+f] = f;
				o[t+f] = function(){o['e'+t+f](window.event);};
				o.attachEvent('on'+t, o[t+f]);
			} else {
				if(t == 'mousewheel') t = 'DOMMouseScroll';
				o.addEventListener(t, f, false);
			}
		}
	},
	remove: function(o, t, f) {
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		var e = o._events;
		if(e && e[t]) {
			e = e[t];
			for(var i = e.length - 1, a; i >= 0; i--) {
				a = e[i];
				if(a === f) {
					e[i] = e[e.length - 1];
					e.length--;
				}
			}
		}
		if(o.detachEvent) {
			o.detachEvent('on'+t, o[t+f]);
			o[t+f] = null;
		} else {
			if(t == 'mousewheel') t = 'DOMMouseScroll';
			o.removeEventListener(t, f, false);
		}
	},
	get: function(o, t) {
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		var e = o.events;
		return (e && e[t]) ? e[t] : [];
	},
	clone: function(o, u) {
		o = I(o);
		var e = o._events;
		if(e) {
			for(var t in e) {
				var a = e[t];
				for(var i = 0, l = a.length; i < l; i++) {
					Event.add(u, t, a[i]);
				}
			}
		}
	},
	/* onDomLoaded */
	_onDomLoaded: {
		cache: [],
		run: function() {
			var m = Event._onDomLoaded, e = m.cache, i, l = e.length;
			m.cache = [];
			for(i = 0; i < l; i++) e[i]();
		},
		/*executer: function() {
			var m = this, o = window.opera;
			onload = m.run;
			if(/WebKit|Konqueror/i.test(navigator.userAgent))
				(function() { if(/loaded|complete/.test(document.readyState)) m.callback(); else setTimeout(arguments.callee, 1); })();
			else if((!o || parseInt(o.version(), 10) >= 9) && document.addEventListener)
				document.addEventListener('DOMContentLoaded', Event._onDomLoaded.callback, false);
			else document.write('<scr' + 'ipt src="void(0)" defer="defer" onreadystatechange="if(this.readyState === \'complete\') Event._onDomLoaded.callback()"></scr'+'ipt>');
		},*/
		executer: function() {
			var m = this, a = Agent, o = a.Opera, t = window.setTimeout, d = document;
			//onload = m.run;
			if(a.Konqueror || a.WebKit)
				(function() { if(/loaded|complete/.test(d.readyState)) m.callback(); else t(arguments.callee, 1); })();
			else if((!o || o >= 9) && d.addEventListener)
				d.addEventListener('DOMContentLoaded', Event._onDomLoaded.callback, false);
			else if(Agent.MSIE)
				(function() { try{ d.documentElement.doScroll('left'); m.run(); } catch(e) { t(arguments.callee, 1); }})();
			else
				Event.add(window, 'load', m.run());
		},
		callback: function() { window.onload = null; Event._onDomLoaded.run(); },
		add: function(e) {
			var m = Event._onDomLoaded;
			if(m.cache.length === 0) m.executer();
			e = Types.getFunction(e);
			m.cache.push(e);
		}
	},
	// onClickOut
	// Metodi per creare e eseguire eventi
	_eventTypes: {
		'DOMFocusIn': 'UIEvent',
		'DOMFocusOut': 'UIEvent',
		'DOMActivate': 'UIEvent',
		'focus': 'UIEvent',
		'blur': 'UIEvent',
		'click': 'MouseEvent',
		'mousedown': 'MouseEvent',
		'mouseup': 'MouseEvent',
		'mouseover': 'MouseEvent',
		'mousemove': 'MouseEvent',
		'mouseout': 'MouseEvent',
		'keydown': 'keyboardEvent',
		'keyup': 'KeyboardEvent',
		'textInput': 'TextEvent',
		'DOMSubtreeModified': 'MutationEvent',
		'DOMNodeInserted': 'MutationEvent',
		'DOMNodeRemoved': 'MutationEvent',
		'DOMNodeRemovedFromDocument': 'MutationEvent',
		'DOMNodeInsertedIntoDocument': 'MutationEvent',
		'DOMAttrModified': 'MutationEvent',
		'DOMCharacterDataModified': 'MutationEvent',
		'DOMElementNameChanged': 'MutationNameEvent',
		'DOMAttributeNameChanged': 'MutationNameEvent',
		'load': 'Event',
		'unload': 'Event',
		'abort': 'Event',
		'error': 'Event',
		'select': 'Event',
		'change': 'Event',
		'submit': 'Event',
		'reset': 'Event',
		'resize': 'Event',
		'scroll': 'Event'
	},
	getEventType: function(t) {
		t = t.replace(/^on/, '');
		var i, p = Event._eventTypes;
		for(i in p) if(t == i) return p[i];
		return null;
	},
	create: function(t, m) {
		var e = null, c;
		// Mozilla / DOM
		if(document.createEvent) {
			c = Event.getEventType(t);
			if(c) {
				e = document.createEvent(c);
				m = Event.cleanEventProperties(m);
				switch(c) {
					case 'Event':
						e.initEvent(t, m.bubbles, m.cancelable);
					break;
					case 'UIEvent':
						e.initUIEvent(t, m.bubble, m.cancelable, m.view, m.detail);
					break;
					case 'MouseEvent':
						e.initMouseEvent(t, m.bubble, m.cancelable, m.view,
							m.detail, m.screenX, m.screenY, m.clientX, m.clientY,
							m.ctrlKey, m.altKey, m.shiftKey, m.metaKey,
							m.button, m.relatedTarget);
					break;
					case 'KeyboardEvent':
						e.initKeyEvent(t, m.bubble, m.cancelable, m.view,
							m.ctrlKey, m.altKey, m.shiftKey, m.metaKey,
							m.keyCode, m.charCode);
					break;
					case 'MutationEvent':
						e.initMutationEvent(t, m.bubble, m.cancelable, m.relatedNode,
							m.prevValue, m.newValue, m.attrName, m.attrChange);
					break;
					case 'MutationNameEvent':
						e.initMutationNameEvent(t, m.bubble, m.cancelable, relatedNode, prevNamespaceUri, prevNodeName);
					break;
					case 'TextEvent':
						e.initTextEvent(t, m.bubble, m.cancelable, m.view, m.data);
					break;
					case 'PopupBlocked':
						e.initPopupBlockedEvent();
					break;
					case 'XULCommandEvent':
						e.initCommandEvent();
					break;
					default:
						e = null;
					break;
				}
			}
		// MSIE
		} else if(document.createEventObject) {
			e = document.createEventObject();
			if(m) Tools.object(e, m);
		}
		return e;
	},
	fire: function(o, t, e) {
		o = I(o);
		t = t.replace(/^on/, '');
		if(!e) e = Event.create(t, e);
		// MSIE
		if(o.fireEvent) {
			o.fireEvent('on' + t, e);
		} else if(o.dispatchEvent) {
			o.dispatchEvent(e);
		}
	},
	cleanEventProperties: function(p) {
		if(!p) p = {};
		return Tools.object({
			altKey: false,
			bubbles: true,
			button: 0,
			cancelable: true,
			//cancelBubble: false,
			charCode: 0,
			clientX: 0,
			clientY: 0,
			ctrlKey: false,
			currentTarget: null,
			detail: 0,
			eventPhase: null,
			//explicitOriginalTarget: null,
			isChar: false,
			keyCode: 0,
			layerX: 0,
			layerY: 0,
			metaKey: false,
			//originalTarget: null,
			pageX: 0,
			pageY: 0,
			relatedTarget: null,
			screenX: 0,
			screenY: 0,
			shiftKey: false,
			target: null,
			timeStamp: 0,
			type: '',
			view: window,
			which: 0
		}, p);
	}
};
