// JavaScript Document
// tabresize.js
//
// Schrunpfung eines kompletten HTML-Dokumentes das die Form einer (großen) Tabelle haben muss, passend auf Fenstergröße.
// Diesen Code am Ende einer HTML-Datei per <script ... einbinden, direkt VOR dem schließenden </body> -Tag.
//
// Author: Joachim Stein, Juli 2010
//

var extra_security_shrink = 1.0;	// Falls ein extra Verkleinerungsfaktor gebraucht wird: Kleiner als 1.0 setzen.

function resize_page_init () {
  if (rp_init ()) {
  	resize_page ();
  	window.onresize = doResizeTimer;
  }
}

// TODO:
// Nachschlagen bei www.quirksmode.org:
function Fensterweite () {
  if (window.innerWidth) {
    return window.innerWidth;
  } else if (document.documentElement && document.documentElement.clientWidth) {
    return document.documentElement.clientWidth;
  } else if (document.body && document.body.offsetWidth) {
    return document.body.offsetWidth;
  } else {
    return 0;
  }
}

function Fensterhoehe () {
  if (window.innerHeight) {
    return window.innerHeight;
  } else if (document.documentElement && document.documentElement.clientHeight) {
    return document.documentElement.clientHeight;
  } else if (document.body && document.body.offsetHeight) {
    return document.body.offsetHeight;
  } else {
    return 0;
  }
}

var timed_resize;
var timer_is_on=0;

function doResizeTimer()
{
  if (timer_is_on) clearTimeout (timed_resize)
  timer_is_on=1;
  timed_resize=setTimeout("resize_page()",1000);
}

Weite = 0;
Hoehe = 0;
var last_resize_factor = 1.0;

function resize_page () {
// Alle Images des Dokumentes resizen.
// Document muss mit rp_init () initalisiert worden sein.

	// Faktor shrink für die Schrumpfung ermitteln:
	Weite = Fensterweite();
	Hoehe = Fensterhoehe();
	var mybody = document.getElementsByTagName("body")[0];
	var mytbl  = mybody.getElementsByTagName("table")[0];
	var wi, he;
	wi = Weite / mytbl.orig_width;
	he = Hoehe / mytbl.orig_height;
	var shrink = (wi < he) ? wi : he;
//	alert ("In resize_page ().\nlast_resize_factor = " + last_resize_factor + "\nshrink = " + shrink + 
//			"\n\nWeite, Höhe: " + Weite + ", " + Hoehe + "\nwi, he: " + wi + ", " + he +
//			"\nwindow.innerWidth: " + window.innerWidth + 
//			"\ndocument.documentElement.clientWidth: " + document.documentElement.clientWidth  + 
//			"\ndocument.body.offsetWidth: " + document.body.offsetWidth +
//			"\n\norig_width = " + mytbl.orig_width + "\norig_height = " + mytbl.orig_height);
	shrink *= extra_security_shrink;
	if ((last_resize_factor == 1 && shrink >= extra_security_shrink) || last_resize_factor == shrink)
		return;
	else if (shrink > extra_security_shrink)
		shrink = extra_security_shrink;		// Keine Vergrößerungen.
	
	// ggf. Höhe/Breite der Tabelle als Ganzes korrigieren:
	if (he = mytbl.orig_height)
		mytbl.setAttribute ("height", Math.floor(he * shrink));			// klappt bei height nur mit get-/setAttribute() (Firefox)
		// mytbl.height = Math.floor (he * shrink);
	if (wi = mytbl.orig_width)
		mytbl.width = Math.floor (wi *shrink);
	/*
	alert ("mytbl.orig_height: " + mytbl.orig_height + "\nmytbl.getAttribute(orig_height): " + mytbl.getAttribute("orig_height") +
		   "\nmytbl.height: " + mytbl.height + "\nmytbl.getAttribute(height): " + mytbl.getAttribute("height") + 
		   "\nmytbl.orig_width: " + mytbl.orig_width + "\nmytbl.getAttribute(orig_width): " + mytbl.getAttribute("orig_width") +
		   "\nmytbl.width: " + mytbl.width + "\nmytbl.getAttribute(width): " + mytbl.getAttribute("width"));
	*/
	
	// Alle Images durchgehen und korrigieren:
	var imgArray = document.getElementsByTagName("img");
	var to, le;		// bedeutet: top, left;
	for (var i = 0; i < imgArray.length; i++) {
		var img = imgArray[i];
		to = img.orig_top;
		le = img.orig_left;
		wi = img.orig_width;
		he = img.orig_height;
		
		if (wi && he) {
		  // Die folgende Berechnung ist scheinbar komplizierter als notwendig. - Warum reicht nicht:
		  // img.width = shrink * wi; ? Warum müssen in rp_init() überhaupt erst umständlich die absoluten Positionen
		  // herausgefunden werden? -- weil sonst durch Rundungsfehler weiße Balken zwischen den Blöcken entstehen!
		  img.width = Math.round (shrink * (le+wi)) - Math.round (shrink * le);
		  img.height = Math.round (shrink * (to+he)) - Math.round (shrink * to);
		  var hiw1 = le + wi;
		  var hiw2 = to + he;
		  // alert ("to = " + to + "\nle = " + le + "\nwi = " + wi + "\nhe = " + he + "\nle+wi = " + hiw1 + "\nto+he = " + hiw2 + "\n\nimg.width: " + img.width + "\nimg.height: " + img.height);
		}
	}
	/*
	if (confirm("Weitere Infos zum Faktor " + shrink + "?")) {
	  for (var i = 0; i < imgArray.length; i++) {
		  var img = imgArray[i];
		  to = img.orig_top;
		  le = img.orig_left;
		  wi = img.orig_width;
		  he = img.orig_height;
		  alert ("Nr. " + i + ":\n\nto, le: " + to + ", " + le + "\nwi, he: " + wi + ", " + he + 
				 "\n\nimg.width: " + img.width + "\nimg.height: " + img.height);
	  }
	}
	*/
	last_resize_factor = shrink;	
   	timer_is_on=0;
}

