/**
 * OverlayElement ist eine Klasse zum erzeugen eines Zeitgesteuerten Overlays.
 * Dabei wird beim Hovern eines Elements ein anderes Element unter diesem (oder
 * optional einem anderen Element) angezeigt, welches zudem Optional einen
 * transparenten Hintergrund bietet (Achtung: Im IE 8 wird vorerst die Transparenz
 * deaktiviert, wenn ein PNG als Hintergrundbild verwendet wird!).
 *
 * Optionen:
 *
 * offsetParent = Objekt an welchem das Overlay beim Einblenden ausgerichtet wird
 * timeout = Zeitverzoegerung bis zum Ausblenden des Elements
 * opacity = Sichtbarkeit des Hintergrund-Elements
 * showCallback = Callback-Funktion die beim Anzeigen des Overlays ausgefuehrt
 *                wird. Mit "this" ist innerhalb der Funktion der Zugriff auf
 *                das aktuelle OverlayElement moeglich.
 * hideCallback = Callback-Funktion die beim Ausblenden des Overlays ausgefuehrt
 *                wird. Mit "this" ist innerhalb der Funktion der Zugriff auf
 *                das aktuelle OverlayElement moeglich.
 *
 * Beispiel:
 *
 *
 */

var OverlayCache = {
	timeout : null,
	instance : null,
	cancelTimeout : function() {
		if(OverlayCache.timeout != null) {
			window.clearTimeout(OverlayCache.timeout);
			OverlayCache.timeout = null;
		}
	},
	startTimeout : function(func, delay) {
		this.timeout = window.setTimeout(func, delay);
	},
	hide : function() {
		if(this.timeout != null) {
			this.cancelTimeout();
		}
		if(this.instance != null && typeof this.instance == "object") {
			this.instance.hide();
		}
	}
}

function OverlayElement(hover_element, overlay_element, options) {
	this.parentElement = hover_element;
	this.hoverElement = hover_element;
	this.overlayElement = overlay_element;
	this.timeout = 200;
	this.opacity = 1.0;
	this.overlayColor = $(overlay_element).css("background-color");
	this.overlayImage = $(overlay_element).css("background-image");
	this.baseZIndex = $(overlay_element).css("z-index") == "auto" ? 1 : $(overlay_element).css("z-index");
	this.hideCallback = null;
	this.showCallback = null;

	this.applyOptions(options);
	this.init();
}

OverlayElement.prototype.applyOptions = function(options) {
	if(!options || typeof options != "object") {
		return false;
	}

	if(options.offsetParent) this.parentElement = options.offsetParent;
	if(options.timeout)      this.timeout = options.timeout;
	if(options.opacity)      this.opacity = options.opacity;
	if(options.hideCallback) this.hideCallback = options.hideCallback;
	if(options.showCallback) this.showCallback = options.showCallback;

	return true;
}

OverlayElement.prototype.init = function() {
	var instance = this;

	if($('#underlay').length == 0) {
		$('<div id="underlay">').css('display','none').appendTo($(document.body));
	}

	$(this.hoverElement).bind('mouseenter', function() {
		instance.show();
	}).bind('mouseleave', function() {
		OverlayCache.startTimeout(function() { instance.hide(); }, instance.timeout);
	});

	$(this.overlayElement).bind("mouseenter", function() {
		OverlayCache.cancelTimeout();
	}).bind("mouseleave",function() {
		OverlayCache.startTimeout(function() { instance.hide(); }, instance.timeout);
	});
}

OverlayElement.prototype.show = function() {
	OverlayCache.hide();

	var position = $(this.parentElement).offset();
	var height = $(this.parentElement).innerHeight();

	$(this.overlayElement).css({
		position        : "absolute",
		top             : position.top + height,
		left            : position.left,
		backgroundColor : "transparent",
		backgroundImage : "none",
		zIndex          : this.baseZIndex + 2
	}).show();

	if($.browser.msie && $.browser.version == "8.0") {
		if(this.overlayImage.toLowerCase().indexOf(".png") == -1) {
			$('#underlay').css("opacity", this.opacity);
		}
	} else {
		$('#underlay').css("opacity", this.opacity);
	}

	$('#underlay').css({
		position:"absolute",
		top             : position.top + height,
		left            : position.left,
		width           : $(this.overlayElement).innerWidth(),
		height          : $(this.overlayElement).innerHeight(),
		backgroundColor : this.overlayColor,
		backgroundImage : this.overlayImage,
		zIndex          : this.baseZIndex + 1
	}).show();

	OverlayCache.instance = this;

	if(this.showCallback && typeof this.showCallback == "function") {
		this.showCallback.call(this, this.overlayElement);
	}
}

OverlayElement.prototype.hide = function() {
	$(this.overlayElement).css({
		backgroundColor: this.overlayColor,
		backgroundImage: this.overlayImage
	});

	if(this.hideCallback && typeof this.hideCallback == "function") {
		this.hideCallback.call(this, this.overlayElement);
	}

	$(this.overlayElement).hide();
	$('#underlay').hide();
	
	OverlayCache.instance = null;
}
