var marbles = new Array(6);
var shadows = new Array(6);

var scaleMin = 32;
var scaleMax = 64;
var scaleSpan = 128;

var lastChosenMarble = -1;

window.onload = function()
{
	initMarbles();
}


function Marble()
{
	this.x = 0;
	this.y = 0;
	this.width = 0;			
	this.height = 0;
	this.deltaY = 0;
	this.gravityY = 0;
	this.bounceDecayY = 0;
	this.deltaDeflate = 0;

	this.isBouncing = false;
	this.isDeflating = false;

	this.alpha = 100;
	this.deltaAlpha = 0.0;
	this.displayString = "";
}

function Shadow()
{
	this.width = 0;	
	this.height = 0;
	this.alpha = 100;
}


function initMarbles()
{
	for (var marbleIndex = 0; marbleIndex < 6; marbleIndex ++)
	{
		marbles[marbleIndex] = new Marble();
		shadows[marbleIndex] = new Shadow();

		resetBounce(marbleIndex);
	}

	marbles[0].displayString = "Our design philosophy; things we've designed...";
	marbles[1].displayString = "Our development process; things we've developed...";
	marbles[2].displayString = "Things we've delivered: websites, software...";
	marbles[3].displayString = "Discussion, contact details, blog...";
	marbles[4].displayString = "Training material, hints and tips...";
	marbles[5].displayString = "Technical support, moral support, and more...";
}


function rolledOverMarbles(event)
{
	//	get the event...
	if (!event)
	{
		event = window.event || arguments.callee.caller.arguments[0];
	}

	//	get the mouse co-ordinates, regardless of which browser we're working in...
	var posX = 0;
	var posY = 0;
	if (event.pageX || event.pageY)
	{
		posX = event.pageX;
		posY = event.pageY;
	}
	else if (event.clientX || event.clientY)
	{
		posX = event.clientX + document.body.scrollLeft;
		posY = event.clientY + document.body.scrollTop;
	}

	//	find out where the bounding box is...
	var boundingBoxId = "marbles";
	var boundingBoxLeft = 0;
	if (document.getElementById)
	{
		boundingBox = document.getElementById(boundingBoxId);
		boundingBoxLeft = boundingBox.offsetLeft;
	}

	boundingBoxId = "menu";
	var boundingBoxTop = 0;
	if (document.getElementById)
	{
		boundingBox = document.getElementById(boundingBoxId);
		boundingBoxTop = boundingBox.offsetTop;
	}

	//	calculate mouse position local to bounding box...
	posX = posX - boundingBoxLeft;
	posY = posY - boundingBoxTop;

//	updateDisplay("posY = " + posY);

	//	check to see if we're out of bounding box...
//	if (posX < 0 || posX > 386 || posY < 0 || posY > 148)
	if (posX < 0 || posX > 386)
	{
		//	mouse is out of bounding box, so no need to track any more, get marbles to deflate...
		document.onmousemove = null;
		updateDisplay("PyrusMalus");

		for (var marbleIndex = 0; marbleIndex < 6; marbleIndex ++)
		{
			marble = marbles[marbleIndex];
			marble.isDeflating = true;
			marble.deltaDeflate = -1;
		}
		window.setTimeout("updateAndDrawMarbles()", 10);
	}
	else
	{
		// 	mouse is in bounding box, so work out which marble it is over...
		var chosenMarble = Math.round((posX + 32) / 64) - 1;
		chosenMarble = (chosenMarble < 0) ? 0 : ((chosenMarble > 5) ? 5 : chosenMarble);

		if (chosenMarble != lastChosenMarble)
		{
			updateDisplay(marbles[chosenMarble].displayString);
			lastChosenMarble = chosenMarble;
		}

		//	for all of the marbles...
		for (var marbleIndex = 0; marbleIndex < 6; marbleIndex++)
		{
			marble = marbles[marbleIndex];
			shadow = shadows[marbleIndex];

			//	work out delta value for marble...
			gapSize = (384 / (6 * 2));
			lineX = -gapSize + (gapSize * 2 * (marbleIndex + 1));
			xDelta = posX - lineX;
			delta = Math.abs(xDelta);

			//	scale the scale value based on delta...
			var aScale = ((scaleMin - scaleMax) / scaleSpan) * delta + scaleMax;
			if (aScale < scaleMin)
			{
				aScale = scaleMin;
			}
			else if (aScale > scaleMax)
			{
				aScale = scaleMax;
			}

			marble.width = aScale;
			marble.height = aScale;

			shadow.width = aScale;
			shadow.height = aScale;
	
//			window.setTimeout("updateAndDrawMarbles()", 10);

			drawMarbles();
		}

		document.onmousemove = handleMouseMoved;
	}
	
	return;
}


function handleMouseMoved()
{
	rolledOverMarbles();
}