function I_Cell (left, width, height, rowSpan) {
// Interne Abbildung einer Tabellenzelle.
	this.left = left;
	this.width = width;
	this.height = height;
	this.rowSpan = rowSpan;
}

function rp_init () {
// Tabellenstruktur und -größe des Dokumentes analysieren. 
// Allen Images Werte für originales top, left, width, height als neues Attribut mitgeben, ie. orig_top, orig_left etc.

	var mybody = document.getElementsByTagName("body")[0];
	var mytbl  = mybody.getElementsByTagName("table")[0];
	if (!mytbl) return false;
	
	// Tabbellen-Umrandung auf 0 setzen:
	// Geht so nicht! Leider, leider...
//	var LEFTMARGIN, TOPMARGIN, MARGINWIDTH, MARGINHEIGHT;
//	LEFTMARGIN = mybody.getAttribute("LEFTMARGIN");
//	TOPMARGIN = mybody.getAttribute("TOPMARGIN");
//	MARGINWIDTH = mybody.getAttribute("MARGINWIDTH");
//	MARGINHEIGHT = mybody.getAttribute("MARGINHEIGHT");
//	alert ("Tabellen-Attribute:\nLeftm" + LEFTMARGIN + "\nTopm: " + TOPMARGIN + "\nmwidth: " + MARGINWIDTH + "\nmheight: " +
//			MARGINHEIGHT);
//	...
	
	var mytblbody = mytbl.getElementsByTagName("tbody")[0];
	var myrows    = mytblbody.getElementsByTagName("tr");
	var Zeilenstruktur = new Array();		// interne Abbildung der jeweils aktuellen Zeilenstruktur.
	var top = 0, left = 0;			// <-- erstmal (top, left) auf (0, 0) setzen. Ggf noch verallgemeinern.
	var max_width = 0;
	var to = top;
	
	for (var ro = 0; ro < myrows.length; ro++) {   // for row ...
		var mycells = myrows[ro].getElementsByTagName("td");
		var le = left;
		var zs_index = 0;		// Index in der Zeilenstruktur.
		var max_height = 0;		// Max. Höhe der jeweiligen Zeile.

		for (var ce=0; ce < mycells.length; ce++) {		// for cell ...
			var img = mycells[ce].getElementsByTagName("img");
			var imgDone = false;
			// zunächst die wichtigen Werte/Attribute auslesen:
			cs = parseInt (mycells[ce].getAttribute("colSpan"));
			rs = parseInt (mycells[ce].getAttribute("rowSpan"));
			if (!cs) cs = 1;
			if (!rs) rs = 1;
			if (img) {
				img = img[0];	// (Nur ein Image pro Zelle ist üblich und hier erlaubt)
				// Im Falle einer Tabellen-Zelle OHNE Image z.B.: "<td></td>" ist nun img nicht gesetzt, 
				// also gleich NULL! Darum checken:
				if (img) {
				  wi = parseInt (img.getAttribute("width"));
				  he = parseInt (img.getAttribute("height"));
				  // Neue Attribute in den img-node einfügen, die in resize_page() benutzt werden:
				  img.orig_top = to;
				  img.orig_width = wi;
				  img.orig_height = he;
				  imgDone = true;
				}	// if (img)
			}	// if (img)
			if (!imgDone) {
				wi = parseInt (mycells[ce].getAttribute("width"));
				he = parseInt (mycells[ce].getAttribute("height"));
			}
			// Ist es die erste Zeile?
			if (!ro) {  // ==>  Zeilenstruktur einrichten:
				// entsprechend colSpan werden soviele Zellen in die Struktur eingefügt:
				for (var i = 0; i < cs; i++)
					Zeilenstruktur[zs_index++] = new I_Cell (le, 0, he, rs);  // (Breite auf 0 setzen)
			} else { 	// ab zweite Zeile:
				// Bevor diese Zelle in die interne Zeilenstruktur-Abbildung übernommen wird, müssen Zellen übersprungen 
				// werden, die von der/den oberen Zeile(n) an dieser Stelle in diese Zeile hinunterragen, erkennbar 
				// an rowSpan > 1. Erst rechts davon geht es dann weiter:
				for ( ; zs_index < Zeilenstruktur.length; zs_index++) {
					var z = Zeilenstruktur[zs_index];
					if (!--z.rowSpan)	// Nebenbei rowSpan decrementieren, für nächste Zeile
						break;
					le += z.width;		// Nach rechts gehen
					// Wenn diese Zelle nicht noch tiefer ragt, auch ihre Höhe für die aktuelle Zeilenhöhe einbeziehen:
					// ===> auskommentiert, weil 1. nicht unbedingt notwendig, und 
					//							 2. diese Höhe so nicht stimmt - sie bezieht sich auf MEHRERE Zeilen:
					//if (z.rowSpan == 1 && z.height > max_height)
					  //  max_height = z.height;
				}
				// Okay, ab hier eintragen. Entsprechend colSpan werden soviele Zellen in die Struktur geschrieben:
				// (Es wird hier davon ausgegangen, dass soviele freie Zellen in der Struktur zur Verfügung stehen.
				//  Wenn nicht, ist die Tabelle fehlerhaft. Damit es keinen ernsthaften Fehler gibt, trotzdem eine Abfrage:)
				for (var i = 0; i < cs && zs_index < Zeilenstruktur.length; i++) {
					var z = Zeilenstruktur[zs_index++];
					z.left = le;
					z.width = 0;		// (Breite auf 0 setzen)
					z.height = he;
					z.rowSpan = rs;
				}
			}
			// Erst jetzt stimmt le korrekt für orig_left:
			if (imgDone)  img.orig_left = le;
			// Nur der letzte dieser (neuen) Einträge bekommt die Breite eingetragen:
			Zeilenstruktur[zs_index-1].width = wi;
			// Wenn diese Zelle nicht tiefer ragt, auch ggf ihre Höhe für die aktuelle Zeilenhöhe übernehmen
			if (rs == 1 && he > max_height)
				max_height = he;
//				  	alert ("Zelle (" + ro + ", " + ce + "):\nto, le: " + to + ", " + le + 
//							"\nwi, he: " + wi + ", " + he + 
//						   "\nrs: " + rs + "\ncs: " + cs + "\nmax_height: " + max_height + "\nzs_index: " + zs_index);
			le += wi;		// Soweit nach rechts geht´s jetzt weiter.
		}	// for (ce
		// Alle Zellen dieser (HTML-)Zeile sind nun abgearbeitet. Falls aber hier noch weitere Zellen folgen,
		// die schon weiter oben begannen, muss noch ihr jeweiliger rowSpan decrementiert werden, sonst gibt´s
		// im folgenden Kuddelmuddel:
		for ( ; zs_index < Zeilenstruktur.length; zs_index++) {
			var z = Zeilenstruktur[zs_index];
			if (z.rowSpan)    z.rowSpan--;
			le += z.width;		// Nach rechts gehen
		}
		// Die Breite dieser letzten Zeile ggf. für die Gesamtbreite der Tabelle übernehmen:
		// alert ("Breite von Zeile " + ro + ": " + le);
		if (le > max_width)
			max_width = le;
		to += max_height;		// Soweit nach unten geht´s jetzt weiter.
	}	// for (ro
	// Neue Attribute für die Gesamt-Ausmaße in die Tabelle eintragen:
	mytbl.orig_width = max_width;
	mytbl.orig_height = to;
	// alert ("orig_width = " + mytbl.orig_width + "\norig_height = " + mytbl.orig_height);
	return true;
}


// Here we go:
resize_page_init();

