var isIE = false;
var isFirefox = false;
var isSafari = false;

var currentPhotoId = 0;

var borderSizeInPixels = 0;
var renderInfosToDownloadInBackground = new Array();

function ie() { isIE = true; }

function firefox() { isFirefox = true; }

function safari() { isSafari = true; }

function setBorderSizeInPixels(newBorderSizeInPixels) { borderSizeInPixels = newBorderSizeInPixels; }

function isLeftArrow(keyCode) { return (keyCode == 37) || (keyCode == 63234); }

function isSpacebar(keyCode, chr) { return (keyCode == 0) && (chr == ' '); }

function isRightArrow(keyCode) { return (keyCode == 39) || (keyCode == 63235); }

/*
function speedTest() {
	var iterations = 1000000;
	var startTime = new Date().getTime();
	for(var i = 0; i < iterations; i++);
	var endTime = new Date().getTime();
	
	var mhz = iterations/1000000/(endTime - startTime);

	startTime = new Date().getTime();
	setTimeout(function() {
		endTime = new Date().getTime();
	}, 1);
	
	alert("mhz = " + mhz + ", time to callback 1ms = " + (endTime - startTime));
}
*/

function setCookie(cookieName,cookieValue,nDays) {
	var today = new Date();
	var expire = new Date();
 	if (nDays==null || nDays==0) nDays=1;
	expire.setTime(today.getTime() + 3600000*24*nDays);
	document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
}

function getCookie(cookieName) {
	var theCookie=""+document.cookie;
 	var ind=theCookie.indexOf(cookieName);
 	if (ind==-1 || cookieName=="") return ""; 
 	var ind1=theCookie.indexOf(';',ind);
 	if (ind1==-1) ind1=theCookie.length; 
 	return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
}

function equals(string1, string2) {
	return (string1.toString() == string2.toString());
}

function reload(oldpageh, oldpagew) {
	setCookie("pageh", pageHeight(), 30);
	setCookie("pagew", pageWidth(), 30);
	//alert('reload called, oldpagew = ' + oldpagew + ', oldpageh = ' + oldpageh + ", pageWidth() = " + pageWidth() + ", pageHeight() = " + pageHeight());
	/*if((Math.abs(oldpagew - pageWidth()) > 30) || (Math.abs(oldpageh - pageHeight()) > 30)) */ load(window.location);
}

function gotoPage(start) {
	setCookie("start", start);
	load(window.location);
}

function newSearch(tag) {
	setCookie("start", 0);
//	alert(buildURL(tag, null, null));
	load(buildURL(tag, null, null));
}

function load(searchTerm) {
//	alert("loading " + searchTerm);
	window.location = searchTerm;
}

function buildURL(tagParam, photoParam, flickrPhotoParam)
{
	var params = new Array();
	if((photoParam != undefined) && (photoParam != null)) params.push("photo=" + photoParam);
	if((flickrPhotoParam != undefined) && (flickrPhotoParam != null)) { 
	  params.push("flickrphoto=" + flickrPhotoParam);
	}

	var retVal = ((tagParam != undefined) && (tagParam != null)) ? tagParam : "";
	
	retVal += (params.length > 0) ? "?" + params.join("&") : "";
	
	return retVal;
}


// Browser Window Size and Position
// copyright Stephen Chapman, 3rd Jan 2005, 8th Dec 2005
// you may copy these functions but please keep the copyright notice as well
function pageWidth() {
	var retVal = window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?       document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;   
	//alert("pageWidth() returning " + retVal);
	return retVal;
} 

function pageHeight() {
	return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;} 
	
function posLeft() {
	return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;} 
	
function posTop() {
	return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;} 
	
function posRight() {
	return posLeft()+pageWidth();} 

function posBottom() {return posTop()+pageHeight();}

var thumbBoxes = new Array();

var first = true;
function adjustThumbnailDiv(photoId, currentTop, currentLeft, thumbBoxIndex, pixelsPerThumbnail) {

	var thumb = document.getElementById(photoId.toString());
	var height = thumb.height;
	var width = thumb.width;
	var div = document.getElementById("thumbnail_" + photoId.toString());
	
	div.style.width = width;
	div.style.height = height;	
	div.style.top = currentTop + (pixelsPerThumbnail - height)/2 + "px";
	div.style.left = currentLeft + (pixelsPerThumbnail - width)/2 + "px";

//	if(thumbBoxIndex == 58) { alert("adjustThumbnailDiv() called currentTop = " + currentTop + ", currentLeft = " + currentLeft + ", div.style.top = " + div.style.top + ", div.style.left = " + div.style.left); first = false; }
	
	thumbBoxes[thumbBoxIndex] = new Array(
				currentLeft + (pixelsPerThumbnail - width)/2, 
				currentTop + (pixelsPerThumbnail - height)/2, 
				width,
				height,
				photoId);
}

