// Mouse Over Thumbnail Image Loader
// (c) 2008 Gee Whiz Labs, Inc,
//
// Jonathon Moldenhauer
// 

// Global array that holds each thumbnail image object when it is created.
var g_Images = new Array ();

// Constructor for moiImageObj...
//   var myImageObj = new moiImageObj( '/somedir/someplace/somepic.jpg', somewidth, someheight, optionaltitle )
// ...
//   <script language="javascript">document.write( myImageObj.render('tooltip="..."'));</script>
//
function moiImageObj(imageSrc, imageWidth, imageHeight, imageTitle) {
	this.imageSrc = imageSrc;
	this.imageWidth = imageWidth;
	this.imageHeight = imageHeight;
	this.imageTitle = imageTitle;
	
	this.render = function(additionalMarkup) {
		var toWrite = '<img src="' + this.imageSrc + '"';
		if (this.imageWidth && this.imageHeight) {
			toWrite += 'width="' + this.imageWidth + '" height="' + this.imageHeight + '"';
		}
		if (this.imageTitle) {
			toWrite += '';
		}
		if (additionalMarkup) {
			toWrite += additionalMarkup;
		}
		toWrite += ' />';
		return toWrite;
	}
}

// Utility function used to determine an element's X, Y position in the current document by
// traversing the elements containers and adding up the offsetTop/offsetLeft values.
//
//    var myXYArray = getXYElementPos('myelementid');
//
//    var myelementobject = document.getElementById('myelementid');
//    var myXYArray = getXYElementPos(myelementobject);
//
function getXYElementPos(elementOrId) {
	var x = 0, y = 0, element;
	
	if (elementOrId && typeof(elementOrId) != 'object') {
		element = document.getElementById(elementOrId);
	}
	else {
		element = elementOrId;
	}
	
	if (element && element.offsetParent) {
		do {
			x += element.offsetLeft;
			y += element.offsetTop;
		} while (element = element.offsetParent);
	}
	
	return [ x, y ];
}

