function TipManager(_tips, _tIn, _tOut) {
	this.tIn = _tIn ? _tIn : 400;
	this.tOut = _tOut ? _tOut : 10;
	this.tip = null;
	this.tipClass = "tooltip";

	for(var i = 0; i < _tips.length; i++) {
		var t = _tips[i];
		
		var a;
		if(t.id) a = document.getElementById(t.id);
		else if(t.element) a = t.element;
		else {
			throw "Invalid tag descriptor: " + t;
		}
		a.htTip = {
			manager: this,
			html: t.tip,
			disabled: false,
			enable: function(enable) {
				this.disabled = !enable;
			}
		};
		CaptureEvent(a, "mouseover", htTipEngine.overEvent, true);
		CaptureEvent(a, "mouseout", htTipEngine.outEvent, true);
		CaptureEvent(a, "click", htTipEngine.clickEvent, true);
	}
}

TipManager.prototype.over = function(e, x, y) {
	if(e.htTip.disabled) return;

	this.tip = this.createTip(e.htTip.html);
	document.body.appendChild(this.tip);
	this.move(x, y);
}

TipManager.prototype.out = function(x, y) {
	if(this.tip) {
		document.body.removeChild(this.tip);
		this.tip = null;
	}
}

TipManager.prototype.move = function(x, y) {
	if(this.tip) {
		x -= 10;
		y += 19;
		with(this.tip.style) {
			top = y + "px";
			left = x + "px";
		}
	}
}

TipManager.prototype.createTip = function(txt) {
	var tt = document.createElement("DIV");
	tt.className = this.tipClass;
	tt.innerHTML = txt;
	return tt;
}

var htTipEngine = {
/*	spin: 0, */
	over: false,
	overElem: null,
	showing: null,
	x: -1,
	y: -1,
	capt: false,

	_pos: function(e) {
		this.x = e.clientX + document.body.parentNode.scrollLeft;
		this.y = e.clientY + document.body.parentNode.scrollTop;
	},

	__init: function() {
		var tips = new Array();

		function walk(e) {
			for(var e1 = e.firstChild; e1 != null; e1 = e1.nextSibling) {
				if(e1.nodeType == 1) {
					var t = e1.getAttribute('tip');
					if(t) tips.push({element: e1, tip: t});
					else walk(e1);
				}
			}
		}

		walk(document.body);
		new TipManager(tips);
	},

	cmouse: function() {
		if(!this.capt) {
			this.capt = true;
			CaptureEvent(document.body, "mousemove", this.moveEvent, true);
		}
	},

	rmouse: function() {
		if(this.capt) {
			this.capt = false;
			ReleaseEvent(document.body, "mousemove", this.moveEvent, true);
		}
	},

	moveEvent: function(e) {
		if(!htTipEngine) return; // Eltévedt események...
		with(htTipEngine) {
			_pos(e);
			if(showing) {
				showing.move(x, y);
			}
		}
	},

	overEvent: function(e) {
		with(htTipEngine) {
			_pos(e);
			over = true;

			var n;
			if(typeof event == 'undefined') n = e.target;
			else n = e.srcElement;
			while(!n.htTip) n = n.parentNode;
			if(overElem !== n) {
				overElem = n;
				if(showing) {
					showing.out(x, y);
					showing = null;
					overTime();
				} else {
					setTimeout("htTipEngine.overTime()", overElem.htTip.manager.tIn);
				}
				cmouse();
			}
		}
	},

	outEvent: function(e) {
		with(htTipEngine) {
			_pos(e);
			over = false;
			if(overElem != null) { // Többszörös out bug, a firebug DOM inspectorában.
				setTimeout("htTipEngine.outTime()", overElem.htTip.manager.tOut);
			}
		}
	},

	clickEvent: function(e) {
		with(htTipEngine) {
			_pos(e);
			if(showing) {
				showing.out(x, y);
				showing = null;
			}
			if(over) {
				over = false;
				rmouse();
			}
		}
	},

	overTime: function() {
		if(this.over && !this.showing) {
			var m = this.overElem.htTip.manager;
			this.showing = m;
			m.over(this.overElem, this.x, this.y);
		}
	},

	outTime: function() {
		if(!this.over) {
			this.rmouse();
			this.overElem = null;
			if(this.showing != null) {
				this.showing.out(this.x, this.y);
				this.showing = null;
			}
		}
	}
}

CaptureEvent(window, "load", function() { htTipEngine.__init(); }, true);