function checkResolution() {
//	alert("checkResolution() called");
	var queryBox = document.getElementById("q");

	pageh = getCookie("pageh");
	pagew = getCookie("pagew");

//alert("again, pageh = " + pageh + ", pagew = " + pagew);

	if(pageh !== "") pageh = unescape(getCookie("pageh"));
	if(pagew !== "") pagew = unescape(getCookie("pagew"));
 
//	alert("window.location = " + window.location + ", pageh = " + pageh + ", pagew = " + pagew); 
 
	if((pageh == "") || (pagew == "") || (pageh == undefined) || (pagew == undefined) || (pageh < 10) || (pagew < 10) || (pagew != pageWidth()) || (pageh != pageHeight())) { 
		//alert("about to call reload(), pageh = " + pageh + ", pagew = " + pagew + ", pageWidth() = " + pageWidth() + ", pageHeight() = " + pageHeight());
		reload(0,0);
	}

	var iterations = 1000000;	
	var startTime = new Date().getTime();

 	//alert("pageWidth() = " + pageWidth() + ", pageHeight() = " + pageHeight() + ", screen.width = " + screen.width + ", screen.height = " + screen.height);
}

var photoInterval = null; 
var lastOverPhotoId = null;

function mousemove(e, actualBorderFloat, baselineImageSize, photosPerRow) {
//	var eventObject = null;
	if(isIE) eventObject = window.event;
	else eventObject = e;
//	alert("event = " + event + ", isIE = " + isIE + ", actualBorderFloat = " + actualBorderFloat + ", baselineImageSize = " + baselineImageSize + ", photosPerRow = " + photosPerRow);
	var row = Math.floor((eventObject.clientY - actualBorderFloat ) / (baselineImageSize + actualBorderFloat));
	var column = Math.floor((eventObject.clientX - actualBorderFloat) / (baselineImageSize + actualBorderFloat));
//	alert("row = " + row + ", column = " + column);
//	if((++tmpCounter %10) == 0) alert("row = " + row + ", column = " + column);

	var thumbBoxIndex = row * photosPerRow + column;
	var coords = thumbBoxes[thumbBoxIndex];
	var overThumb = (coords != null) ? ((eventObject.clientX >= coords[0] - 2) && (eventObject.clientY >= coords[1] - 3) && (eventObject.clientX < (coords[0] + coords[2])) && (eventObject.clientY < (coords[1] + coords[3]))) : false;

//	alert("thumbBoxIndex = " + thumbBoxIndex + ", eventObject.clientX = " + eventObject.clientX + ", eventObject.clientY = " + eventObject.clientY + ", coords = " + coords + ", overThumb = " + overThumb);

	if((coords != null) && (lastOverPhotoId == coords[4]) && overThumb); // same2same
	else if(lastOverPhotoId != null) { // in2out & in2in
		mouseoffThumbnail(lastOverPhotoId); 
		lastOverPhotoId = null; 
		if(overThumb) { // in2in
			lastOverPhotoId = coords[4];
			mouseoverThumbnail(lastOverPhotoId);
		}
	} 
	else if (overThumb) { // out2in
		lastOverPhotoId = coords[4];
		mouseoverThumbnail(lastOverPhotoId);
	}

//	if((++tmpCounter %5) == 0) alert("row = " + row + ", column = " + column + ", photoId = " + photoId + ", overThumb = " + overThumb);	
}


function mouseX( oElement ) {
  if( typeof( oElement.offsetParent ) != 'undefined' ) {
    for( var posX = 0; oElement; oElement = oElement.offsetParent ) {
      posX += oElement.offsetLeft;
    }
    return posX;
  } else {
    return oElement.x;
  }
}

function mouseY( oElement ) {
  if( typeof( oElement.offsetParent ) != 'undefined' ) {
    for( var posY = 0; oElement; oElement = oElement.offsetParent ) {
      posY += oElement.offsetTop;
    }
    return posY ;
  } else {
    return oElement.y;
  }
}

function hidePhoto() {
	if(currentPhotoId != 0) {
		$("#photo_div_" + currentPhotoId).css("display","none");
		$("#photo_deets_" + currentPhotoId).css("display","none");
	}
}


function thumbClick(newImageNumber) {
	hidePhoto();
	currentPhotoId = newImageNumber;

        photoDiv = $("#photo_div_" + currentPhotoId);
        photoDiv.css("z-index","100");
        photoDiv.css("display","block");


//        alert("imageDiv.css(display) = " + imageDiv.css("display"));
        
	deetsDiv = $("#photo_deets_" + currentPhotoId);
//	alert("textDiv = " + textDiv);
	if(! deetsDiv.attr("loaded")) {
	        $.ajax({
		  type: "GET",
		  url: "?photoid=" + newImageNumber,
		  data: "{}",
		  contentType: "application/json; charset=utf-8",
		  dataType: "json",
		  success: function(msg) {
	          	// Hide the fake progress indicator graphic.
		        // $('#RSSContent').removeClass('loading');

		        // Insert the returned HTML into the <div>.
			var newHTML = "<table style=\"color:#000000;\"><tr><td>photo by: " + msg.author + "</td></tr>";
			var counter = 0;
			for(var i in msg.tags) {
			  counter++;
			  newHTML += '<tr><td><a href="' + msg.tags[i].internal + '">' + msg.tags[i].external + '</a></td></tr>';
			}
			newHTML += '</table>';
			//alert("newHTML = " + newHTML);
		        deetsDiv.html(newHTML);
		        deetsDiv.css("display","block");
			deetsDiv.attr("loaded","true");
		  }
		});

	        //var textSpan = $("#photo_tag_span_" + newImageNumber);
		
		//textSpan.text("hi world");
		//alert("textSpan.size() = " + textSpan.size() + ", textSpan.text() = " + textSpan.text());
		//actualImage.after('<span style="border: none; color:#888888; font-family: Verdana; font-size: 14; text-align:right; vertical-align:top;">hi world</span>');
	}
	else deetsDiv.css("display","block");
}

