// 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.enlarge = function()
	{
		if (!this.backgroundFaded)
		{
			this.fadeBackground(true);
		}
		if (!this.enlargedImage.complete)
		{
			if(!this.loadingVisible)
			{
				this.showHideLoading(true);
			}
			this.preloadTimeoutID = setTimeout(function(){thisObj.enlarge()}, 10);
		}
		else
		{
			this.showHideLoading(false);
			clearTimeout(this.preloadTimeoutID);
			if (this.TimeoutIDArr)
			{
				for (var i=this.frameNumber; i >= 0; i--)
				{
					clearTimeout(this.TimeoutIDArr[i]);
				}
			}
			this.initFrameState();
			this.enlargedImage.style.visibility = 'visible';
			this.TimeoutIDArr = new Array();
			for (var i=0; i <= this.framesCount; i++)
			{
				this.tmp = function(i)
				{
					this.TimeoutIDArr[i] = setTimeout(function(){thisObj.drawFrameState(i)}, this.AnimationSpeed * i);
				}
				this.tmp(i);
			}
		}
	}
	this.reduce = function()
	{
		for (var i=this.frameNumber; i <= this.framesCount; i++)
		{
			clearTimeout(this.TimeoutIDArr[i]);
		}
		this.TimeoutIDArr = new Array();
		for (var i=this.frameNumber; i >= 0; i--)
		{
			this.tmp = function(i)
			{
				this.TimeoutIDArr[i] = setTimeout(function(){thisObj.drawFrameState(i)}, this.AnimationSpeed * (this.frameNumber - i));
			}
			this.tmp(i);
			
			if (i == 0 && this.backgroundFaded)
			{
				this.TimeoutIDArr[i] = setTimeout(function(){thisObj.fadeBackground(false);thisObj.enlargedImage.style.visibility = 'hidden';}, this.AnimationSpeed*(this.frameNumber));
			}
		}
		
	}
	this.changeOpacity = function(object, opacity)
	{
		if (typeof(this.OpacityType) == "undefined")
		{
			this.getOpacityType();
		}
		if (opacity < 0)
		{
			opacity = 0;
		}
		if (this.OpacityType == "filter")
		{
			var oAlpha = object.filters['DXImageTransform.Microsoft.alpha'] || object.filters.alpha;
			if (oAlpha)
			{
				oAlpha.opacity = opacity*100;
			}
			else
			{
				object.style.filter += "progid:DXImageTransform.Microsoft.Alpha(style=0, opacity="+ Math.round(opacity*100) +", FinishOpacity="+ Math.round(opacity*100) +")";
			}
		}
		else
		{
			object.style[this.OpacityType] = opacity;
		}
	}
	
	this.getOpacityType = function ()
	{
		this.OpacityType = false;
		if (typeof(document.body.style.opacity) == 'string') // CSS3 compliant (Moz 1.7+, Safari 1.2+, Opera 9, IE7)
			this.OpacityType = 'opacity';
		else if (typeof(document.body.style.MozOpacity) == 'string') // Mozilla 1.6 && less, Firefox 0.8 
			this.OpacityType = 'MozOpacity';
		else if (typeof(document.body.style.KhtmlOpacity) == 'string') // Konqueror 3.1, Safari 1.1
			this.OpacityType = 'KhtmlOpacity';
		else if (document.body.filters && navigator.appVersion.match(/MSIE ([\d.]+);/)[1] >= 5.5 )// Internet Exploder 5.5+
			this.OpacityType =  'filter';
	}
	
	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) 
			{
				if (obj.id == mainBlock.id)
				{
					curleft += obj.offsetLeft;
					curtop += obj.offsetTop;
					break;
				}
				curleft += obj.offsetLeft - obj.scrollLeft;
				curtop += obj.offsetTop - obj.scrollTop;
			}
		}
		return [curleft,curtop];
	}
	this.drawFrameState = function(currentFrameNumber)
	{
		this.frameNumber = currentFrameNumber;
		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.changeOpacity(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';
	}
	this.fadeBackground = function(show)
	{
		if (destTranspLayer && mainBlock)
		{
			if (!this.backgroundFaded && show)
			{
				var windowScroll = viewPortTop;
				var mainHeight = mainBlock.offsetHeight;
				
				if (viewPortHeight < mainHeight)
					destTranspLayer.style.height = mainHeight + 'px';
				else
					destTranspLayer.style.height = viewPortHeight + 'px';
				destTranspLayer.style.width = viewPortWidth + 'px';
				destTranspLayer.style.display = "block";
				this.changeOpacity(destTranspLayer, 0.5);
				this.backgroundFaded = true;
			}
			else if (!show)
			{
				destTranspLayer.style.display = "none";
				this.changeOpacity(destTranspLayer, 0);
				this.backgroundFaded = false;
			}
		}
	}
	this.showHideLoading = function(show)
	{
		var loadingObj = document.getElementById('loadingObjPicture') || false;
		if (!loadingObj)
		{
			var loadingObj = document.createElement('div');
			loadingObj.id = 'loadingObjPicture';
			loadingObj.className = 'loadingImage';
			loadingObj.style.left = (viewPortWidth/2 - 24) + 'px';
			loadingObj.style.top = (viewPortTop + viewPortHeight/2 - 24) + 'px';
			bodyContainer.appendChild(loadingObj);
		}
		if(!this.loadingVisible && show)
		{
			this.loadingVisible = true;
			loadingObj.style.display = 'block';
		}
		else if (!show)
		{
			this.loadingVisible = false;
			loadingObj.style.display = 'none';
		}
	}
	this.initFrameState = function()
	{
		this.frameNumber = 0;
		this.calculateViewPort();
		this.xStartSize = this.originalElement.offsetWidth;
		this.yStartSize = this.originalElement.offsetHeight;
		aspectRatio = this.enlargedImage.offsetWidth / this.enlargedImage.offsetHeight;
		
		var sourcePosition = this.findPos(this.originalElement);
		this.xStartCoordinate = sourcePosition[0];
		this.yStartCoordinate = sourcePosition[1];
		
		this.changeOpacity(this.enlargedImage, 0);
		
		if (this.xEndSize == 0 || this.yEndSize == 0)
		{
			this.xEndSize = this.enlargedImage.offsetWidth;
			this.yEndSize = this.enlargedImage.offsetHeight;
			
			if (this.xEndSize >= viewPortWidth) 
			{
				this.xEndSize = viewPortWidth * 0.9;
				this.yEndSize = this.xEndSize / aspectRatio;
			}
			if (this.yEndSize >= viewPortHeight) 
			{
				this.yEndSize = viewPortHeight * 0.9;
				this.xEndSize = this.yEndSize * aspectRatio;
			}
		}
		
		this.xEndCoordinate = viewPortWidth/2 - this.xEndSize/2;
		this.yEndCoordinate = viewPortTop + viewPortHeight/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';
	}
	
	this.calculateViewPort = function()
	{
		if (window.pageYOffset)
		{
			viewPortLeft = window.pageXOffset;
			viewPortTop = window.pageYOffset;
		}
		else
		{
			viewPortLeft = document.documentElement.scrollLeft;
			viewPortTop = document.documentElement.scrollTop;
		}
		viewPortWidth = document.documentElement.offsetWidth;
		viewPortHeight = document.documentElement.offsetHeight;
	}
	
	var thisObj = this;
	this.frameNumber = 0;
	this.framesCount = 15;
	this.AnimationSpeed = 30;
	this.originalElement = element;
	this.xEndSize = 0;
	this.yEndSize = 0;
	this.enlargedImage = new Image();
	this.enlargedImage.className = 'enlargedImage';
	this.enlargedImage.src = url;
	this.enlargedImage.onclick = function()
	{
		thisObj.reduce();
	}
	this.calculateViewPort();
	destTranspLayer = document.getElementById('transparent_overlay') || false;
	mainBlock = document.getElementById('main_block') || false;
	bodyContainer = document.getElementById('body_container') || false;
	bodyContainer.appendChild(this.enlargedImage);
}
function startZoomAnimation(element, url)
{
	if (window.contentLoaded)
	{
		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.enlarge();
		
	}
	else
	{
		window.domLoadTree.fn_startAnimation = function(){startZoomAnimation(element, url)};
	}
}