﻿// (c) meinhardt, 19.06.04, www.meinhardt-kommunikation.de
//
// Script zum automatisch Plazieren von Divs im sichtbaren Bereich des Browserfensters.
// Die Divs werden horizontal zentriert (Pixelversatz prinzipiell nicht zu verhindern, aber selten)
//
// *** AUFRUFE und PARAMETER ***
// FloatingDiv(id, Breite, Höhe, y, y-offset, 'bottom') plaziert ein Div am unteren Rand
//	Breite und Höhe sind die entsprechenden Größen des Divs
//	(für Breite > größte Fensterbreite wird das (beliebig breite) Div left valign)
//	(für Höhe = offset + reale Höhe des Div wird das Div offset Pixel vom unteren Rand plaziert)
//	y ist die (aktuelle) y-Position des Divs
//	y-offset ist ein irrelevantes Funktionsargument
//
// FloatingDiv(id, Breite, Höhe, y, y-offset,'top') plaziert ein Div am oberen Rand
//	Höhe ist ein irrelevantes Funktionsargument
//	y-offset ist die Schwelle für das floating, d.h. das Div wird fest top=y-offset plaziert
//	bis mehr als y-offset Pixel nach oben aus dem Fenster geschoben wurden.
//	Wenn das Div floated, dann wird es top valign
//
// Im einfachsten Fall wird dem attribute onload des body-tags der Wert
//	"FloatingDiv('menu',width,height,top,offset,'top').ShiftDiv()"
// bzw. FloatingDiv("mainnav",924,40,300,135,'top','left').ShiftDiv();
// zugewiesen um ein Div mit id = 'menu', Breite width, Höhe height von top nach offset zu verschieben
// und fließen zu lassen.
//
// Verifiziert für:  Netscape 4, IE 6, Opera 7 und Mozilla 6 unter Windows
//                        IE 5 und Safari unter Mac
//                        Konqueror und Mozilla unter Linux
//
// Interna: 
//	Die Crossbrowser-Funktionalität basiert nicht auf einer expliziten Browseridentifikation.
//	Es werden vielmehr Browsereigenschaften identifiziert um Browserspezifischen Code zu bieten.
//
// Beschreibung:
//	FloatingDiv erweitert das Objekt mit der gegebenen id um Methoden und Eigenschaften,
//	die unabhängig vom Browser sind.
//	Die wichtigste Methode ShiftDiv verschiebt das Div in die gewünschte Richtung und sorgt per
//	Timer für ihren periodischen Aufruf.
//	Die Timersteuerung ist einerseits nötig, weil das Div nicht direkt auf die Zielpostion gesetzt wird,
//	sondern dieses Ziel erst schnell und dann immer langsamer »anfährt«.
//	Andererseits ersetzt die Timersteuerung quasi das nicht existierende Event onScroll.
//	Da die Objekte auch als Elemente global_id des window-Objekts existieren, ist 
//		global_menu.x
//	die x-Koordinate des Objektes mit id = 'menu'

function FloatingDiv(DivId, width, height, top, offset, valign, halign) {
    // definiere objekt fd
	var fd = document.getElementById ? document.getElementById(DivId):(document.all ? document.all[DivId]:document.layers[DivId]);
	fd.h = height;
	fd.w = width;
	fd.x = 0;
	fd.y = top;
	fd.o = offset;
    if(isNaN(parseInt(halign)))
    { fd.halign = halign || "center"; }
    else
    {
        fd.halign = "special";
        fd.xx = parseInt(halign);
    }
	window["global_"+DivId] = fd;
    
    // definiere methode ShiftDiv des objekts fd
	fd.ShiftDiv = function() {
		var nx = Math.max(0,Math.round((this.ww() - this.w)/2));
        switch(this.halign) {
            case "special":
                nx = this.xx;
                break;
            case "left":
            case "links":
                nx = 0;
                break;
            case "right":
            case "rechts":
                nx = this.ww;
                break;
        }
		var dy = this.dy();
		if ((nx != this.x) || (dy != 0)) {
			this.x = nx;
			this.y += Math.round(dy/5 + ((dy == 0) ? 0 : (dy > 0) ? 1 : -1));
			this.pos(this.x, this.y);
            // window.alert("dy: "+dy+" y: "+this.y);
            window.korrY[DivId] = this.y;
            window.korrX[DivId] = this.x;
		}
        // Überwachung!
		setTimeout("global_"+this.id+".ShiftDiv()",40);
	}
    // *****************************************************************************************************
    // definiere methode dy des objekts fd, abhängig vom valign-status
	if (valign == "bottom") {
		fd.dy = function() {
			return this.wh() + this.st() - this.h - this.y;			// Die Strecke
		}
	} else { // top valign
		fd.dy = function() {
			return Math.max(this.o,this.st()) - this.y;			// Die Strecke
		}
	}
    // definiere methoden pos, ww, wh, st des objekts fd
    if (document.layers) { // alte netscape Syntax
		fd.pos = function(x, y) {
			fd.left = x;
			fd.top = y;
		}
		fd.ww = function() {
			return  (document.height > innerHeight) ? innerWidth - 16 : innerWidth;
		}
		fd.wh = function() {
			return (document.width > innerWidth) ? innerHeight - 16 : innerHeight;
		}
		fd.st = function() {
			return pageYOffset;
		}
    } else {    // div/css-Syntax, IE + moderne Browser
		fd.pos = function(x, y) {
			fd.style.left = x + "px";
			fd.style.top = y + "px";
		}
		fd.ww = function() {
			return document.body.clientWidth;
		}
		fd.wh = function() {
			return Math.min(document.body.clientHeight, (window.innerHeight) ? innerHeight : document.body.clientHeight);
		}
		fd.st = function() {
			if (document.documentElement &&   (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
				return document.documentElement.scrollTop;
			}
			if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
				return document.body.scrollTop;
                        }
                        return 0;
		}			
	}
    // *****************************************************************************************************
    // gebe objekt an aufrufende instanz aus
	return fd;
}

 