function adjustImageContainer(imageNumber) {
        //alert("imageNumber = " + imageNumber);
        var photoDiv = document.getElementById("photo_div_" + imageNumber);
        var photoDeetsDiv = document.getElementById("photo_deets_" + imageNumber);
        var actualPhoto = document.getElementById("photo_img_" + imageNumber);
        var photoWidth = actualPhoto.width;
        var photoHeight = actualPhoto.height;
        var thumbPhoto = document.getElementById("photo_thumb_" + imageNumber);
        var currentX = mouseX(thumbPhoto);
        var currentY = mouseY(thumbPhoto);
//alert("currentX = " + currentX + ", currentY = " + currentY + ", top = " + bigImage.style.top + ", left = " + bigImage.style.left + ", pageWidth() = " + pageWidth());


        var top;
        if(currentY < photoHeight/2) top = "0px";
	else if((currentY + photoHeight/2 ) >= pageHeight()) top = (pageHeight() - photoHeight) + "px";
        else top = (currentY - photoHeight/2) + "px";

        photoDiv.style.left = "0px"; 
        photoDiv.style.width = photoWidth + "px";
        photoDiv.style.height = photoHeight + "px";
	photoDiv.style.top = top;

	photoDeetsDiv.style.left = photoWidth + "px";
	photoDeetsDiv.style.width = "200px";
	photoDeetsDiv.style.height = photoHeight + "px";
	photoDeetsDiv.style.top = top;
	photoDeetsDiv.style.zIndex = 20;

//alert("imageWidth = " + imageWidth + ", imageHeight = " + imageHeight + ", currentX = " + currentX + ", currentY = " + currentY + ", top = " + bigImage.style.top + ", left = " + bigImage.style.left + ", bigImage.style.width = " + bigImage.style.width + ", bigImage.style.height = " + bigImage.style.height + ", pageWidth() = " + pageWidth());

}



var pagew = getCookie("pagew");
var pageh = getCookie("pageh");

//alert("pagew = " + pagew + ", pageh = " + pageh);

var mouseOver = new Array();

//var photoIntervalMillis = 3000;
var photoIntervalMillis = 25;

var tmpCounter = 0; 

function associativeArrayLength(aa) {
	var counter = 0;
	for(var e in aa) {counter++;}
	return counter;
}

var renderInfosPerBatch = 5;
var currentlyDownloadingRenderInfos = false;

function downloadRenderInfos() {
	if(!currentlyDownloadingRenderInfos && renderInfosToDownloadInBackground.length > 0) {
		
		var actionCounter = 0;
		for(var s in sunrises) { actionCounter++; break; }
		if(actionCounter == 0) { for(var s in sunsets) { actionCounter++; break; } }
		
		if(actionCounter == 0) {
			var nextBatch = new Array();
			for(var i = 0; i < renderInfosPerBatch; i++) {
				var nextId = renderInfosToDownloadInBackground.shift();
				if(nextId == null) break;
				else nextBatch.push(nextId);
			}
			currentlyDownloadingRenderInfos = true;
			getRenderInfos(buildURL(null, nextBatch.join(","), null));
		}
	}
}

function getRenderInfos(url) {
	var photo_sizes;
	var pagew = Number(pageWidth());
	var pageh = Number(pageHeight());
	var http_request = new XMLHttpRequest();
	http_request.open("GET", url, true);
	http_request.send(null);
	http_request.onreadystatechange = function () 
	{
  		if ((http_request.readyState == 4) && (http_request.status == 200)) {
       			var sizeData = eval("(" + http_request.responseText + ")");
//			alert("sizeData = " + sizeData);
			for (var photo_sizes in sizeData) {	
				var photoId = Number(sizeData[photo_sizes][0]);
//				alert("photo_sizes = " + photo_sizes);
				var imageWidth = Number(sizeData[photo_sizes][2][2]);
				var imageHeight = Number(sizeData[photo_sizes][2][3]);
				var renderWidth = imageWidth;
				var renderHeight = imageHeight;
						
				if((renderWidth + 2 * borderSizeInPixels) >  pagew) 
				{
					renderWidth = pagew - 2 * borderSizeInPixels;
					renderHeight = renderHeight * (renderWidth/imageWidth);
				}

				if((renderHeight + 2 * borderSizeInPixels) > pageh) 
				{
					oldRenderHeight = renderHeight;
					renderHeight = pageh - 2 * borderSizeInPixels;
					renderWidth = renderWidth * (renderHeight / oldRenderHeight);			
				}
					
//					alert("pagew = " + pagew + ", pageh = " + pageh + ", imageWidth = " + imageWidth + ", imageHeight = " + imageHeight + ", renderWidth = " + renderWidth + ", renderHeight = " + renderHeight + ", biggest img src = " + sizeData[photo_sizes][2][1]);

				var upperLeftX = (pagew - renderWidth) / 2;
				var upperLeftY = (pageh - renderHeight) / 2;

				var renderInfo = new Array();
				renderInfo["width"] = renderWidth; 
				renderInfo["height"] = renderHeight;
				renderInfo["src"] = sizeData[photo_sizes][2][1];
//				renderInfo["href"] = sizeData[photo_sizes][3][1];
				renderInfos[photoId.toString()] = renderInfo;
//				alert("renderInfo[" + photoId + "] = " + renderInfo[photoId.toString]);
//						alert("renderInfos[photoId.toString()][\"width\"] = " + renderInfos[photoId.toString()]["width"]);
//						render(photoId);
			}
			currentlyDownloadingRenderInfos = false;

			var actionCounter = 0;
			for(var s in sunrises) { actionCounter++; break; }
			if(actionCounter == 0) {
				for(var s in sunsets) { actionCounter++; break; }
			}
			if(actionCounter == 0) setTimeout("downloadRenderInfos()", 300);
			
		}
	};
}


