// javascript for setting the feature image from thumbnails

var gCurrentImage = null;
var gCurrentImageIndex = null;		// index of the currently displayed image
var gNewImageIndex = null;

//imgWidth, imgHeight, leftMattWidth, imgMarginTop, mattColor, imagePath, null
var GIMAGES_SUPPLIED_WIDTH 		= 0;
var GIMAGES_SUPPLIED_HEIGHT 	= 1;
var GIMAGES_LEFT_MATT_WIDTH 	= 2;
var GIMAGES_IMG_MARGIN_TOP 		= 3;
var GIMAGES_MATT_COLOR 			= 4;
var GIMAGES_IMAGE_PATH 			= 5;
var GIMAGES_IMGOBJ 				= 6;

// DEFAULT MATT COLOR: grey matt
//var defaultMattColor = "#E2E6E7";
var defaultMattColor = "#FFFFFF";

var gCurrentFadeOutOpacity;
var gCurrentFadeInOpacity;

var bImageLoaded = false;
var bMattMoved = false;

var gFadeInMsStart;
var gFadeInMsEnd;

// INTERVAL TIMERS
var intervalTimerFadeOut = null;
var intervalTimerAdjustMatt = null;
var intervalTimerFadeIn = null;

var gExpectedTotalMillisecondsFade = 1000;
var gExpectedTotalStepsFade = 40;

var gTotalMillisecondsFade = gExpectedTotalMillisecondsFade;
var gTotalStepsFade = gExpectedTotalStepsFade;
var gFadeOutObj;
var gFadeInObj;
var gOpacityIncrement;


var leftMattWidthStart = 450;
var leftMattWidthDifference;
var rightMattWidthStart = 450;
var rightMattWidthDifference;
var totalMillisecondsAdjustMatt = 0;
var totalStepsAdjustMatt = 0;
var currentStepAdjustMatt = 0;
var leftMattObj;
var rightMattObj;
var adjustMattObj;

var currentOpacity = 100;
var browserdetect = "";

var bInitialized = false;

function init() {
	output( "calling init" );
	leftMattObj = getElementById( "id_mattLeftBox");
	rightMattObj = getElementById( "id_mattRightBox");
}

/* the beginning of changing an image from one to another
 * mostly this does 4 things:
 *		determine the image to load next
 * 		ensure that the image has been downloaded
 * 		either: 	start any fadeout process of previous image (if necessary)
 *			or:		call setFeatureImage2 for the next stage of the process
 */

function setFeatureImage( id_anchor ) {
	
	output( "setFeatureImage( "+id_anchor+" )" );

	// reset all interval timers
	if ( intervalTimerFadeOut != null ) clearInterval( intervalTimerFadeOut );
	if ( intervalTimerAdjustMatt != null ) clearInterval( intervalTimerAdjustMatt );
	if ( intervalTimerFadeIn != null ) clearInterval( intervalTimerFadeIn );

	// restart the flags for showing the iamge
	bMattMoved = false;
	bImageLoaded = false;
	
	// only ever called once
	if ( ! bInitialized ) {
		init();
		bInitialized = true;
	}

	// grab the image index from the passed in achor tag
	var regExp = new RegExp( /\d+/ );
	gNewImageIndex = id_anchor.match( regExp );
	
	// determine if the image has already been loaded, if not, create an ImgObj which will load it
	if ( gImages[ gNewImageIndex ][GIMAGES_IMGOBJ] == null ) {
		output( "setFeatureImage: creating imgObj for " + gImages[ gNewImageIndex ][GIMAGES_IMAGE_PATH] );
		gImages[ gNewImageIndex ][GIMAGES_IMGOBJ] = new ImgObj( gNewImageIndex, gImages[ gNewImageIndex ][GIMAGES_IMAGE_PATH] );
	} else {
		bImageLoaded = true;
	}

	// find out if we need to "fadeout" the previous image or not
	if ( gCurrentImageIndex != null ) {
		// ensure the highlights of the links are correct
		getElementById( 'navigation_' + gCurrentImageIndex ).className = "navigation";
		getElementById( "navigation_" + gNewImageIndex ).className = "navigationCurrent";

		// begin the fadeout process using an interval timer... when it is done, setFeatureImage2 will be called
		output( "setFeatureImage: calling fadeObjOut( " + gCurrentImage + ")" );
		fadeObjOut( gCurrentImage );
	} else {
		// ensure the hightlights of the links are correct
		//alert( "navigation_" + gNewImageIndex );
		getElementById( "navigation_" + gNewImageIndex ).className = "navigationCurrent";
		output( "setFeatureImage: calling setFeatureImage2" );			
		setFeatureImage2();
	}
}

