var gallery;

function PxRect(x, y, width, height) {
	this.x = x + "px";
	this.y = y + "px";
	this.w = width + "px";
	this.h = height + "px";
}

function Thumbnail(imgElem, imgSrc, descriptionElem, config) {
	this.img = imgElem;
	this.id = imgElem.id;
	this.imageSrc = imgSrc;
	this.description = descriptionElem;
	var p = imgElem.parentNode;
	while(p.nodeName.toLowerCase() != "a") {
		p = p.parentNode;
	}
	this.link = p;
	var x = parseInt(this.link.style.left);
	var y = parseInt(this.link.style.top);
	var width = parseInt(imgElem.style.width);
	var height = parseInt(imgElem.style.height);
	this.rectIndex = 0;
	this.imgRects = new Array();
	this.linkRects = new Array();
	
	while(width < config.tnMaxWidth) {
		this.imgRects.push(new PxRect(x, y, width, height));
		this.linkRects.push(new PxRect(x, y, width + 2, height + 2));
		x -= 4;
		y -= 3;
		width += 8;
		height += 6;
	}
	this.maxRectIndex = this.imgRects.length - 1;
}

Thumbnail.prototype.showDescription = function() {
	this.description.style.display = "block";
}

Thumbnail.prototype.hideDescription = function() {
	this.description.style.display = "none";
}

Thumbnail.prototype.shrink = function() {
	if(this.rectIndex === 0) {
		return false;
	}
	this.resize(-1);
	return true;
}

Thumbnail.prototype.canShrink = function() {
	return this.rectIndex > 0;
}

Thumbnail.prototype.canGrow = function() {
	return this.rectIndex < this.maxRectIndex;
}

Thumbnail.prototype.grow = function() {
	if(this.rectIndex === this.maxRectIndex) {
		return false;
	}
	this.resize(1);
	return true;
}

Thumbnail.prototype.resize = function(d) {
	this.rectIndex += d;
	var i = this.rectIndex;
	var r = this.linkRects[i];
	var s = this.link.style;

	s.left = r.x;
	s.top = r.y;
	s.width = r.w;
	s.height = r.h;

	r = this.imgRects[i];
	s = this.img.style;
	s.width = r.w;
	s.height = r.h;
}

function GalleryImage(tnSrc, imgSrc, descId) {
	this.thumbnailSrc = tnSrc;
	this.imageSrc = imgSrc;
	this.descriptionContainerId = descId;
}

function GalleryConfig() {
	this.columns = 3;
	this.rows = 3;
	this.tnMinWidth = 60;
	this.tnMaxWidth = 120;
	this.borderColor = "#aaaaaa";
}

function Gallery(imgArray, containerId, imgContainerId, descriptionId, config) {
	this.thumbnails = new Array();
	this.timeID;
	this.growTimeID;
	this.timeIDs = new Array();
	this.shrinkingElems = new Array();
	this.currentlyHovering;
	
	this.html = "";
	var ids = new Array();

	if(!config) {
		config = new GalleryConfig();
	}

	for(var row = 0; row < config.rows; row++) {
		for(var col = 0; col < config.columns; col++) {
		    var index = row * config.rows + col;
		    if(index < imgArray.length) {
			    var id = generateId(index);
			    var l = (config.tnMinWidth + 3) * (2 * col + 1);
			    var t = (config.tnMinHeight + 3) * (2 * row + 1);
				this.html += '<a style="background-color: ' + config.borderColor + '; display: block; position: absolute;';
				this.html += ' top: ' + t + 'px; left: ' + l + 'px;';
				this.html += ' width: ' + (config.tnMinWidth + 2) + 'px; height: ' + (config.tnMinHeight + 2) + 'px;"';
				this.html += ' onmouseover="return resizeOverHandle(' + index + ');" onmouseout="return resizeOutHandle();"';
				this.html += ' href="javascript:gallery.showImage(' + index + ')">';
				this.html += '<img id="' + id + '" style="left: 1px; top: 1px; position: absolute; border: none;';
				this.html += ' width: ' + config.tnMinWidth + 'px; height: ' + config.tnMinHeight + 'px;"';
				this.html += ' src="' + imgArray[index].thumbnailSrc + '" /></a></td>';
				ids.push(id);
		    }
		}
	}

	document.getElementById(containerId).innerHTML = this.html;

	var srcElem = document.getElementById(descriptionId);
	this.description = addDescription(srcElem.innerHTML);
	this.description.style.display = 'block';

	var size = ids.length;
	
	var descs = new Array();
	for(var i = 0; i < size; i++) {
		var descriptionElem;
		if(imgArray[i].descriptionContainerId) {
			var srcElem = document.getElementById(imgArray[i].descriptionContainerId);
			if(srcElem) {
				descriptionElem = addDescription(srcElem.innerHTML);
			}
		}
		descs.push(descriptionElem);
	}
	
	
	for(var i = 0; i < size; i++) {
		var elem = document.getElementById(ids[i]);
		var descriptionElem = getDescription(descs[i].id);
		this.thumbnails[i] = new Thumbnail(elem, imgArray[i].imageSrc, descriptionElem, config);
	}

	this.container = document.getElementById(containerId);
	this.imageContainer = document.getElementById(imgContainerId);
	this.description = getDescription(this.description.id);
}