function getBiggestImage(photoId) {
//	alert("showMediumWhileMouseOver() mouseOver = " + mouseOver[photoId]);
	if(mouseOver[photoId.toString()]) {
		if(renderInfos[photoId.toString()] != null) render(photoId.toString());
		else {
			var photo_sizes;
			var http_request = new XMLHttpRequest();
			var url = buildURL(null, photoId.toString(),null);
	//		alert("showMediumWhileMouseOver() url = " + url);
			http_request.open("GET", url, true);
			http_request.send(null);
			http_request.onreadystatechange = function () 
			{
  			  	if ((http_request.readyState == 4) && (http_request.status == 200)) {
       			     		photo_sizes = eval("(" + http_request.responseText + ")");
					if(mouseOver[photoId.toString()]) {	

						var pagew = Number(pageWidth());
						var pageh = Number(pageHeight());
						var imageWidth = Number(photo_sizes[0][2][2]);
						var imageHeight = Number(photo_sizes[0][2][3]);
						var renderWidth = imageWidth;
						var renderHeight = imageHeight;
						
						if((renderWidth + 2 * borderSizeInPixels) >  pagew) 
						{
							renderWidth = pagew - 2 * borderSizeInPixels;
							renderHeight = renderHeight * (renderWidth/imageWidth);
						}

						if((renderHeight + 2 * borderSizeInPixels) > pageh) 
						{
							oldRenderHeight = renderHeight;
							renderHeight = pageh - 2 * borderSizeInPixels;
							renderWidth = renderWidth * (renderHeight / oldRenderHeight);			
						}
					
//					alert("pagew = " + pagew + ", pageh = " + pageh + ", imageWidth = " + imageWidth + ", imageHeight = " + imageHeight + ", renderWidth = " + renderWidth + ", renderHeight = " + renderHeight + ", biggest img src = " + photo_sizes[0][2][1]);

						var upperLeftX = (pagew - renderWidth) / 2;
						var upperLeftY = (pageh - renderHeight) / 2;

						var renderInfo = new Array();
						renderInfo["width"] = renderWidth; 
						renderInfo["height"] = renderHeight;
						renderInfo["src"] = photo_sizes[0][2][1];
//						renderInfo["href"] = photo_sizes[0][3][1];
						renderInfos[photoId.toString()] = renderInfo;
//						alert("renderInfos[photoId.toString()][\"width\"] = " + renderInfos[photoId.toString()]["width"]);
						render(photoId);
					}
		        	}
			};
		}
	}
}


function render(photoId) { 
	var renderInfo = renderInfos[photoId.toString()];
	document.getElementById("actual_image_" + photoId.toString()).src = renderInfo["src"];
}
	
function setOpacity(node, fractionalOpacity) {
	node.style.opacity = fractionalOpacity;
	node.style.filter = "alpha(opacity=" + (fractionalOpacity * 100) + ")";
}

var renderInfos = new Array();