/* this phase will move the image across the page, while loading the image.
 * there is an assumption that the previous image is fully faded by now
 */
 
function setFeatureImage2() {
	
	output( "setFeatureImage2" );

	// hide the old image (fully faded)
	getElementById('id_featureImageBox').style.display = "none";

	// if there was no previous image, then we set the current image also as the previous, so that 
	// future commands on the previous image don't fail.
	if ( gCurrentImageIndex == null ) {
		gCurrentImageIndex = gNewImageIndex+ "";
	}
	
	if ( bImageLoaded ) {
		bImageLoaded = false;
		output( "clearTimer: setTimeout( 'setFeatureImage3()') " );			
		setTimeout( 'setFeatureImage3();', 1 );
	} else {
		bMattMoved = true;
		output( "clearTimer: showLoadingText" );
		showLoadingText();
	}
}


// show the image as transparent and start the process of fading in
function setFeatureImage3() {
	
	output( "setFeatureImage3: should have a valid img: " + gImages[gNewImageIndex][GIMAGES_IMGOBJ].img );
	output( "setFeatureImage3: calling setImageFeature" );
	
	
	// this will set the height, width, position, and mattcolor
	setImageFeatures( gImages[gNewImageIndex][GIMAGES_SUPPLIED_WIDTH], 
					  gImages[gNewImageIndex][GIMAGES_SUPPLIED_HEIGHT], 
					  gImages[gNewImageIndex][GIMAGES_LEFT_MATT_WIDTH],
					  gImages[gNewImageIndex][GIMAGES_IMG_MARGIN_TOP], 
					  gImages[gNewImageIndex][GIMAGES_MATT_COLOR], 
					  gImages[gNewImageIndex][GIMAGES_IMGOBJ].img ); 
					  
	featureImageBoxNode = getElementById("id_featureImageBox");
	gCurrentImageIndex = gNewImageIndex;
	gCurrentImage = gImages[gNewImageIndex][GIMAGES_IMGOBJ].img;

	// image starts out faded
	setOpacity(gCurrentImage, 0);

	// show the image, fully transparent
	featureImageBoxNode.style.display = "inline";	
	featureImageBoxNode.replaceChild( gCurrentImage, featureImageBoxNode.firstChild );
	
	output( "setFeatureImage3: calling fadeObjIn" );
	// begin the fadeIn process using an interval timer...
	fadeObjIn( gCurrentImage );
}




function ImgObj ( index, src ) {
	output( "creating ImgObj: [" + [index, src] + "]" );
	this.img = document.createElement("img");
	
	this.img.className = "picture";
	this.img.id = "id_feature_image_" + index;
	this.img.onload = evtImageLoaded;
	this.img.src = src;

	setOpacity( this.img, 0 );	
}

function evtImageLoaded() {
	
	output( "evtImageLoaded" );
	
	output( "evtImageLoaded: this: " + this );
	output( "evtImageLoaded: this['parentNode']: " + this["parentNode"] );
	
	// the image will load twice, once for the IMG and once for IMG.SRC
	if ( this["parentNode"] != null ) {
		// this is when the IMG is created but not assigned and has no source... ignore
		output("evtImageLoaded: parentNode exists, evtImageLoaded return");
		return;
	}
	
	try {
		output( "evtImageLoaded: gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height "  + gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height );
	} catch ( e ) {
		output ( e );
	}
	
	try {
		// if the image is too tall, we scale it down to fit within 400 pixels
		if ( gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height > 400 ) {
			output( "evtImageLoaded: readjusting height" );
			var imgMultiplier = 400 / gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height;
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height 			= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height * imgMultiplier;		
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.style.height 	= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height + "px";		
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width 			= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width * imgMultiplier;
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.style.width 	= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width + "px";
		}
	
		// if the image is too wide (even after scaling), we scale it down to fit within 900 pixels
		if ( gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width > 900 ) {
			output( "evtImageLoaded: readjusting width" );
			var imgMultiplier = 900 / gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width;
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height 			= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height * imgMultiplier;		
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.style.height 	= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.height + "px";		
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width 			= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width * imgMultiplier;
			gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.style.width 	= gImages[gNewImageIndex][GIMAGES_IMGOBJ].img.width + "px";
		}
	} catch ( e1 ) {
		output( "tried to used img.width: " + e1 );
	}


	
	// check to see if the image is ready to display
	if ( bMattMoved ) {
		// yes, so display image
		output( "evtImageLoaded: calling directly setFeatureImage3" ); 
		mMattMoved = false;
		setFeatureImage3();
	} else {
		// no, so flag that the image is loaded
		output( "evtImageLoaded: ending completely, bImageLoaded = true;" );
		bImageLoaded = true;
	}
}	

