// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var currentPopupImage = new GalleryItem();

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// Class LayoutPortion

function LayoutPortion(yPos, xStart,xEnd)
{
	this.yPos = yPos;
	this.xStart = xStart;
	this.xEnd = xEnd;
}

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LayoutPortion.prototype.width = function width()
{
	return this.xEnd - this.xStart;
}

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LayoutPortion.prototype.setWidth = function setWidth(newWidth)
{
	this.xEnd = this.xStart + newWidth;
}

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function centerPopupImage()
{
//	alert('center!');
	if ( (currentPopupImage.image1) && (currentPopupImage.image2) )
	{
	// If the viewport is too small for image1, use image2 instead.
	if (currentPopupImage.image1.complete && currentPopupImage.image2.complete)
	{
//		alert('both images are ready!');

		if (currentPopupImage.currentImageSize == 1)		
		{
			if ( (currentPopupImage.image1.height > (viewportHeight-100)) || (currentPopupImage.image1.width > (viewportWidth-100)) )			
			{
				currentPopupImage.currentImageSize = 2;

				currentPopupImage.img.src = currentPopupImage.image2path();

				currentPopupImage.img.width = currentPopupImage.currentWidth();
				currentPopupImage.img.height = currentPopupImage.currentHeight();
			}

		}
		else
		{
			if (currentPopupImage.currentImageSize == 2)
			{
//				alert('check for enlarfing');
				if (!( (currentPopupImage.image1.height > (viewportHeight-100)) || (currentPopupImage.image1.width > (viewportWidth-100)) )	)
				{
					currentPopupImage.currentImageSize = 1;

					currentPopupImage.img.src = currentPopupImage.image1path();

					currentPopupImage.img.width = currentPopupImage.currentWidth();
					currentPopupImage.img.height = currentPopupImage.currentHeight();
				}
				else
				{
//					alert('no enlarge');
				}
			}
		}
	}
	else
	{
//		alert('images are not complete !');
	}
	}
	else
	{
//		alert('images are not there at all!');
	}

	// ---

	var popupImage = document.getElementById('popup-image');
	if (popupImage)
	{
		// Center the image
		if (navigator.appName != 'Microsoft Internet Explorer')
		{
			var topPos = Math.max(0.5*(viewportHeight - popupImage.offsetHeight),50);			
			popupImage.style.top = topPos;
		}
		
		popupImage.style.left = Math.max(0.5*(viewportWidth - popupImage.offsetWidth),50);
	}
//	alert('center end');
}

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function layoutElems()
{
	elems = getElementsByClassName('uber-layout-item');

	var footer = document.getElementById('footer');

	if (footer.vbrlOpacity == undefined)
	{
		footer.vbrlOpacity = 0.0;
	}

	elems = elems.concat(footer);

	return elems;
}

// --------------------------------------------------------------------------------------------------------------------------------------------------------------------

function revealMoreLayout()
{
	elems = layoutElems();

	globalIds.push(elems);

	revealMore(globalIds.length-1, revealInterval);
}

// --------------------------------------------------------------------------------------------------------------------------------------------------------------------

function revealAllLayout()
{
	if (elems == undefined)
	{
		return;
	}

	// ---

	elems = layoutElems()

	globalIds.push(elems);

	revealAll(globalIds.length-1);
}

// --------------------------------------------------------------------------------------------------------------------------------------------------------------------