function mouseoverThumbnail(photoId) {
//var currentTime = new Date().getTime();
//	alert("mouseoverThumbnail() called for photoId = " + photoId);
//	delete sunsets[photoId.toString()];
	mouseOver[photoId.toString()] = photoId.toString();
	if(sunsets[photoId.toString()] != null) {
		delete sunsets[photoId.toString()];
		sunrises[photoId.toString()] = photoId.toString();
	}
	else {
//	shutdownThumb([photoId.toString()]);
//	var photoDialog = document.getElementById("photo_dialog");

		var thumbDiv = document.getElementById("thumbnail_" + photoId.toString());

		var photoDiv = document.getElementById("actual_photo").cloneNode(true);
		photoDiv.setAttribute("id", "actual_photo_" + photoId.toString());
		photoDiv.style.zIndex = 1.0;
//	alert("photoDiv.style.zIndex = " + photoDiv.style.zIndex);
		document.getElementById("search_results_dialog").appendChild(photoDiv);	

		var href = document.getElementById("flickr_href").cloneNode(false);
		href.setAttribute("id", "flickr_href_" + photoId.toString());
		href.setAttribute("href", buildURL(null,null, photoId.toString()));
		photoDiv.appendChild(href);

		var photo = document.getElementById("actual_image").cloneNode(true);
		photo.setAttribute("id", "actual_image_" + photoId.toString());
		photo.style.display="block";
		href.appendChild(photo);

//	alert("photoDiv.style.zIndex = " + photoDiv.style.zIndex + ", thumbDiv.style.zIndex = " + thumbDiv.style.zIndex + ", photo.style.zIndex = " + photo.style.zIndex);

		var thumbDiv = document.getElementById("thumbnail_" + photoId.toString());
		var thumb = document.getElementById(photoId.toString());

		var thumbWidth = thumb.width;
		var thumbHeight = thumb.height;
		var thumbDivLeft = thumbDiv.style.left;
		var thumbDivTop = thumbDiv.style.top;
		var originalCenterX = Number(thumb.getAttribute("originalCenterX"));
		var originalCenterY = Number(thumb.getAttribute("originalCenterY"));

		photoDiv.style.left = thumbDivLeft;
		photoDiv.style.top = thumbDivTop;
		photo.src = thumb.src;
		photo.width = thumbWidth;
		photo.height = thumbHeight;
		photo.currentCenterX = thumb.getAttribute("originalCenterX");
		photo.currentCenterY = thumb.getAttribute("originalCenterY");

//	alert("document.getElementById(\"thumbnail_\" + photoId.toString()).style.left = " + document.getElementById("thumbnail_" + photoId.toString()).style.left);

		var leftX = originalCenterX - Number(thumbWidth)/2 - 6;
		var rightX = originalCenterX + Number(thumbWidth)/2;
		var upperY = originalCenterY - Number(thumbHeight)/2 - 6;
		var lowerY = originalCenterY + Number(thumbHeight)/2;

//	alert("photoId = " + photoId + ", photo.id = " + photo.id + ", photoDiv.id = " + photoDiv.id);
//	alert("mouseoverThumbnail() thumb = " + thumb + ", photoDiv = " + photoDiv + ", photoDiv.style.left = " + photoDiv.style.left + ", photoDiv.style.top = " + photoDiv.style.top + ", thumb.width = " + thumb.width + ", thumb.height = " + thumb.height + ", leftX = " + leftX + ", rightX = " + rightX + ", upperY = " + upperY + ", lowerY = " + lowerY + ", originalCenterX = " + originalCenterX + ", originalCenterY = " + originalCenterY);

		setOpacity(photoDiv, 0.1);

		photoDiv.style.display = "block";
	
		sunrises[photoId.toString()] = photoId.toString();
		if(photoInterval == null) photoInterval = setInterval("update()", photoIntervalMillis);

		setTimeout("getBiggestImage(" + photoId.toString() + ")", 600);
	}
//	alert("mouseoverThumbnail() finishing");
}

var first = true;

//var photoInterval = null;

var listenerCallCount = 0;
var listenerAggregateRunTime = 0;

//var tmpCounter = 0;

function update() {
//	if(++tmpCounter % 10 == 0) speedTest();
//	var startTime = new Date().getTime();
//	alert("imageListener() called!");

//	var paginationDiv = document.getElementById("pagination_dialog");
//	paginationDiv.zIndex =- 
	var actionCounter = 0;
	var largestZoomedOpacity = 0.0;	
	var sunriseCounter = 0;

//	var curtain = document.getElementById("fading_curtain_dialog");
	var searchResults = document.getElementById("thumbs_and_pagination_dialog");
	var searchResultsOpacity = Number(searchResults.style.opacity);

	for(var i in sunrises) 
	{
		var opacityRecommendation = growImage(i);
		if(opacityRecommendation > largestZoomedOpacity) largestZoomedOpacity = opacityRecommendation;
		actionCounter++;
		sunriseCounter++;
	}

	for(var i in sunsets) {
		var opacityRecommendation = shrinkImage(i);
		if(opacityRecommendation > largestZoomedOpacity) largestZoomedOpacity = opacityRecommendation;
		actionCounter++;
	}
	
	if(((associativeArrayLength(mouseOver) > 0) || ((sunriseCounter > 0) && (largestZoomedOpacity > .9))) && (searchResultsOpacity > .1) && (searchResultsOpacity <= .2)) // decrement results opacity
	{
		searchResultsOpacity -= .02;
		if(searchResultsOpacity < .1) searchResultsOpacity = .1;
		setOpacity(searchResults, searchResultsOpacity);
	}
	else if(actionCounter > 0) {
		if((largestZoomedOpacity > .9) && (searchResultsOpacity > .2)) setOpacity(searchResults, .2); // pop background out
		else if((associativeArrayLength(mouseOver) == 0) && (sunriseCounter == 0) && (largestZoomedOpacity < .4) && (searchResultsOpacity < .55)) { // last sunset
			setOpacity(searchResults, .55);
		}
	}
	else if(associativeArrayLength(mouseOver) == 0) { // no image changes and not currently showing an image, decrement opacity
		searchResultsOpacity += .05;
		if(searchResultsOpacity > .98) {
			searchResultsOpacity = 1.0;
			clearInterval(photoInterval); photoInterval = null; 
			downloadRenderInfos();
		}
		setOpacity(searchResults, searchResultsOpacity);
	}
	else { // no images to update, download renderInfos in the background if necessary
		clearInterval(photoInterval); photoInterval = null;
		downloadRenderInfos();
	}

/*	listenerAggregateRunTime += new Date().getTime() - startTime;
	if(++listenerCallCount % 100 == 0) alert("after " + listenerCallCount + " calls, the average run time = " + (listenerAggregateRunTime / listenerCallCount) + " millis, photoIntervalMillis = " + photoIntervalMillis);
*/
}