// move to the previous image
function setFeatureImagePrevious( ) {
	var index = (parseInt(gCurrentImageIndex) - 1);
	
	// the mod operaton failed here, so I do mod manually
	if ( index == -1 ) {
		index = gImages.length - 1;
	}
	setFeatureImage( 'navigation_' + index );
}

// move to the next image
function setFeatureImageNext( ) {
	var index = (parseInt(gCurrentImageIndex) + 1) % gImages.length;
	setFeatureImage( 'navigation_' + index );
}

function equalsNothing( value ) {
	if ( value == "" || value == null || value == undefined || value == 0 ) {
		return true;
	} else {
		return false;
	}
}

// this function is for a div with a background color and an internal image div
function setImageFeatures( imgWidth, imgHeight, leftMattWidth, imgMarginTop, mattColor, img ) {

	output( "setImageFeatures: " + [imgWidth, imgHeight, leftMattWidth, imgMarginTop, mattColor, img] );	
	/*
	// set the color of the borders around the navigation menu
	var navGalleryTable = getElementById("id_navGalleryTable");
	var row = navGalleryTable.rows[0];
	for ( var index = 0; index < row.cells.length; index++ ) {
		row.cells[index].style.borderColor = mattColor;
	}
	*/
	
	if ( mattColor == "" || mattColor == null || mattColor == undefined ) {
		mattColor = defaultMattColor;
		output( "mattColor = " + mattColor );
	}

	// set the color of the matt
	var mattLeftBox = getElementById( "id_mattLeftBox" );
	var mattRightBox = getElementById( "id_mattRightBox" );
	var featureImageBox = getElementById( "id_featureImageBox" );
	mattLeftBox.style.backgroundColor = mattColor;
	mattRightBox.style.backgroundColor = mattColor;
	
	output( "img.width = " + img.width );
	output( "img.height = " + img.height );
		
	if ( equalsNothing(imgWidth) || equalsNothing(imgHeight) || equalsNothing(leftMattWidth) ) {
		mattLeftBox.style.width = (( 900 - img.width ) / 2  - 1 ) + "px";
		mattLeftBox.style.height = img.height + "px";
		mattRightBox.style.width = (( 900 - img.width ) / 2 - 1) + "px";
		mattRightBox.style.height = img.height + "px";
		img.style.width = img.width;
		img.style.height = img.height;
	} else {
	//	featureImageBox.style.borderLeftColor = mattColor;
	//	featureImageBox.style.borderRightColor = mattColor;
	
		// set the size of the leftMatt
	//	mattLeftBox.style.width = leftMattWidth + "px";
	//	mattRightBox.style.width = (900 - imgWidth - 2 - leftMattWidth) + "px";
		
		// set the size of the matt height (which should always be 400)
		mattLeftBox.style.height = imgHeight + "px";
		mattRightBox.style.height = imgHeight + "px";
		
	//	output( img["node"] );
	
		// override the defaults
		if ( imgHeight != "" && imgHeight != null ) {
			img.style.height = imgHeight + "px";
		}
		
		if ( imgWidth != "" && imgWidth != null ) {
			img.style.width = imgWidth + "px";
		}
	
		// set any margin at the top
	//	mattLeftBox.style.paddingTop = imgMarginTop + "px";
	//	mattRightBox.style.paddingTop = imgMarginTop + "px";
	}
}

// settting up the interval to fadeout
function fadeObjOut( obj ) {

	gFadeOutObj = obj;

	if ( obj.src == "" || obj.src == null ) {
		output( "fadeObjOut: obj does not exist, calling setFeatureImage2" );
		setFeatureImage2();
		return;
	}
	
	gFadeOutObj = obj;
	var stepMilliseconds = Math.round( gTotalMillisecondsFade / gTotalStepsFade );
	gOpacityIncrement = 100 / gTotalStepsFade;
	gCurrentFadeOutOpacity = 100;
	
	//alert( "fadeout: stepMilliseconds = " + stepMilliseconds + " : gOpacityIncrement = " + gOpacityIncrement );

	output( "fadeObjOut: gradualFadeIn( gradualFadeOut" );
	intervalTimerFadeOut = setInterval(gradualFadeOut, stepMilliseconds);
}