// Constructor for moiThumbnailObj
//   var myThumbnailObj = new moiThumbnailObj(new moiImageObj('...', )
//     new Array( new moiImageObj('...', ), new moiImageObj('...', ), ... ) );
// ...
//   <script language="javascript">document.write( myThumbnailObj.render('tooltip="..."'));</script>
//
function moiThumbnailObj(thumbnailImage, imageObjectArray) {
	// Save passed in object references into this object
	this.thumbnailImage = thumbnailImage;
	this.imageObjectArray = imageObjectArray;

  // This object's index in the global table stored in this object for future use
	this.index = g_Images.length;
	
	// Set some object variables
	this.imagesDiv = null;
	this.imagesDivWritten = 0;

  // This is a member function, render(), that generates the HTML code to be written to the
	// document by the caller.
	this.render = function(additionalMarkup) {
		if (! additionalMarkup)
		  additionalMarkup = '';
		var toWrite = thumbnailImage.render('onmouseover="Helper_OnMouseOver(' + this.index + ', event);" onmouseout="Helper_OnMouseOut(' + this.index + ');" id="image' + this.index + '" ' + additionalMarkup);
		if (this.imagesDivWritten == 0) {
			toWrite += '<div id=imageoverlay' + this.index +
								 ' style="display: none; width: auto; height: auto; background-color: transparent; color: #000000; z-index: 1000000;"' +
								 ' onmouseover="Helper_OnMouseOver(' + this.index + ', event);" onmouseout="Helper_OnMouseOut(' + this.index + ');"></div>';
			this.imagesDivWritten = 1;
		}
		return toWrite;
	}
	
	// This is a member function, which is called when a timeout event is triggered that was
	// previously setup by the setTimeout function.
	//
	// This specific function is for displaying the popup div window and setting its contents
	// to show all image objects.  This is triggered by a timeout that is setup by the
	// onmouseover event.
	this.ontimeoutover = function() {
		if (this.shown == 0 && this.imagesDiv != null) {
			this.imagesDiv.style.position = 'absolute';
			var imageElement = document.getElementById('image' + this.index);
			var xy = getXYElementPos('image' + this.index);

//			if (imageElement === null || (xy[0] == 0 && xy[1] == 0)) {
//				if (this.imagesDiv.style.pixelLeft) {
//					this.imagesDiv.style.pixelLeft = this.mouseX;
//					this.imagesDiv.style.pixelTop = this.mouseY;
//				}
//				else {
//					this.imagesDiv.style.left = this.mouseX + 'px';
//					this.imagesDiv.style.top = this.mouseY + 'px';
//				}
//			}
//			else {
//				xy[1] += imageElement.offsetHeight + 4;
//				this.imagesDiv.style.left = xy[0] + 'px';
//				this.imagesDiv.style.top = xy[1] + 'px';
//			}
			if (this.imagesDiv.innerHTML == '') {
				var divborder = 'border: 1px solid #6c6; border-top: none;';
				var innerHTML = '';

				if (this.imageObjectArray.length > 1 || this.imageObjectArray[0].imageTitle) {
					innerHTML += '<ul style="text-align: left; margin: 1em 0 0 0; font: bold 11px verdana, arial, sans-serif; border-bottom: 1px solid #6c6; list-style-type: none; padding: 3px 10px 3px 10px;">';
					for (index = 0; index < this.imageObjectArray.length; index++) {
						var title = '';
						if (this.imageObjectArray[index].imageTitle) {
							title = this.imageObjectArray[index].imageTitle;
						}
						else {
							var imgIndex = index + 1;
							title = 'Image ' + imgIndex;
						}
						var styleli = (index == 0) ? 'border-bottom: 1px solid #fff; background-color: #fff;' : '';
						var stylea = (index == 0) ? 'background-color: #fff; color: #000; position: relative; top: 1px; padding-top: 4px;' : '';
						innerHTML += '<li id="imageoverlay' + this.index + 'li' + index + '" style="display: inline; ' + styleli + '">' +
							'<a id="imageoverlay' + this.index + 'link' + index + '" href="javascript:Helper_OnClickLink(' + this.index + ', ' + index + ')" style="padding: 3px 4px; border: 1px solid #6c6; background-color: #cfc; color: #666; margin-right: 0px; text-decoration: none; border-bottom: none; ' + stylea + '">' + title + '</a></li>';
					}
//				innerHTML += '<li style="display: inline;"><a id="imageoverlay' + this.index + 'closelink" href="javascript:Helper_OnClickClose(' + this.index + ')" style="border: 1px solid #6c6; background-color: #cfc; color: #600 margin-right: 0px; padding: 3px 4px; text-decoration: none; text-align: right">Close&nbsp;Window</a></div>';
					innerHTML += '</ul>';
				}
				else {
					divborder = 'border: 1px solid #6c6;';
				}

				for (index = 0; index < this.imageObjectArray.length; index++) {
					var display = (index == 0) ? "block" : "none";
					innerHTML += '<div id="imageoverlay' + this.index + 'image' + index + '" style="display: ' + display + '; ' + divborder + '">';
					innerHTML += this.imageObjectArray[index].render();
					innerHTML += '</div>';
				}
				this.imagesDiv.innerHTML = innerHTML;
				document.body.appendChild(this.imagesDiv);
			}
			this.imagesDiv.style.visibility = 'hidden';
			this.imagesDiv.style.display = 'block';

			viewport.getAll();

			if ( this.mouseX + this.imagesDiv.offsetWidth + 12 > viewport.width + viewport.scrollX ) {
					this.mouseX = this.mouseX - this.imagesDiv.offsetWidth - 12;
					if (this.mouseX < 0) this.mouseX = 0;
			} else this.mouseX = this.mouseX + 12;

			if ( this.mouseY + this.imagesDiv.offsetHeight + 12 > viewport.height + viewport.scrollY ) {
					this.mouseY = this.mouseY - this.imagesDiv.offsetHeight - 12;
					if ( this.mouseY < viewport.scrollY ) this.mouseY = viewport.height + viewport.scrollY - this.imagesDiv.offsetHeight;
					if (this.mouseY < 0) this.mouseY = 0;
			} else this.mouseY = this.mouseY + 12;

      this.imagesDiv.style.left = this.mouseX + "px"; this.imagesDiv.style.top = this.mouseY + "px";

//			var left = parseInt(this.imagesDiv.style.left);
//			if (left + this.imagesDiv.offsetWidth > document.body.clientWidth) {
//				left = document.body.clientWidth - this.imagesDiv.offsetWidth;
//				this.imagesDiv.style.left = left + 'px';
//			}
			
			this.imagesDiv.style.visibility = 'visible';

			this.shown = 1;
			this.timerOver = null;
		}
	}
	
	// This is a member function, which is called when a user clicks a tabbed link in the
	// popup div.
	//
	// This function changes which image is displayed and updates the styles of the tabs
	// to reflect the visual clues of which image is being shown.
	this.onclicklink = function(index) {
		var objLi = document.getElementById('imageoverlay' + this.index + 'li' + index);
		var objA = document.getElementById('imageoverlay' + this.index + 'link' + index);
		var objDiv = document.getElementById('imageoverlay' + this.index + 'image' + index);
		
		for (oldIndex = 0; oldIndex < this.imageObjectArray.length; oldIndex++) {
			if (oldIndex != index) {
				var oldObjLi = document.getElementById('imageoverlay' + this.index + 'li' + oldIndex);
				var oldObjA = document.getElementById('imageoverlay' + this.index + 'link' + oldIndex);
				var oldObjDiv = document.getElementById('imageoverlay' + this.index + 'image' + oldIndex);
				
				if (oldObjLi.style.removeProperty) {
					oldObjLi.style.removeProperty('background-color');
					oldObjLi.style.removeProperty('border-bottom');
					oldObjA.style.removeProperty('top');
					oldObjA.style.removeProperty('position');
				}
				else {
					oldObjLi.style.backgroundColor = '#cfc';
					oldObjLi.style.borderBottom = '1px solid #cfc';
					oldObjA.style.top = '0px';
				}
				oldObjA.style.backgroundColor = '#cfc';
				oldObjA.style.color = '#666';
				oldObjA.style.padding = '3px 4px';
				oldObjDiv.style.display = 'none';
			}
		}
		
		objLi.style.backgroundColor = '#fff';
		objLi.style.borderBottom = '1px solid #fff';
		objA.style.top = '1px';
		objA.style.position = 'relative';
		objA.style.backgroundColor = '#fff';
		objA.style.color = '#000';
		objA.style.paddingTop = '4px';
		objDiv.style.display = 'block';
	}

	// This is a member function, which is called when a user moves their mouse over
	// either the thumbnail image or, if the popup div is shown, the popup div area.
	//
	// This function is used to  set a timer to popup the div when the user hovers
	// their mouse over the thumbnail AND it is used to keep the popup div up when the
	// user hovers their mouse over the popup div.
	this.onmouseover = function(e) {
		if (this.shown == 0) {
			if (this.imagesDivWritten == 1 && this.imagesDiv == null)
						this.imagesDiv = document.getElementById('imageoverlay' + this.index);
			if (this.imagesDiv != null && this.timerOver == null) {
				this.timerOver = setTimeout('Helper_OnTimeoutOver(' + this.index + ');', 750);

				if (!e) e = window.event;
        var x = e.pageX ? e.pageX : e.clientX + viewport.scrollX;
        var y = e.pageY ? e.pageY : e.clientY + viewport.scrollY;

				this.mouseX = x;
				this.mouseY = y;
			}
		}
		else if (this.imagesDiv != null && this.timerOut != null) {
			clearTimeout(this.timerOut);
			this.timerOut = null;
		}
	}
	
	// This is a member function, which is called when a user clicks on the window
	// close icon/link.  (this feature is currently turned off).
	//
	// This function clears any timers pending to close out the window and then
	// uses the ontimeout member function to actually close (hide) the div popup.
	this.onclickclose = function() {
		if (this.timerOut != null) {
			clearTimeout(this.timerOut);
			this.timerOut = null;
		}
		this.ontimeoutout();
	}
	
	// This is a member function, which is called by onclickclose above OR when
	// a timeout is fired to close out the window.  This timeout is setup by the
	// onmouseout member function so that the div remains visible for a short time
	// after the user moves their mouse out of the div or thumbnail.
	//
	// This function clears any timers pending to open the window to prevent the
	// div from popping up if the user just briefly moves over a thumbnail.  It
	// adjusts the style properties of the div to cause it to be hidden.
	this.ontimeoutout = function() {
		if (this.shown == 1 && this.imagesDiv != null) {
			this.imagesDiv.style.display = 'none';
			this.shown = 0;
		}
		if (this.timerOver != null) {
			clearTimeout(this.timerOver);
			this.timerOver = null;
		}
		this.timerOut = null;
	}
	
	// This is a member function, which is called by when a user moves their mouse
	// out of either the thumbnail image OR the popped up div.
	//
	// This function sets a timeout to close the popup div a short while after the
	// mouse has left; this gives the user time to navigate from the thumbnail to
	// the div and vice/versa.
	this.onmouseout = function() {
		if (this.shown == 1 && this.imagesDiv != null) {
			this.timerOut = setTimeout('Helper_OnTimeoutOut(' + this.index + ');', 750);
		}
		if (this.timerOver != null) {
			clearTimeout(this.timerOver);
			this.timerOver = null;
		}
	}
	
	// Few more variables
	this.timerOver = null;
	this.timerOut = null;
	this.shown = 0;
	
	// Store a reference to this object in the global images array.
	g_Images[g_Images.length] = this;
}