function growImage(photoId) {
//	alert("growImage(" + photoId + ") called");
	var renderInfo = renderInfos[photoId.toString()];

//	alert("renderInfo = " + renderInfo);

	var opacityIncrement = 0.01;
	
	if(renderInfo != null) opacityIncrement *= 6.0;
	
	var scaleFactor = 1.0 + 30.0 * opacityIncrement * photoIntervalMillis/100;

	var thumb = document.getElementById(photoId.toString());
	var thumbDiv = document.getElementById("thumbnail_" + photoId.toString());

	var actualImage = document.getElementById("actual_image_" + photoId.toString());
	var photoDiv = document.getElementById("actual_photo_" + photoId.toString());

	var nextOpacity = Number(photoDiv.style.opacity) + opacityIncrement;
	setOpacity(photoDiv, nextOpacity);

	var oldWidth = Number(actualImage.width);
	var oldHeight = Number(actualImage.height);

	var nextWidth = Number(actualImage.width) * scaleFactor;
	var nextHeight = Number(actualImage.height) * scaleFactor;

//	alert("growImage() oldWidth = " + oldWidth + ", oldHeight = " + oldHeight + ", nextLeft = " + nextLeft + ", nextTop = " + nextTop);

	var currentMaxWidth = 500.0;
	var currentMaxHeight = 500.0;

	if(oldWidth > oldHeight) currentMaxHeight = currentMaxHeight *  oldHeight / oldWidth;
	else if(oldWidth < oldHeight) currentMaxWidth = currentMaxWidth *  oldWidth / oldHeight;

	if(renderInfo != null) {
		currentMaxWidth = Number(renderInfo["width"]);
		currentMaxHeight = Number(renderInfo["height"]);
//		alert("growImage() currentMaxWidth = " + currentMaxWidth + ", currentMaxHeight = " + currentMaxHeight);
	}

	if((nextWidth >= currentMaxWidth || nextHeight >= currentMaxHeight)) {			
		if(renderInfo != null) delete sunrises[photoId.toString()];
		nextOpacity = 1.0;
		setOpacity(photoDiv, nextOpacity);

//		alert("growImage() max reached.. photoDiv.style.zIndex = " + photoDiv.style.zIndex + " thumbDiv.style.zIndex = " + document.getElementById("thumbnail_" + photoId.toString()).style.zIndex + ", curtainDiv.style.zIndex = " + document.getElementById("fading_curtain_dialog").style.zIndex + ", photoDiv.style.opacity = " + photoDiv.style.opacity + ", thumbDiv.style.opacity = " + document.getElementById("thumbnail_" + photoId.toString()).style.opacity + ", curtainDiv.style.opacity = " + document.getElementById("fading_curtain_dialog").style.opacity);

		nextHeight = currentMaxHeight;	
		nextWidth = currentMaxWidth;
	}

	var currentCenterX = (actualImage.currentCenterX == null) ? thumb.getAttribute("originalCenterX") : actualImage.currentCenterX;
	var currentCenterY = (actualImage.currentCenterY == null) ? thumb.getAttribute("originalCenterY") : actualImage.currentCenterY;
	
	var xRatio = Number(currentCenterX - borderSizeInPixels - actualImage.width/2) / (Number(pageWidth() - 2 * borderSizeInPixels - actualImage.width/2)); // ("left space")/("right space")
	var yRatio = Number(currentCenterY - borderSizeInPixels - actualImage.height/2) / (Number(pageHeight() - 2 * borderSizeInPixels - actualImage.height/2)); // ("top space")/("bottom space")

	var xMovement = Number(nextWidth - actualImage.width) * xRatio;
	var yMovement = Number(nextHeight - actualImage.height) * yRatio;

	var nextLeft = Number(currentCenterX - actualImage.width/2) - xMovement;
	var nextTop = Number(currentCenterY - actualImage.height/2) - yMovement;

	if(nextLeft < borderSizeInPixels) nextLeft = borderSizeInPixels;
	if(nextTop < borderSizeInPixels) nextTop = borderSizeInPixels;

	if(nextLeft > pageWidth() - nextWidth - borderSizeInPixels) nextLeft = pageWidth() - nextWidth - borderSizeInPixels;
	if(nextTop > pageHeight() - nextHeight - borderSizeInPixels) nextTop = pageHeight() - nextHeight - borderSizeInPixels;

	actualImage.width = nextWidth;
	actualImage.height = nextHeight;	
	photoDiv.style.left = nextLeft + "px";	
	photoDiv.style.top = nextTop + "px";	

	actualImage.currentCenterX = nextLeft + nextWidth/2;
	actualImage.currentCenterY = nextTop + nextHeight/2;

/*	if(first) { first = false; alert("currentCenterX = " + currentCenterX + ", currentCenterY = " + currentCenterY + ", actualImage.width = " + actualImage.width
	 + ", actualImage.height = " + actualImage.height + ", nextLeft = " + nextLeft + ", nextTop = " + nextTop +  ", nextWidth = " + nextWidth + ", nextHeight = " + nextHeight + ", pageWidth() = " + pageWidth() + ", pageHeight() = " + pageHeight() + ", xRatio = " + xRatio + ", yRatio = " + yRatio + ", borderSizeInPixels = " + borderSizeInPixels);}
*/
//	if(nextOpacity < .9) nextOpacity = 0;
//	alert("growImage() returning " + nextOpacity);
	return nextOpacity;
}
	
