
function initialize()
{
	var indexElement 		= $('index');
	var projects 			= $$('div.project');
	
	var borderSize			= 1;
	var isClosing			= false;
	var queuedProject		= null;
	var dontTrackClass		= 'auxilary';
	var disabledClass		= 'disabled';
	
	var projectMaxWidth 	= 750 - borderSize; // subtract 1 because of border
	var projectMaxHeight 	= 500 - borderSize; // subtract 1 because of border
	
	var projectMinWidth		= 250;
	var projectMinHeight	= 250;
	
	var indexCoords 		= indexElement.getCoordinates();
	
	var gridWidth 			= indexCoords.width - borderSize;
	var gridWidthHalf 		= gridWidth * 0.5;
	
	var projectsPerRow		= gridWidth / projectMinWidth;
	var projectsPerColumn	= projects.length / projectsPerRow;
	
	var newIndexHeight		= (projectsPerColumn + 1) * projectMinHeight; // + 1 to allow bottom projects to extend
	
	// Set index element height accordingly
	indexElement.setStyle('height', String(newIndexHeight + 'px')); 
	
	// update indexCoords
	indexCoords.height		= newIndexHeight;
	
	var gridHeight 			= indexCoords.height;
	var gridHeightHalf 		= gridHeight * 0.5;
	
	var projectMorphOpen	= {
		'width'		: [projectMinWidth, projectMaxWidth],
		'height'	: [projectMinHeight, projectMaxHeight]
	};
	
	var projectMorphClose	= {
		'width'		: [projectMaxWidth, projectMinWidth - borderSize],
		'height'	: [projectMaxHeight, projectMinHeight - borderSize]
	};
	
	var detailMorphOpen		= {
		'height'	: [0, projectMinHeight - borderSize]
	};
	
	var detailMorphClose	= {
		'height'	: [projectMinHeight - borderSize, 0]
	};
	
	var imageMorphOpen		= {
		'opacity'	: [0.2, 1]
	};
	
	var imageMorphClose	= {
		'opacity'	: [1, 0.2]
	};
	
	var currentYCount = 0;
	
	projects.each(function(project, i)
	{
		// Assign initial project styles
		project.setStyle('width', String((projectMinWidth - borderSize) + 'px'));
		project.setStyle('height', String((projectMinHeight - borderSize) + 'px'));
		project.setStyle('overflow', 'hidden');
		
		var detailElement	= project.getElement('.project_detail');
		var imageElement	= project.getElement('img');
		var projectModX		= i % projectsPerRow;
		var projectModY		= currentYCount % projectsPerColumn;
		var newProjectX		= projectModX * projectMinWidth;
		var newProjectY		= projectModY * projectMinHeight;
		var adjustedX 		= projectMinWidth * (projectModX - (projectsPerRow * 0.5));		
		
		// Verify range
		if (currentYCount >= projectsPerRow)
			currentYCount = 0;
		else if (projectModX == projectsPerRow - 1)
			currentYCount++;
		
		var projectFx 		= new Fx.Morph(project, { 'link' : 'cancel' });
		var detailFx		= new Fx.Morph(detailElement, { 'link' : 'cancel' });
		var imageFx			= new Fx.Morph(imageElement, { 'link' : 'cancel' });
		
		// Temporarily hide project details
		detailElement.setStyle('height', '0px');
		
		// Add close button
		var closeButton = new Element('span',
		{
			'class'		: 'close_button'
		});
		
		closeButton.inject(detailElement, 'top');
		
		closeButton.addEvent('click', function()
		{
			project.fireEvent('mouseleave');
			project.addClass(disabledClass);
		});
		
		projectFx.addEvent('start', function()
		{
			// Check for closed/minimized state
			if (project.getSize().x < projectMaxWidth)
				project.setStyle('z-index', '300');
			else
				project.setStyle('z-index', '200');
		});
		
		projectFx.addEvent('complete', function()
		{
			// Check for closed/minimized state
			if (project.getSize().x < projectMaxWidth)
			{
				project.setStyle('z-index', '100');
				detailFx.start(detailMorphClose);
				imageFx.start(imageMorphClose);
				
				if (project.hasClass(disabledClass))
					project.removeClass(disabledClass);
				
				// Set closing flag to false
				isClosing = false;
				
				if (queuedProject)
				{
					// Verify that mouse is still over queued project
					queuedProject.addEvent('mousemove', function()
					{
						queuedProject.removeEvents('mousemove');
						queuedProject.fireEvent('mouseenter');
						queuedProject = null;
					});
				}
			}
			else
			{
				detailFx.start(detailMorphOpen);
				imageFx.start(imageMorphOpen);
			}
		});
		
		project.setStyles({
			'position'		: 'absolute',
			'left'			: String(newProjectX + 'px'),
			'top'			: String(newProjectY + 'px')
		});
		
		// Add mouseenter handler
		project.addEvent('mouseenter', function(e)
		{
			// Verify that element is not disabled
			if (!project.hasClass(disabledClass) && !isClosing)
			{
				var thisProjectMorphOpen = projectMorphOpen;
				
				if (newProjectX >= gridWidthHalf)
					thisProjectMorphOpen.left = [newProjectX, adjustedX];
				else
					thisProjectMorphOpen.left = newProjectX;
	
				projectFx.start(thisProjectMorphOpen);
				
				// Apply only to non auxilary
				if (!project.hasClass(dontTrackClass))
				{			
					// Track mouse and add variable opacity
					project.addEvent('mousemove', function(e)
					{
						var opacityBuffer		= 400; // Allow complete opacity to be reached more quickly by adding a buffer
						var transparencyBuffer	= 100; // Allow more transparency range by adding a buffer
						var mouseY 				= e.page.y - indexCoords.top - newProjectY;
						var ratio 				= (mouseY - transparencyBuffer) / (projectMaxHeight - opacityBuffer);
						var newOpacity 			= ratio;
						
						if (newOpacity > 1)
							newOpacity = 1;
						else if (newOpacity < 0)
							newOpacity = 0;
						
						detailElement.setStyle('opacity', newOpacity);
					});
				}
				
				// Add mouseleave handler
				project.addEvent('mouseleave', function(e)
				{
					// Verify that element is not disabled
					if (!project.hasClass(disabledClass))
					{
						// Set closing flag to true
						isClosing = true;
						
						var thisProjectMorphClose = projectMorphClose;
						
						if (newProjectX >= gridWidthHalf)
							thisProjectMorphClose.left = [adjustedX, newProjectX];
						else
							thisProjectMorphClose.left = newProjectX;
			
						projectFx.start(thisProjectMorphClose);
						
						// Apply only to non auxilary // Clear mouse tracking
						if (!project.hasClass(dontTrackClass))
							project.removeEvents('mousemove');
							
						project.removeEvents('mouseleave');
					}
					
				}.bind(this));
				
			}
			else if (!project.hasClass(disabledClass) && isClosing)
			{
				// queue
				queuedProject = project;
			}
			
		}.bind(this));
		
	}.bind(this));
}

window.addEvent('domready', initialize);