
function getWidth()
{
	var de = document.documentElement;
	var myWidth = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
	return myWidth;
}
document.getWidth = getWidth;

function getHeight()
{
	var de = document.documentElement;
	var myHeight = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
	return myHeight;
}

document.getHeight = getHeight;

function ImageExpander(oThumb, sImgSrc)
{
	// store thumbnail image and overwrite its onclick handler.
	this.oThumb = oThumb;
	this.oThumb.expander = this;
	this.OrgOnClickFunction = this.oThumb.onclick;
	this.oThumb.onclick = function() { this.expander.expand(); }

	// record original size
	this.smallWidth = oThumb.offsetWidth;
	this.smallHeight = oThumb.offsetHeight;	

	this.bExpand = true;
	this.bTicks = false;

	// self organized list
	if (!window.aImageExpanders)
	{
		window.aImageExpanders = new Array();
	}
	window.aImageExpanders.push(this);

	// create the full sized image.
	this.oImg = new Image();
	this.oImg.expander = this;
	this.oImg.onload = function(){this.expander.onload();}
	this.oImg.src = sImgSrc;
}

ImageExpander.prototype.onload = function()
{
	this.bgDiv = document.createElement("div");
	this.bgDiv.style.position = "absolute";
	this.bgDiv.style.border = "solid #888888 0px";
	this.bgDiv.style.top = "0px";
	this.bgDiv.style.filter = "alpha(opacity=50)";
	this.bgDiv.style.MozOpacity = 0.5;
	this.bgDiv.style.backgroundColor = "#BBBBBB";
	this.bgDiv.expander = this;
	this.bgDiv.style.width = document.getWidth() + "px";
	this.bgDiv.style.height = document.getHeight() + "px";
	this.bgDiv.onclick = function() {this.expander.toggle();};
	document.body.appendChild(this.bgDiv);
	
	this.oDiv = document.createElement("div");
	document.body.appendChild(this.oDiv);
	this.oDiv.appendChild(this.oImg);
	this.oDiv.style.position = "absolute";
	this.oDiv.style.border = "solid #888888 2px";
	this.oDiv.style.backgroundColor = "#FFFFFF";
	this.oDiv.expander = this;
	this.oDiv.onclick = function() {this.expander.toggle();};
	this.oImg.title = "Click to reduce.";
	this.bigWidth = this.oImg.width;
	this.bigHeight = this.oImg.height;

	if (this.bExpand)
	{
		this.expand();
	} else
	{
		this.oDiv.style.visibility = "hidden";
		this.oImg.style.visibility = "hidden";
	}
}
ImageExpander.prototype.toggle = function()
{
	this.bExpand = !this.bExpand;
	if ( this.bExpand )
	{
		for (i = 0; i < 10; i++)
			if (window.aImageExpanders[i] && window.aImageExpanders[i] !== this )
				window.aImageExpanders[i].reduce();
	}
}

function getOffsetLeft(elem)
{
	// Return the x coordinate where the image starts.
	if (elem.offsetParent) {
		// Recurse up to the parent element, all the way to the root element.
		return getOffsetLeft(elem.offsetParent) + elem.offsetLeft;
	} else {
		// Root element found, the +1 is because this offset returns a distance, and we want a coordinate.
		return elem.offsetLeft + 1;
	}
} 

function getOffsetTop(elem)
{
	// Return the x coordinate where the image starts.
	if (elem.offsetParent) {
		// Recurse up to the parent element, all the way to the root element.
		return getOffsetTop(elem.offsetParent) + elem.offsetTop;
	} else {
		// Root element found, the +1 is because this offset returns a distance, and we want a coordinate.
		return elem.offsetTop + 1;
	}
} 


ImageExpander.prototype.expand = function()
{
	// set direction of expansion.
	this.bExpand = true;

	// set all other images to reduce
	for (i = 0; i < 10; i++)
		if (window.aImageExpanders[i] && window.aImageExpanders[i] !== this )
			window.aImageExpanders[i].reduce();

	// if not loaded, don't continue just yet
	if ( !this.oDiv ) return;

	// hide the thumbnail
	// this.oThumb.style.visibility = "hidden";

	// calculate initial dimensions
	this.x = getOffsetLeft(this.oThumb);
	this.y = getOffsetTop(this.oThumb);
	this.w = this.oThumb.clientWidth;
	this.h = this.oThumb.clientHeight;

	this.oDiv.style.left = this.x + "px";
	this.oDiv.style.top = this.y + "px";
	this.oImg.style.width = this.w + "px";
	this.oImg.style.height = this.h + "px";
	this.oDiv.style.visibility = "visible";
	this.bgDiv.style.visibility = "visible";
	this.oImg.style.visibility = "visible";

	// start the animation engine.
	if (!this.bTicks)
	{
		this.bTicks = true;
		var pThis = this;
		window.setTimeout(function(){pThis.tick();},25);	
	} 
}

ImageExpander.prototype.reduce = function()
{
	// set direction of expansion.
	this.bExpand = false;
}

ImageExpander.prototype.tick = function()
{
	// calculate screen dimensions
	var cw = document.getWidth(); // document.body.clientWidth;
	var ch = document.getHeight(); // document.body.clientHeight;
	var cx = document.body.scrollLeft + cw / 2;
	var cy = document.body.scrollTop + ch / 2;

	// calculate target
	var tw,th,tx,ty;
	if ( this.bExpand )
	{
		tw = this.bigWidth;
		th = this.bigHeight;
		if ( tw > cw )
		{
			th *= cw / tw;
			tw = cw;
		}	
		if ( th > ch )
		{
			tw *= ch / th;
			th = ch;
		}
		tx = cx - tw / 2;
		ty = cy - th / 2; 
	} else
	{
		tw = this.smallWidth;
		th = this.smallHeight;
		tx = getOffsetLeft(this.oThumb);
		ty = getOffsetTop(this.oThumb);
	}	
	// move 5% closer to target
	var nHit = 0;
	var fMove = function(n,tn) 
	{
		var dn = tn - n;
		if ( Math.abs(dn) < 3 )
		{
			nHit++;
			return tn;
		} else
		{
			return n + dn / 5;
		}
	}
	this.x = fMove(this.x, tx);
	this.y = fMove(this.y, ty);
	this.w = fMove(this.w, tw);
	this.h = fMove(this.h, th);

	this.oDiv.style.left = this.x + "px";
	this.oDiv.style.top = this.y + "px";
	this.oImg.style.width = this.w + "px";
	this.oImg.style.height = this.h + "px";

	// if reducing and size/position is a match, stop the tick	
	if (!this.bExpand && (nHit == 4))
	{
		this.oImg.style.visibility = "hidden";
		this.oDiv.style.visibility = "hidden";
		this.bgDiv.style.visibility = "hidden";
		this.oThumb.style.visibility = "visible";
		this.bTicks = false;
		this.oThumb.onclick = this.OrgOnClickFunction;
	}

	if (this.bTicks)
	{
		var pThis = this;
		window.setTimeout(function(){pThis.tick();},25);
	}
}