var sunrises = new Array();
var sunsets = new Array();


/* var loaded = new Array();

function setLoaded(photoId) {
//	alert("setLoaded called");
	if(mouseOver[photoId.toString()]) loaded[photoId.toString()] = true;
}
*/

function mouseoffThumbnail(photoId) {
	delete sunrises[photoId.toString()];
	delete mouseOver[photoId.toString()];
	sunsets[photoId.toString()] = photoId.toString();

	var thumb = document.getElementById(photoId.toString());
	var actualImage = document.getElementById("actual_image_" + photoId.toString());
//	actualImage.setAttribute("src", thumb.getAttribute("originalSrc"));
//	alert("mouseoffThumbnail() setting src = " + actualImage.getAttribute("originalSrc"));
	if(photoInterval == null) photoInterval = setInterval("update()", photoIntervalMillis);
}

var tmpCounter = 0;

function shrinkImage(photoId) {
	var photoDiv = document.getElementById("actual_photo_" + photoId.toString());
	var thumb = document.getElementById(photoId.toString());
	var thumbDiv = document.getElementById("thumbnail_" + photoId.toString());
	var actualImage = document.getElementById("actual_image_" + photoId.toString());

	var thumbCenterX = Number(thumb.getAttribute("originalCenterX"));
	var thumbCenterY = Number(thumb.getAttribute("originalCenterY"));

	var thumbWidth = thumb.width;
	var thumbHeight = thumb.height;
	
	var opacityIncrement = 0.08 * photoIntervalMillis/25;
	
	var scaleFactor = 1.0 + opacityIncrement * photoIntervalMillis/10;

	var nextOpacity = Number(photoDiv.style.opacity) - opacityIncrement;

	setOpacity(photoDiv, nextOpacity);

	var nextWidth = Number(actualImage.width) / scaleFactor;
	var nextHeight = Number(actualImage.height) / scaleFactor;

//	alert("growImage() oldWidth = " + oldWidth + ", oldHeight = " + oldHeight + ", nextLeft = " + nextLeft + ", nextTop = " + nextTop);

	if((nextWidth <= (1.1 * thumbWidth)) || nextHeight <= (1.1 * thumbHeight)) {shutdownThumb(photoId); nextOpacity = 0.0; }
	else {

		var currentCenterX = (actualImage.currentCenterX == null) ? thumbCenterX : actualImage.currentCenterX;
		var currentCenterY = (actualImage.currentCenterY == null) ? thumbCenterY : actualImage.currentCenterY;
	
		var paintableWidth = Number(Number(pageWidth()) - 2 * borderSizeInPixels);
		var paintableHeight = Number(Number(pageHeight()) - 2 * borderSizeInPixels);

/*		var leftXSpace = thumbCenterX - thumbWidth/2 - borderSizeInPixels;
		var rightXSpace = Number(pageWidth()) - borderSizeInPixels - thumbWidth/2.0 - thumbCenterX;
		var topYSpace = thumbCenterY - thumbHeight/2 - borderSizeInPixels;
		var bottomYSpace = Number(pageHeight()) - borderSizeInPixels - thumbHeight/2.0 - thumbCenterY;
*/
		var xRatio = (thumbCenterX - (thumbWidth/2.0) - borderSizeInPixels) / (paintableWidth - thumbWidth);
		var yRatio = (thumbCenterY - (thumbHeight/2.0) - borderSizeInPixels) / (paintableHeight - thumbHeight);

//	alert("thumbCenterX = " + thumbCenterX + ", thumbCenterY = " + thumbCenterY + ", xRatio = " + xRatio + ", yRatio = " + yRatio);

		var nextLeft = thumbCenterX - thumbWidth/2.0 - (xRatio * (nextWidth - thumbWidth));
		var nextTop = thumbCenterY - thumbHeight/2.0 - (yRatio * (nextHeight - thumbHeight));

//		var nextLeft = thumbCenterX - (xRatio * nextWidth) + (1 - xRatio) * thumbWidth/2;
//		var nextTop = thumbCenterY - (yRatio * nextHeight) + (1 - yRatio) * thumbHeight/2;

		actualImage.currentCenterX = nextLeft + nextWidth/2.0;
		actualImage.currentCenterY = nextTop + nextHeight/2.0;

		actualImage.width = nextWidth;
		actualImage.height = nextHeight;	

		photoDiv.style.left = nextLeft + "px";	
		photoDiv.style.top = nextTop + "px";	
	}
//	if(nextOpacity == 0) alert("shrinkImage() returning 0");
//	if(nextOpacity < .9) nextOpacity = 0;
	return nextOpacity;
}