Gallery.prototype.docMoveHandle = function() {
	for (var i = this.thumbnails.length; i-- > 0;) {
		var tn = this.thumbnails[i];
		if (tn != this.currentlyHovering && tn.canShrink()) {
			this.shrinkingElems.push(tn);
		}
	}
	this.shrink();
}

Gallery.prototype.grow = function() {
	if (this.currentlyHovering != null) {
		var tn = this.currentlyHovering;
		if (!tn.grow()) {
			for (var i = this.timeIDs.length; i-- > 0;) {
				clearTimeout(this.timeIDs.shift());
			}
			return;
		}
		this.timeIDs.push(setTimeout(growGallery, 1));
	}
}

Gallery.prototype.shrink = function() {
	var len = this.shrinkingElems.length;
	if (len === 0) {
		return;
	}
	var elem = this.shrinkingElems[len - 1];
	if(elem === this.currentlyHovering) {
		this.shrinkingElems.pop();
		return;
	}
	if (!elem.shrink()) {
		this.shrinkingElems.pop();
		if(this.shrinkingElems.length > 0) {
			this.shrink();
		}
		return;	
	}
	this.shrinkTimeID = setTimeout(shrinkGallery, 1);
}

Gallery.prototype.showImage = function(index) {
	for (var i = this.timeIDs.length; i-- > 0;) {
		clearTimeout(this.timeIDs.shift());
	}

	this.currentlyHovering = null;
	this.docMoveHandle();

	var src = this.thumbnails[index].imageSrc;
	
	var html = '<table cellpadding="0" cellspacing="0" border="0" height="100%" width="100%">'
	html += '<tr><td align="center" valign="middle">'
	html += '<a href="javascript:gallery.hideImage()"><img src="' + src + '" class="picture" border="0" title="Zur&uuml;ck zur &Uuml;bersicht"/></a>';
	html += '</td></tr></table>'
	
	
	this.container.style.display = "none";
	this.imageContainer.innerHTML = html;
	this.imageContainer.style.display = "block";
	this.description.style.display = "none";

	this.thumbnails[index].showDescription();
}

Gallery.prototype.hideImage = function() {
	for (var i = this.thumbnails.length; i-- > 0;) {
		this.thumbnails[i].hideDescription();
	}
	this.container.style.display = "block";
	this.imageContainer.style.display = "none";
	this.description.style.display = "block";
}

function resizeOverHandle(id) {
	var tn = gallery.thumbnails[id];
	gallery.currentlyHovering = tn;
	for (var i = gallery.timeIDs.length; i-- > 0;) {
		clearTimeout(gallery.timeIDs.shift());
	}
	gallery.grow();
	return false;
}

function resizeOutHandle() {
	if(gallery.currentlyHovering != null) {
		gallery.currentlyHovering = null;
		gallery.docMoveHandle();
	}
	return false;
}

function growGallery() {
	gallery.grow();
}

function shrinkGallery() {
	gallery.shrink();
}

function createGallery(imgArray, containerId, imgContainerId, descriptionId, config) {
	gallery = new Gallery(imgArray, containerId, imgContainerId, descriptionId, config);
}

function generateId(index) {
	var id = 'tn' + index;
	while(document.getElementById(id)) {
		index++;
		id = 'tn' + index;
	}
	return id;
}
