// ZoomAttitude
//
// Copyright (c) 2008 NuAttitude Ltd www.nuattitude.ee
// All rights reserved.
// 
// Redistribution and use of this effect in source form, with or without modification,
// are permitted provided that the following conditions are met:
// 
// * USE OF SOURCE ON COMMERCIAL (FOR-PROFIT) WEBSITE REQUIRES ONE-TIME LICENSE FEE PER DOMAIN.
//   Reasonably priced! Email: info@nuattitude.ee for licensing instructions. Thanks!
//
// * Redistribution of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//
// * Redistribution of source code and derived works cannot be sold without specific
//   written prior permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var lastUsedZoomingPicture;
function zoomingPicture(element, url)
{
	this.clicked = function()
	{
		if (this.fullyEnlarged == true)
		{
			this.reduce();
		}
		else
		{
			this.enlarge();
		}
	}
	this.enlarge = function()
	{
		if (!this.enlargedImage.complete)
		{
			this.preloadTimeoutID = setTimeout(function(){thisObj.enlarge()}, 10);
		}
		else
		{
			clearTimeout(this.preloadTimeoutID);
			clearTimeout(this.timeoutID);
			this.initFrameState();
			this.enlargedImage.style.visibility = 'visible';
			this.drawFrameState(1);
		}
	}
	this.reduce = function()
	{
		clearTimeout(this.timeoutID);
		this.enlargedImage.style.visibility = 'visible';
		this.drawFrameState(0);
	}
	this.opacity = function(object, opacity) 
	{
		object.style.opacity = opacity;
		object.style.MozOpacity = opacity;
		object.style.opacity = opacity;
		object.style.filter = "alpha(opacity=" + opacity*100 + ")";
	}
	this.calcFrameCoordinate = function(startPosition, frameNumber, acceleration)
	{
		var coordinate = startPosition + (acceleration*frameNumber*frameNumber)/2
		return coordinate;
	}
	this.calcAcceleration = function(startPosition, endPosition, framesCount)
	{
		var acceleration = 2*(endPosition - startPosition)/(framesCount*framesCount);
		return acceleration;
	}
	this.findPos = function(obj)
	{
		var curleft = curtop = 0;
		if (obj.offsetParent)
		{
			curleft = obj.offsetLeft;
			curtop = obj.offsetTop;
			while (obj = obj.offsetParent) 
			{
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			}
		}
		return [curleft,curtop];
	}
	this.drawFrameState = function(direction)
	{
		this.xCoordinate = this.calcFrameCoordinate(this.xStartCoordinate, this.frameNumber, this.xMovementAcceleration);
		this.yCoordinate = this.calcFrameCoordinate(this.yStartCoordinate, this.frameNumber, this.yMovementAcceleration);

		this.xSize = this.calcFrameCoordinate(this.xStartSize, this.frameNumber, this.xSizeAcceleration);
		this.ySize = this.calcFrameCoordinate(this.yStartSize, this.frameNumber, this.ySizeAcceleration);

		newOpacity = this.frameNumber / this.framesCount;
		newOpacity = newOpacity * newOpacity;
		this.opacity(this.enlargedImage, newOpacity);
		
		this.enlargedImage.style.left = this.xCoordinate + 'px';
		this.enlargedImage.style.top = this.yCoordinate + 'px';
		
		this.enlargedImage.style.width = this.xSize + 'px';
		this.enlargedImage.style.height = this.ySize + 'px';
		
		if (direction == 0)
		{
			if (this.frameNumber > 0)
			{
				this.frameNumber--;
				this.timeoutID = setTimeout(function(){thisObj.drawFrameState(0)}, this.AnimationSpeed);
			}
			else
			{
				this.enlargedImage.style.visibility  = 'hidden';
				this.fullyEnlarged = false;
			}
		}
		else
		{
			if (this.frameNumber < this.framesCount)
			{
				this.frameNumber++;
				this.timeoutID = setTimeout(function(){thisObj.drawFrameState(1)}, this.AnimationSpeed);
			}
			else
			{
				this.fullyEnlarged = true;
			}
			
		}
	}
	this.initFrameState = function()
	{
		this.frameNumber = 0;
		
		this.xStartSize = this.originalElement.offsetWidth;
		this.yStartSize = this.originalElement.offsetHeight;
		aspectRatio = this.enlargedImage.offsetWidth / this.enlargedImage.offsetHeight;
		
		var sourcePosition = this.findPos(this.originalElement);
		
		viewportObject = document.getElementById('viewport');
		
		this.xStartCoordinate = sourcePosition[0];
		this.yStartCoordinate = sourcePosition[1];
		
		this.opacity(this.enlargedImage, 0);
		
		if (this.xEndSize == 0 || this.yEndSize == 0)
		{
			this.xEndSize = this.enlargedImage.offsetWidth;
			this.yEndSize = this.enlargedImage.offsetHeight;
			
			if (this.xEndSize >= viewportObject.offsetWidth) 
			{
				this.xEndSize = viewportObject.offsetWidth * 0.9;
				this.yEndSize = this.xEndSize / aspectRatio;
			}
			if (this.yEndSize >= viewportObject.offsetHeight) 
			{
				this.yEndSize = viewportObject.offsetHeight * 0.9;
				this.xEndSize = this.yEndSize * aspectRatio;
			}
		}
		
		this.xEndCoordinate = viewportObject.offsetWidth/2 - this.xEndSize/2;
		this.yEndCoordinate = viewportObject.scrollTop + viewportObject.offsetHeight/2 - this.yEndSize/2;
		
		this.xMovementAcceleration = this.calcAcceleration(this.xStartCoordinate, this.xEndCoordinate, this.framesCount);
		this.yMovementAcceleration = this.calcAcceleration(this.yStartCoordinate, this.yEndCoordinate, this.framesCount);
		
		this.xSizeAcceleration = this.calcAcceleration(this.xStartSize, this.xEndSize, this.framesCount);
		this.ySizeAcceleration = this.calcAcceleration(this.yStartSize, this.yEndSize, this.framesCount);
		
		this.enlargedImage.style.width = this.xStartSize + 'px';
		this.enlargedImage.style.height = this.yStartSize + 'px';	
		
		this.enlargedImage.style.left = this.xStartCoordinate + 'px';
		this.enlargedImage.style.top = this.yStartCoordinate + 'px';
	}

	var thisObj = this;
	this.frameNumber = 0;
	this.framesCount = 15;
	this.AnimationSpeed = 15;
	this.originalElement = element;
	this.xEndSize = 0;
	this.yEndSize = 0;
	this.fullyEnlarged = false;
	this.enlargedImage = new Image();
	this.enlargedImage.className = 'enlargedImage';
	this.enlargedImage.src = url;
	this.enlargedImage.onclick = function()
	{
		thisObj.reduce();
	}
	viewportObject = document.getElementById('viewport');
	viewportObject.appendChild(this.enlargedImage);
}
function startZoomAnimation(element, url)
{
	if (typeof(lastUsedZoomingPicture) != 'undefined')
	{
		lastUsedZoomingPicture.reduce();
	}
	if (typeof(element.zoomingPicture) != 'undefined')
	{
		if (element.zoomingPicture.enlargedImage.src == url)
		{
			newZoomImage = element.zoomingPicture;
		}
		else
		{
			newZoomImage = new zoomingPicture(element, url);
			element.zoomingPicture = newZoomImage;
		}
	}
	else
	{
		newZoomImage = new zoomingPicture(element, url);
		element.zoomingPicture = newZoomImage;
	}
	lastUsedZoomingPicture = newZoomImage;
	newZoomImage.clicked();
}