// settting up the interval to fadein
function fadeObjIn( obj ) {
	
	gFadeInObj = obj;
	browserdetect=obj.style.filter? "ie" : typeof obj.style.MozOpacity=="string"? "mozilla" : "";

	var stepMilliseconds = Math.round( gTotalMillisecondsFade / gTotalStepsFade );
	gOpacityIncrement = 100 / gTotalStepsFade;
	gCurrentFadeInOpacity = 0;

	//alert( "fadein: stepMilliseconds = " + stepMilliseconds + " : gOpacityIncrement = " + gOpacityIncrement );

	output( "fadeObjIn: gradualFadeIn( gradualAdjustMatt" );
	gFadeInMsStart = new Date();
	intervalTimerFadeIn = setInterval("gradualFadeIn()",stepMilliseconds);
}

// settting up the interval to adjust the matt
function adjustMatt( leftMattWidthNew, rightMattWidthNew, totalMilliseconds, totalSteps ) {
	var stepMilliseconds = Math.round(totalMilliseconds / totalSteps);
	totalStepsAdjustMatt = totalSteps;
	
	output( "adjustMatt: leftMattWidthNew - leftMattWidthStart = leftMattWidthDifference " + leftMattWidthNew + "-" + leftMattWidthStart + "=" + (leftMattWidthNew - leftMattWidthStart) );
	output( "adjustMatt: rightMattWidthNew - rightMattWidthStart = rightMattWidthDifference " + rightMattWidthNew + "-" + rightMattWidthStart + "=" + (rightMattWidthNew - rightMattWidthStart) );
	
	leftMattWidthDifference = leftMattWidthNew - leftMattWidthStart;
	rightMattWidthDifference = rightMattWidthNew - rightMattWidthStart;
//	alert( leftMattWidthDifference + ":" + rightMattWidthDifference );
//	alert( Math.round(( leftMattWidthDifference / totalStepsAdjustMatt ) * 1 ));
	currentStepAdjustMatt = 0;
	output( "adjustMatt: setInterval( gradualAdjustMatt, " + stepMilliseconds + ")" );
	intervalTimerAdjustMatt = setInterval("gradualAdjustMatt('adjustMatt')",stepMilliseconds);	
}

function gradualFadeIn(){
	gCurrentFadeInOpacity += gOpacityIncrement;
	setOpacity( gFadeInObj, gCurrentFadeInOpacity );
	if ( gCurrentFadeInOpacity >= 100 ) {
		clearTimer( 'fadeIn' );
	} 
}

function gradualFadeOut(){

	gCurrentFadeOutOpacity -= gOpacityIncrement;
	setOpacity( gFadeOutObj, gCurrentFadeOutOpacity );
	if ( gCurrentFadeOutOpacity <= 0) {
		clearTimer( 'fadeOut' );
	}
}

function gradualAdjustMatt( timerType ) {
	output( "gradualAdjustMatt: " + currentStepAdjustMatt + " < " + totalStepsAdjustMatt );
	currentStepAdjustMatt += 1;
	output( "gradualAdjustMatt: " + currentStepAdjustMatt + " < " + totalStepsAdjustMatt );
	if ( currentStepAdjustMatt >= totalStepsAdjustMatt ) {
		output( "inside if" );
		output( "leftMattObj: " + leftMattObj);
		output( "leftMattObj.style.width: " + leftMattObj.style.width);
		output( "leftMattWidthStart: " +leftMattWidthStart );
		output( "leftMattWidthDifference: " + leftMattWidthDifference);
		output( "rightMattObj: " + rightMattObj);
		output( "rightMattObj.style.width: " + rightMattObj.style.width);
		output( "rightMattWidthStart: " +rightMattWidthStart );
		output( "rightMattWidthDifference: " + rightMattWidthDifference);
		leftMattObj.style.width = leftMattWidthStart + leftMattWidthDifference + "px";
		rightMattObj.style.width = rightMattWidthStart + rightMattWidthDifference + "px";
		output( "gradualAdjustMatt: calling clearTimer( " + timerType +")" );
		clearTimer( timerType );
		return;
	}
	leftMattObj.style.width = leftMattWidthStart + Math.round(( leftMattWidthDifference / totalStepsAdjustMatt ) * currentStepAdjustMatt )  + "px";
	rightMattObj.style.width = rightMattWidthStart + Math.round(( rightMattWidthDifference / totalStepsAdjustMatt ) * currentStepAdjustMatt )  + "px";
}