function shutdownThumb(photoId) {
//	alert("shutdownThumb(" + photoId + ") called");

//	delete sunrises[photoId.toString()];
	delete sunsets[photoId.toString()];
	delete mouseOver[photoId.toString()];
//	delete loaded[photoId.toString()];
//	var actualImage = document.getElementById("actual_image_" + photoId.toString());
//	actualImage.currentCenterX = null;
//	actualImage.currentCenterY = null;
	// TODO remove "actualImage"
	var photoDiv = document.getElementById("actual_photo_" + photoId.toString());
	if(photoDiv != null) document.getElementById("search_results_dialog").removeChild(photoDiv);
	DeleteNode(photoDiv);	
	return null;
}

function DeleteNode(node)
{
	if(node) //make sure the node exists
	{
		DeleteChildren(node); //delete node's children
//		if(!isIE) gEVENTS.removeBuiltinListener(node); //remove listeners
		if (typeof node.outerHTML !== 'undefined')
			node.outerHTML = ''; //prevent pseudo-leak in IE
		else
			if(node.parentNode) //if the node has a parent
				node.parentNode.removeChild(node); //remove the node from the DOM tree
		delete node; //clean up just to be sure
	}
}

function DeleteChildren(node)
{
	if(node) //make sure the node exists
	{
		for(var x = node.childNodes.length - 1; x >= 0; x--) //delete all of node's children
		{
			var childNode = node.childNodes[x];
			if(childNode.hasChildNodes()) //if the child node has children then delete tehm first
				DeleteChildren(childNode);
//			if(!isIE) gEVENTS.removeBuiltinListener(childNode); //remove listeners
			if (typeof childNode.outerHTML !== 'undefined')
				childNode.outerHTML = ''; //prevent pseudo-leak in IE
			else
				node.removeChild(childNode); //remove the child from the DOM tree
			delete childNode; //clean up just to be sure
		}
	}
}

function searchDialogShowing() { return ! (search_dialog !== undefined && (search_dialog != null) && (search_dialog.style.display.toString() != "block")); }

function handleKeystroke(evt, start, photosPerPage, photosTotal)
{             
//	alert(document.hasFocus());

	// Grab the cross browser event
	if( !evt ) evt = window.event;
	// Character code of key pressed
	var asc = !evt.keyCode ? (!evt.which ? evt.charCode : evt.which) : evt.keyCode;
	// ASCII character of above code
	var chr = String.fromCharCode(asc).toLowerCase();
	for (var i in this)
	{
		if (asc == i)
  		{
	 		this[i](evt);
 			break;
  		}
	}
//	alert("keyCode = " + evt.keyCode + ", char = " + chr + ", window.event.ctrlKey = " + evt.ctrlKey + ", document.getElementById(\"search_dialog\").style.display = " + document.getElementById("search_dialog").style.display + ", document.getElementById(\"search_dialog\").style.display.toString() != \"block\" = " + (document.getElementById("search_dialog").style.display.toString() != "block"));

	if(! (evt.ctrlKey || evt.altKey || evt.metaKey)) {
		if(evt.keyCode == 27) { // escape!!!;
  	              document.getElementById("search_dialog").style.display="none";
		}
		else if (isLeftArrow(evt.keyCode) && (Number(start) >= Number(photosPerPage)) && ! searchDialogShowing()) // left arrow
		{ gotoPage(Number(start) - Number(photosPerPage)); }
		else if ((isSpacebar(evt.keyCode, chr) || isRightArrow(evt.keyCode)) && (Number(start) < Number(photosTotal) - Number(photosPerPage)) && ! searchDialogShowing()) // right arrow
		{ gotoPage(Number(start) + Number(photosPerPage)); }
		else if(
			(evt.keyCode == 8) || // backspace
			(evt.keyCode == 13) || // enter
//			(evt.keyCode == 37) || (evt.keyCode == 63234) || // left arrow
			isRightArrow(evt.keyCode) || 
			(evt.keyCode == 38) || // up arrow
			isLeftArrow(evt.keyCode) || 
//			(evt.keyCode == 39) || (evt.keyCode = 63235) || // right arrow
			(evt.keyCode == 40) ||  // down arrow
			(evt.keyCode == 91) || // windows key
			(isIE && (evt.keyCode > 111 && evt.keyCode < 124))) // function key
		{  
			// do nothing
		}
		else {
			var search_dialog = document.getElementById("search_dialog");
			var just_changed = false;
//			alert("search_dialog = " + search_dialog + ", search_dialog.style.display.toString() = " + search_dialog.style.display.toString());
		  	if(! searchDialogShowing())
			{
	        		search_dialog.style.display = "block";
	        		search_dialog.style.zIndex = 2.0;
				just_changed = true;
				var queryBox = document.getElementById("q");
  				if(queryBox !== undefined && (queryBox != null)) {
		       			if(!isIE && !isSafari && just_changed) queryBox.value = chr;
					queryBox.focus();
				};
			}
		}
	}
}
	
