Array.implement({
	shuffle: function() {
		//destination array
		for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
		return this;
	}
});

window.addEvent('domready', function() {

	var showDuration = 3500;
	var tweenTime = 1000;
	var tileDimension = 154;
	var interval;
	var intervalR;
	var currentR = -1;
	var lastPosition;
	var json;
	
	var tileDivs = $$('.greenTile');
	var imagePaths = [];
	var imagesLoaded;

	var activeImages = [];
	var inactiveImages = [];
	var rightImages = [];
	var rightImagePaths = [];
	
	var isIE7 = false;
	
	browserDetect();
	
	/**
	 *	GET DATA
	 */
	
	function browserDetect()
	{	
		if (navigator.appVersion.search("MSIE 7") != -1) isIE7 = true;
		loadJSON();
	}
	
	function loadJSON()
	{
		var jsonUrl = 'index/homepage-images';
		var jsonRequest = new Request.JSON({url:jsonUrl, 
			onSuccess: function(responseJSON, responseText){
				json = responseJSON;
				setupTileArrayFromJSON();
				setupRightImageFromJSON();
			}
		}).get();
	}
	
	/**
	 *	SETUP ARRAYS
	 */ 
	
	function setupTileArrayFromJSON()
	{		
		for(i=0; i<json.tiles.length; i++)
		{
			json.tiles[i].gridIndex = -1;
			if(json.tiles[i].static) {				
				activeImages.push(json.tiles[i]);
			}
			else {
				inactiveImages.push(json.tiles[i]);
			}
			imagePaths.push(json.tiles[i].path);
		}			
		
		preloadImages();		
	}	
	
	function setupRightImageFromJSON()
	{
		for(i=0; i<json.images.length; i++)
		{
			var rightImagePath = json.images[i].path;
				rightImagePaths.push(rightImagePath);
		}		

		var randomNum = Math.floor(Math.random()*json.images.length);
		var path = 	rightImagePaths[randomNum];
		
		preloadRightImages();
		//$('rImg').innerHTML = '<img src="'+path+'" width="363" height="473"/>';
	}
		
	/**
	 * LOAD IMAGES
	 */
	
	function preloadRightImages()
	{
		imagesLoaded = new Asset.images(rightImagePaths, {
		    onComplete: function() {
				initRightImages();
			}
		});
	}
	
	function preloadImages()
	{		
		/*var progressTemplate = 'Loading image {x} of ' + json.tiles.length;
		var updateProgress = function(num) {
		    progress.set('text', progressTemplate.replace('{x}',num));
		};
		var progress = $('progress');*/
		//updateProgress('text','0');
		
		imagesLoaded = new Asset.images(imagePaths, {
		    onProgress: function(c,index) {
		     	//updateProgress('text',index + 1);		    	
		    },
		    onComplete: function() {
				//progress.set('text', imagePaths.length + ' images loaded.  MooTools FTW.');
				initImages();
			}
		});
	}
	
	/**
	 *	TILE FUNCTIONS
	 */
	
	function initRightImages()
	{
		rightImagePaths.shuffle();
		
		var rImg = $('rImg');
		
		var rImgBack = new Element('div', {
			styles: {
				top	:0,
            	left:0,
				width: 363,
				height:474,
            	position:'absolute',
				background: "#e1f0de",
				padding:2,	
            	'z-index': 12
			}
		});	
		rImgBack.inject(rImg);
		
		for (var i=0; i < rightImagePaths.length; i++) {
			var imageR = new Element('img',{
	        	src: rightImagePaths[i],
	        	width: 363,
	        	height: 473
	        });
			var rImgContainer = new Element('div', {
				styles: {
					top	:0,
	            	left:0,
	            	position:'absolute',
					background: "#e1f0de",
					padding:2,	
	            	'z-index': 13
				}
			});
			imageR.inject(rImgContainer);
			rImgContainer.inject(rImg);
			rightImages.push(rImgContainer);
		};
		intervalR = showNextRightImage.periodical(10000);
	}
	
	function showNextRightImage()
	{
		currentR++;
		currentR >= rightImagePaths.length ? currentR = 0 : currentR;
		
		for (var i=0; i < rightImages.length; i++) {
			if (i == currentR){
				rightImages[i].set('morph', {duration: 'long'});
				rightImages[i].morph({
			     	'opacity': ['1']
			    });
			} else {
				rightImages[i].set('morph', {duration: 'long'});
				rightImages[i].morph({
			     	'opacity': ['0']
			    });
			}
		};
	}
	
	function initImages()
	{			
		// turn on tiles till we have 8 (or total tiles returned) total, including previous static images
		var numImgs = json.tiles.length < 8 ? json.tiles.length : 8;
		
		while(activeImages.length < numImgs){
			var n = Math.floor(Math.random()*inactiveImages.length);
			if (!activeImages.contains(inactiveImages[n])) {
				activeImages.push(inactiveImages[n]);
				inactiveImages.splice(n,1);
			}
		};
		
		// mix it up
		activeImages.shuffle();
		inactiveImages.shuffle();
		
		// remove 4 random positions to start
		var positions = [0,1,2,3,4,5,6,7,8,9,10,11];
		//positions.shuffle();
		positions.splice(1, 1);
		positions.splice(5, 1);
		positions.splice(6, 1);
		positions.splice(11, 1);
		/*positions.splice(Math.random()*positions.length-1,1);
		positions.splice(Math.random()*positions.length-1,1);
		positions.splice(Math.random()*positions.length-1,1);
		positions.splice(Math.random()*positions.length-1,1);*/	
		
		// create active images in positions left over
		for (var i=0; i < activeImages.length; i++) {
			createTile(activeImages[i], positions[i], "true", "false");				
		}
		
		beginSlideshow();
	}
	
	function showNextTile() {
		var positions = [0,1,2,3,4,5,6,7,8,9,10,11];
			positions.shuffle();
		var nextIndex = -1;
		var p = 0;
		var oldImage;
		var isSameTile = "false";
		
		// search for next index
		while (nextIndex == -1)	{
			// if grid is empty, all set
			/*if(tileDivs[positions[p]].getChildren().length == 0) {
				nextIndex = positions[p];
			}
			// check if grid is static
			else*/ {
				for (i=0; i < activeImages.length; i++) {
					if (activeImages[i].gridIndex == positions[p] && !activeImages[i].static) {
						nextIndex = positions[p];
						
						if (lastPosition == nextIndex){
							showNextTile();
							return;
						}
						lastPosition = nextIndex;
						
						// this is the image we'll swap out
						oldImage = activeImages[i];
						activeImages.splice(i,1);	
						isSameTile = "true";					
						break;
					}
				}
				// go to next position in shuffled array
				p++
			}
		}
		
		// find an image to remove
		if (!oldImage) { 
			for (var i=0; i < activeImages.length; i++) {
				if (!activeImages[i].static) {
					oldImage = activeImages[i];
					activeImages.splice(i,1);				
					break;
				}
			}
		}
		
		// remove old tile
		inactiveImages.push(oldImage);
		removeTile(oldImage);		
		
		// take oldest inactive and create nextIndex slot
		var newImage = inactiveImages[0];
		
		createTile.delay(1000, this, [newImage, nextIndex, "false", isSameTile]);
		
		// transfer new image to active and remove from inactive		
		activeImages.push(newImage);
		inactiveImages.splice(0,1);
	}	
	
	function removeTile(tile){
		tile.gridIndex = -1;
		// look up div by id
		var targetDiv = $('grid'+tile.id);
				
		// setup tween and remove mouse events
		var fx = new Fx.Morph(targetDiv, {
		    duration: tweenTime
		});
		removeMouseEvents(targetDiv);
		
		// fade out and remove
		
		fx.set({ 'opacity':"1"})
		fx.start({
		    'opacity': '0'
	    }).chain(function(){
	    	targetDiv.parentNode.removeChild(targetDiv);
		});
	}
	
	// tile: 	the target tile
	// gridIndex: 	the target grid index
	// init: 		set to true on 1st load (no opacity tween)
	// isSameTile: 	set to true if creating new item in populated tile
	function createTile(tile, gridIndex, init, isSameTile){ 
		tile.gridIndex = gridIndex;
		var initOpacity = 1;
		
		if (init != "true"){
			init = false;
			initOpacity = 0;
		}
		var containerDiv = new Element('div');		
			containerDiv.id = 'grid'+tile.id;
			
		var tileDiv = tileDivs[gridIndex];
		
		var imageEl = new Element('img',{
        	src:tile.path,
        	width: tileDimension,
        	height: tileDimension,
        	styles: {
            	opacity:[initOpacity],
            	top:tileDiv.top,
            	left:tileDiv.left,
            	position:'absolute',
            	'z-index': 10
        	}
        });
		imageEl.inject(containerDiv);
		
		// setup overlays
		var descStart = '<h3>';
		var descEnd = '</h3>';
		
		if (tile.quote == "1"){
			descStart = '<h4>"';
			descEnd = '"</h4>';
		}
		
		tile.description == null ? tile.description = "" : tile.description;
			
		var newdiv = new Element('div');
			newdiv.addClass('overlay');
			newdiv.style.zIndex = 11;
			newdiv.style.position = "relative";	
			newdiv.index = tile;
			newdiv.innerHTML = 
				'<h1>' + tile.name + '</h1>' + 
				'<h2>' + tile.title + '</h2>' + 
				descStart + tile.description + descEnd;
				
		if (tile.link) {
			newdiv.style.cursor = "pointer";
		}
			
		if (tileDiv.getPosition($("container")).x < 470) newdiv.style.left = "158px";
		
		if (isIE7){
			if (tileDiv.getPosition($("container")).x < 470) {
				newdiv.style.left = "0px";
			} else {
				newdiv.style.left = "-158px";
			}
		}
		
		tileDiv.newName = tile.name;
		tileDiv.index = gridIndex;
		tileDiv.image = imageEl;
		tileDiv.overlay = newdiv;
		tileDiv.container = containerDiv;
		
		newdiv.addEvent("click", function(e){
			if (!e) var e = window.event;
				if (e.target) targ = e.target;
				else if (e.srcElement) targ = e.srcElement;
				if (targ.nodeType == 3) // defeat Safari bug
					targ = targ.parentNode;
			while (targ.nodeName != "DIV"){
				targ = targ.parentNode;
			}
			
			var tgtUrl = targ.index.link;
			if (tgtUrl){
				window.open(tgtUrl, "_blank");
			}
		});
		
		newdiv.inject(containerDiv);
		containerDiv.inject(tileDiv);
		
		addMouseEvents(tileDiv);
		
		var tweenMultiplier = 1;
		isSameTile == "true" ? tweenMultiplier = 2 : tweenMultiplier;
		
		var fx = new Fx.Morph(imageEl, {
		    duration: tweenTime * tweenMultiplier
		});
		
		fx.start({
		    'opacity': '1'
	    });
	}
	
	function beginSlideshow()
	{	
    	$clear(interval);
		interval = showNextTile.periodical(showDuration);
	}
	function endSlideshow()
	{
		$clear(interval);
	}
	
	/**
	 *	MOUSE EVENTS
	 */
	
	function addMouseEvents(tile)
	{
		tile.addEvent("mouseenter", function(event){
			tile.overlay.set('morph', {duration: 'short'});
			tile.overlay.morph({
		     	'opacity': ['0','.9']
		    });	
			endSlideshow();
		});
		tile.addEvent("mouseleave", function(){
			tile.overlay.set('morph', {duration: 'short'});
			tile.overlay.morph({
		    	'opacity': '0'
		    });
			beginSlideshow();
		});
	}

	function removeMouseEvents(tile)
	{
		tile.removeEvents('mouseenter');
		tile.removeEvents('mouseleave');
	}
});