function instantset(obj, opacity){
	setOpacity( obj, opacity );
}

function clearTimer( timerType ){
	
	output( "clearTimer: timerType == " + timerType );
	
	if ( timerType == 'fadeOut' ) {
		clearInterval(intervalTimerFadeOut);
		output( "clearTimer: setTimeout( 'setFeatureImage2()') " );
		setTimeout( 'setFeatureImage2();', 1 );
	} else if ( timerType == 'fadeIn' ) {
		gFadeInMsEnd = new Date();
		var totalTime = gFadeInMsEnd.getTime() - gFadeInMsStart.getTime();
		var factor = gExpectedTotalMillisecondsFade / totalTime;
		if ( factor < 0.9 ) {
			var halfFactor = 1 - ( (1 - factor) / 2);
			//alert( " factor = " + factor + " :  Math.round( gTotalStepsFade * factor ) = " + Math.round( gTotalStepsFade * factor ) );
			if ( gTotalMillisecondsFade != 1 ) {
				gTotalStepsFade = Math.max( Math.round( gTotalStepsFade * halfFactor ), 1 ) + 1;
				if ( factor > 1 ) {
					gTotalMillisecondsFade = gTotalMillisecondsFade * 1.2;
				}
			}
			if ( gTotalStepsFade == 1 ) {
				gTotalMillisecondsFade = 1;
			} 
		}
		//alert ( "new total steps = " + gTotalStepsFade );
		clearInterval(intervalTimerFadeIn);
	} else if ( timerType == 'adjustMatt' ) {
		clearInterval(intervalTimerAdjustMatt);
		leftMattWidthStart += leftMattWidthDifference;
		rightMattWidthStart += rightMattWidthDifference;
		if ( bImageLoaded ) {
			bImageLoaded = false;
			output( "clearTimer: setTimeout( 'setFeatureImage3()') " );			
			setTimeout( 'setFeatureImage3();', 1 );
		} else {
			bMattMoved = true;
			output( "clearTimer: showLoadingText" );
			showLoadingText();
		}
	}
}

function showLoadingText() {
	output( "showLoadingText" );
	var featureImageBoxNode = getElementById('id_featureImageBox');
	featureImageBoxNode.replaceChild( document.createTextNode( "image loading..." ), featureImageBoxNode.firstChild );
	featureImageBoxNode.style.display = "inline";
}

function outputObject( obj ) {
	/*
	var output = document.getElementById( "id_output" );
	var x;
	for ( x in obj ) {
		output.appendChild( document.createTextNode( x + " = " + obj[x] ) );
		output.appendChild( document.createElement( "br" ) );
	}
	*/
}

function output( str ) {
	/*
	var output = document.getElementById( "id_output" );
	output.appendChild( document.createTextNode( str ));
	output.appendChild( document.createElement( "br" ) );
	*/	
}

function setOpacity(obj, opacity)
{
	if (obj.style.MozOpacity != null) {
			/* Mozilla’s pre-CSS3 proprietary rule */
			obj.style.MozOpacity = (opacity/100)-.001;
			/* the .001 fixes a glitch in the opacity calculation which normally results in a flash when reaching 1 */
	} else if (obj.style.opacity != null) {
			/* CSS3 compatible */
			obj.style.opacity = (opacity/100)-.001;
	} else if (obj.style.filter != null) {
			/* IE’s proprietary filter */
			obj.style.filter = "alpha(opacity="+opacity+")";
			/* worth noting: IE’s opacity needs values in a range of 0-100, not 0.0 - 1.0 */
	}
}

function detectEnterGoToClient() {
	if ( event.keyCode == 13 ) {
		goToClient();
	}
}


function goToClient() {
	var dir=getElementById('id_login').value;
	window.location='/'+dir+'/index.html';
}

function getElementById( id ) {
	if ( document.getElementById ) {
		return document.getElementById( id );
	} else {
		return document.all[id];
	}
}