// This is a helper function that uses the global images array to call into
// the specified index's ontimeoutover function.
function Helper_OnTimeoutOver(index) {
	g_Images[index].ontimeoutover();
}

// This is a helper function that uses the global images array to call into
// the specified index's onmouseover function.
function Helper_OnMouseOver(index, e) {
	g_Images[index].onmouseover(e);
}

// This is a helper function that uses the global images array to call into
// the specified index's onmouseout function.
function Helper_OnMouseOut(index) {
	g_Images[index].onmouseout();
}

// This is a helper function that uses the global images array to call into
// the specified index's ontimeoutout function.
function Helper_OnTimeoutOut(index) {
	g_Images[index].ontimeoutout();
}

// This is a helper function that uses the global images array to call into
// the specified index's onclicklink function.
function Helper_OnClickLink(index, imgIndex) {
	g_Images[index].onclicklink(imgIndex);
}

// This is a helper function that uses the global images array to call into
// the specified index's onclickclose function.
function Helper_OnClickClose(index) {
	g_Images[index].onclickclose();
}

/* copied from rolltip_lib.js: */

/*************************************************************************

  dw_viewport.js
  version date Nov 2003
  
*************************************************************************/  

if (!viewport) {
	var viewport = {
		getWinWidth: function () {
			this.width = 0;
			if (window.innerWidth) this.width = window.innerWidth - 18;
			else if (document.documentElement && document.documentElement.clientWidth) 
				this.width = document.documentElement.clientWidth;
			else if (document.body && document.body.clientWidth) 
				this.width = document.body.clientWidth;
		},
		
		getWinHeight: function () {
			this.height = 0;
			if (window.innerHeight) this.height = window.innerHeight - 18;
			else if (document.documentElement && document.documentElement.clientHeight) 
				this.height = document.documentElement.clientHeight;
			else if (document.body && document.body.clientHeight) 
				this.height = document.body.clientHeight;
		},
		
		getScrollX: function () {
			this.scrollX = 0;
			if (typeof window.pageXOffset == "number") this.scrollX = window.pageXOffset;
			else if (document.documentElement && document.documentElement.scrollLeft)
				this.scrollX = document.documentElement.scrollLeft;
			else if (document.body && document.body.scrollLeft) 
				this.scrollX = document.body.scrollLeft; 
			else if (window.scrollX) this.scrollX = window.scrollX;
		},
		
		getScrollY: function () {
			this.scrollY = 0;    
			if (typeof window.pageYOffset == "number") this.scrollY = window.pageYOffset;
			else if (document.documentElement && document.documentElement.scrollTop)
				this.scrollY = document.documentElement.scrollTop;
			else if (document.body && document.body.scrollTop) 
				this.scrollY = document.body.scrollTop; 
			else if (window.scrollY) this.scrollY = window.scrollY;
		},
		
		getAll: function () {
			this.getWinWidth(); this.getWinHeight();
			this.getScrollX();  this.getScrollY();
		}
	}
}