function uberLayout(fade,maxLayoutWidth)
{
	var gutterWidth = 10;

	var marginTop = 50;
	var minMarginTop = 50;
	var minMarginLeft = 50;
	var marginLeft = 50;

	getViewportSize();

//	centerPopupImage();

	if (maxLayoutWidth == undefined)
	{
		maxLayoutWidth = viewportWidth;
	}
	else
	{
		maxLayoutWidth = Math.min(viewportWidth,maxLayoutWidth);
	}

	var layoutWidth = maxLayoutWidth-(2*minMarginLeft);
db('layout width: ' + layoutWidth);
db(' ');
	// ---------------------------------------------------	

	elems = getElementsByClassName('uber-layout-item');

	// ---------------------------------------------------	

	var layoutPortions = new Array(1);
//	layoutPortions[0] = new LayoutPortion(0, 0,layoutWidth);
	layoutPortions[0] = new LayoutPortion(0, 0,10000);

//db(layoutPortions[0].width());

	// ---------------------------------------------------

	function nbPortions()
	{
		return layoutPortions.length;
	}

	// ---------------------------------------------------

	function lastPortion()
	{
		return layoutPortions[layoutPortions.length-1];
	}

	// ---------------------------------------------------

	function portionsGroupWidth(firstPortion)
	{
		var totalWidth = layoutPortions[firstPortion].width();
		var nbNext = 0;

		while ((firstPortion + nbNext + 1) < layoutPortions.length)
		{
			if (layoutPortions[firstPortion + nbNext + 1].yPos <= layoutPortions[firstPortion].yPos)
			{
				nbNext++;
				totalWidth += layoutPortions[firstPortion + nbNext].width() + gutterWidth;
			}
			else
			{
				break;
			}
		}

		return Math.min(totalWidth,layoutWidth-layoutPortions[firstPortion].xStart);
	}

	// ---------------------------------------------------

	function highestAvailableHeight(firstPortion,elemWidth)
	{
		var xPos = layoutPortions[firstPortion].xEnd;
		var highestAvailable = layoutPortions[firstPortion].yPos;

		var nbNext = 0;

		while ( (xPos < (layoutPortions[firstPortion].xStart + elemWidth)) && ((firstPortion+nbNext+1) < nbPortions()) )
		{
			nbNext++;
			xPos = layoutPortions[firstPortion+nbNext].xEnd;
			highestAvailable = Math.max( highestAvailable, layoutPortions[firstPortion+nbNext].yPos );
		}

		return highestAvailable;
	}

	// ---------------------------------------------------

	var xMax = 0;
	var yMax = 0;

	var previousElem = undefined;

	for (i = 0; i < elems.length; i++)
	{
db('Elem: ' + i);
		var elem = elems[i];

		var elemWidth = elem.offsetWidth;
		var elemHeight = elem.offsetHeight;

		// ---

		

db('elem-width: ' + elemWidth);

		// If the previous element defines a allow-line-break == false, don't look any further a layout the current element right after it

		var highestIndex = 0;
		var highestPos = 1000000;

		var allowLineBreak = true;

		if (previousElem != undefined)
		{
			if (previousElem.getAttribute("allow-line-break") == "false")
			{
				allowLineBreak = false;
			}
		}

		if (allowLineBreak == false)
		{
db('previously: allow-line-break == false => automatic layout');
			highestPos = previousElem.yPos;
			highestIndex = previousElem.iPortion+1;
		}
		else

		{
			// Find the highest portion or group of portions where we can insert the current element.
			
	
			for (iPortion = 0; iPortion < layoutPortions.length; iPortion++)
			{
				var currentPortion = layoutPortions[iPortion];				

//db('free portion group width: ' + portionsGroupWidth(iPortion))				
				if (elemWidth <= portionsGroupWidth(iPortion))
				{
					if (currentPortion.yPos < highestPos)
					{
						highestPos = currentPortion.yPos;
						highestIndex = iPortion;
					}
				}
			} // for iPorion
			
		}
//db('highest available height: ' + highestAvailable);

		// ---

		// Set the element position
		elem.style.position = 'absolute';
db('highest index: ' + highestIndex);

		// Due to automatic layout following a allow-line-break == false, the next portion might not exist yet (happens only when the window size fit exactly the last element's end)
		if (highestIndex > nbPortions()-1)
		{
		}

		elem.style.left = layoutPortions[highestIndex].xStart;
		elem.style.top = highestAvailableHeight(highestIndex,elemWidth);

		elem.leftSet = layoutPortions[highestIndex].xStart;
		elem.topSet = highestAvailableHeight(highestIndex,elemWidth);

		// Will be read when laying out the next element
		elem.yPos = highestAvailableHeight(highestIndex,elemWidth);
		elem.iPortion = highestIndex;

		// Update the total page size
		/*
		xMax = Math.max(xMax, elem.offsetLeft + elemWidth);
		yMax = Math.max(yMax, elem.offsetTop + elemHeight);
		*/
		xMax = Math.max(xMax, elem.leftSet + elemWidth);
		yMax = Math.max(yMax, elem.topSet + elemHeight);

		// Check how many portions the element covers completely (and absorbs, then)
		var lastCoveredPortion = highestIndex;

		var logicalElemWidth = elemWidth;

		if (elem.getAttribute("force-line-break") == 'true')
		{
			logicalElemWidth = 100000;
		}

		var coveredWidth = layoutPortions[lastCoveredPortion].width();

		while (lastCoveredPortion < nbPortions()-1)			
		{
			if (coveredWidth <= logicalElemWidth+gutterWidth)
			{
				lastCoveredPortion++;
				coveredWidth += layoutPortions[lastCoveredPortion].width();				
			}
			else
			{
				break;
			}			
		}

		lastCoveredPortion = Math.min(lastCoveredPortion,nbPortions()-1);
db('last covered portion: ' + lastCoveredPortion);
db('last covered portion x end: ' + layoutPortions[lastCoveredPortion].xEnd);
		// Is the last covered portion entirely covered?
		if (layoutPortions[lastCoveredPortion].xEnd > (layoutPortions[highestIndex].xStart + logicalElemWidth))
		{
			lastCoveredPortion--;
		}


		var nbCoveredPortions = (lastCoveredPortion-highestIndex+1);

db('covered width: ' + coveredWidth);
db('last covered portion: ' + lastCoveredPortion);
db('nb covered portions: ' + nbCoveredPortions);
		
		// Create the new portion
		newPortion = new LayoutPortion(elem.topSet + elemHeight + gutterWidth, layoutPortions[highestIndex].xStart, layoutPortions[highestIndex].xStart + elemWidth + gutterWidth);

		if (elem.getAttribute("force-line-break") == 'true')
		{
			newPortion.xEnd = 100000;
		}

		// Remove completely covered portions, but not if only one remains
		if (elem.getAttribute("force-line-break") == 'true')
		{
			layoutPortions.splice(highestIndex,nbCoveredPortions);
		}
		else
		{
			if (nbPortions() > 1)
			{
				layoutPortions.splice(highestIndex,nbCoveredPortions);
			}
		}

db('removed covered portions, remaining: ' + nbPortions());

		// Insert the new portion
		layoutPortions.splice(highestIndex,0, newPortion);

db('force-line vbreak: ' + elem.getAttribute("force-line-break"));
		if (elem.getAttribute("force-line-break") == 'true')
		{
			layoutPortions.splice(highestIndex+1,1);
//			layoutPortions.splice(Math.min(highestIndex+1,nbPortions()-1),1);
		}
		else
		{
			// Shorten the overlaped last portion
			if ((highestIndex+1) < nbPortions())
			{
				layoutPortions[highestIndex+1].xStart = layoutPortions[highestIndex].xEnd;
db('shorten!');
//				layoutPortions[Math.min(highestIndex+1,nbPortions()-1)].xStart = layoutPortions[highestIndex].xEnd;
			}
		}
	

		// ---


		//db('nb portions: ' + layoutPortions.length);
		var str = 'p:';
		for (iPortion = 0; iPortion < layoutPortions.length; iPortion++)
		{
			str += '(';
			str += layoutPortions[iPortion].yPos + ')';
			str += layoutPortions[iPortion].xStart;
			str += '..';
			str += layoutPortions[iPortion].xEnd;
			str += ' | ';
		}


db(str);
db(' ');

		previousElem = elem;

	} // for i in elems

	// Center the whole stuff

	leftMargin = Math.max( 0.5*(viewportWidth-xMax), minMarginLeft );

//	topMargin = Math.max( 0.5*(viewportHeight-yMax), minMarginTop );
	topMargin = Math.max( 0.5*(viewportHeight-yMax-footerHeight), minMarginTop );

	var bottomMargin = topMargin;

	for (i in elems)
	{
		var elem = elems[i];
/*
		elem.style.left = elem.offsetLeft + leftMargin;
		elem.style.top = elem.offsetTop + topMargin;
*/
		elem.style.left = elem.leftSet + leftMargin;
		elem.style.top = elem.topSet + topMargin;

		//setOpacity(elem,1.0);
		elem.vbrlOpacity = 0.0 - (0.2*i);
	}

	// Add a bottom margin if necessary
//	if (yMax > viewportHeight-(2*topMargin))
	{
		var mainContainer = document.getElementById('main-container');
		var allContainer = document.getElementById('all-container');

		if (allContainer != undefined)
		{
			allContainer.style.width = (xMax+(2*leftMargin)) + 'px';
			allContainer.style.height = (yMax+(2*topMargin) + footerHeight) + 'px';
		}

		if (mainContainer != undefined)
		{
//			mainContainer.style.height = (yMax+(2*topMargin)-gutterWidth) + 'px';
			mainContainer.style.width = (xMax+(2*leftMargin)) + 'px';
//			document.body.style.width = (xMax+(2*leftMargin)) + 'px';
//			document.body.innerWidth = (xMax+(2*leftMargin));
//			document.body.style.width = (xMax+(2*leftMargin)) + 'px';
//			mainContainer.style.width = '5000px';
			mainContainer.style.height = (yMax+(2*topMargin) + footerHeight) + 'px';

//			mainContainer.style.offsetHeight = (yMax+(2*topMargin)-gutterWidth);
		}		
	}

	

	if (fade)
	{
		revealMoreLayout();
	}
	else
	{
		revealAllLayout(elems);
	}

	centerPopupImage();

}

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