function drawMarbles()
{
	//	draw all marbles at the appropriate place...
	for (var marbleIndex = 0; marbleIndex < 6; marbleIndex++)
	{
		marbleObjectId = "marble_" + marbleIndex;
		shadowObjectId = "shadow_" + marbleIndex;
		if (document.getElementById)
		{
			marbleObject = document.getElementById(marbleObjectId);
			shadowObject = document.getElementById(shadowObjectId);
			marble = marbles[marbleIndex];
			shadow = shadows[marbleIndex];

			niceWidth = Math.round(marble.width);
			if (niceWidth % 2)
			{
				niceWidth = niceWidth + 1;
			} 

			niceHeight = Math.round(marble.height);
			if (niceHeight % 2)
			{
				niceHeight = niceHeight + 1;
			} 

			//	set the marble's x, y, width, height, and alpha...
			marbleObject.width = niceWidth;
			marbleObject.height = niceHeight;

			//	need to play with padding to keep image where it should be...
			paddingLeft = (64 - niceWidth) / 2;
			paddingTop = 128 - niceHeight - Math.abs(marble.y);

			marbleObject.style.marginLeft = paddingLeft + "px";
			marbleObject.style.marginTop = paddingTop + "px";

			//	set the shadow's x, y, sizeX, sizeY, and alpha...

			niceShadowWidth = Math.round(shadow.width);
			if (niceShadowWidth % 2)
			{
				niceShadowWidth = niceShadowWidth + 1;
			} 

			niceShadowHeight = Math.round(shadow.height);
			if (niceShadowHeight % 2)
			{
				niceShadowHeight = niceShadowHeight + 1;
			} 

			shadowObject.width = niceShadowWidth;
			shadowObject.height = niceShadowHeight;

			//	need to play with padding to keep image where it should be...
			shadowPaddingTop = 128 - niceShadowHeight;
			shadowPaddingLeft = (64 - niceShadowWidth) / 2;
			shadowObject.style.marginLeft = shadowPaddingLeft + "px";
			shadowObject.style.marginTop = shadowPaddingTop + "px";

			setOpacity(shadowObject, shadow.alpha);
		}
	}
}

function updateMarbles()
{
	//	go through marbles and add any deltas, perform any direction changes...
	stillNeedsUpdate = false;
	for (var marbleIndex = 0; marbleIndex < 6; marbleIndex++)
	{
		marble = marbles[marbleIndex];
		shadow = shadows[marbleIndex];

		//	check if marble is moving...
		if (marble.isDeflating)
		{
			newWidth = marble.width + marble.deltaDeflate;
			newHeight = marble.height + marble.deltaDeflate;

			if (newWidth < 32 || newHeight < 32)
			{				
				newHeight = 32;
				newWidth = 32;
				marble.isDeflating = false;
				marble.deltaDeflate = 0;
			}
			marble.width = newWidth;
			marble.height = newHeight;

			shadow.width = newWidth;
			shadow.height = newHeight;
		}

		if (marble.isBouncing)
		{
			//	update position...
			newY = marble.y + marble.deltaY;

			//	movement affected by gravity...
			marble.deltaY = marble.deltaY + marble.gravityY;

			//	check if we've hit the ground...
			if (newY >= 0)
			{
				//	reverse direction...
				marble.deltaY = -marble.deltaY;

				//	and lose some energy...
				marble.deltaY = marble.deltaY + Math.min(Math.abs(marble.deltaY), Math.abs(marble.bounceDecayY)) + marble.gravityY;

				//	if delta has gone zero, or is attempting to go below ground, we're now at rest...
				if (marble.deltaY >= 0)
				{
					marble.isBouncing = false;
					shadow.alpha = 100;
				}

				newY = 0;
			}

			marble.y = newY;

			//	shadow changes according to height of marble above ground...
			heightAboveGround = -marble.y;

			//	shadow alpha decreases as height increases...
			shadow.alpha = 100 - heightAboveGround;
			shadow.width = marble.width - heightAboveGround / 2;
			shadow.height = marble.height - heightAboveGround / 2;
		}

		if (marble.isBouncing || marble.isDeflating)
		{
			stillNeedsUpdate = true;
		}
	}

	if (stillNeedsUpdate)
	{
		window.setTimeout("updateAndDrawMarbles()", 10);
	}
}


function updateAndDrawMarbles()
{
	updateMarbles();
	drawMarbles();
}


function resetBounce(inMarbleIndex)
{
	marbles[inMarbleIndex].deltaY = -7;
	marbles[inMarbleIndex].gravityY = 0.5;
	marbles[inMarbleIndex].bounceDecayY = 1.5;
}


function clickedMarble(inMarbleIndex)
{
	if (!marbles[inMarbleIndex].isBouncing)
	{
		marbles[inMarbleIndex].isBouncing = true;
		resetBounce(inMarbleIndex);

		updateMarbles();
		drawMarbles();
	}
}



function updateDisplay(inDisplayString)
{
	objectId = "display_string";
	if (document.getElementById)
	{
		object = document.getElementById(objectId);
		object.innerHTML = inDisplayString;
	}
}


function setOpacity(object, opacity)
{
	opacity = (opacity == 100 ? 99.999 : opacity);
	
	//	Safari 1.2, Firefox, Mozilla, CSS3...
	object.style.opacity = opacity / 100;

	//	Old Mozilla, Firefox...
	object.style.MozOpacity = opacity / 100;

	//	Old Safari, Konqueror...
	object.style.KHTMLOpacity = opacity / 100;

	//	IE/Win...
	object.style.filter = "alpha(opacity:"+opacity+")";
}



function setOpacityForId(objectId, opacity)
{
	if (document.getElementById)
	{
		object = document.getElementById(objectId);
		setOpacity(object, opacity);
	}
}

