// sriFloatImages
//
// Copyright (c) 2006 Smallrock Internet Serivces, Inc.  All rights reserved.
//
// FloatImages is designed to show a larger floating image as the visitor moves the mouse
// over a thumbnail on the page.  The image is displayed as long as the mouse is over the
// thumbnail, and tracks with the mouse.  When the mouse is moved over the thumbnail for
// the first time, the optimum size and position for the larger image is determined by
// comparing that image against the browser client area.  Once that has been determined,
// it sticks until the mouse moves away from the thumbnail.  The following external
// functions are defined:
//
//		floatShowImage(event, "image URL");
//		floatMoveImage(event);
//		floatHideImage();
//
// These functions are called from <a> tags wrapping the thumbnail.  Each <a> tag should
// call floatShowImage from the onmouseover event, floatMoveImage from the onmousemove
// event, and floatHideImage from the onmouseout event.  The event object is browser
// dependent, but if not defined is handled in the functions.  Example:
//
//		<a href="" onmouseover="floatShowImage(event, 'xyz', 'images/one.gif');"
//			onmousemove="floatMoveImage(event);" onmouseout="floatHideImage();">
//			<img src="thumbnailone.gif" border="0"></a>
//		<a href="" onmouseover="floatShowImage(event, 'xyz', 'images/two.gif');"
//			onmousemove="floatMoveImage(event);" onmouseout="floatHideImage();">
//			<img src="thumbnailtwo.gif" border="0"></a>
//
// The script normally rewrites the <body> tag to include a division to float the image
// in.  In some circumstances this could cause problems because the page is effectivly
// reloaded.  The page can define a <div> tag with absolute positioning and hidden visibility
// and an id of "_floatImageDiv" to avoid having the HTML rewritten:
//
//		<div id="_floatImageDiv" style="position: absolute; visibility: hidden;">&nbsp;</div>
//
// There are several constant values defining padding within the division, the space
// from the mouse cursor, the background color and border characteristics of the
// floating division that may be changed here:

var _floatPadding = 10;						// Padding around the image in the div.
var _floatOffset = 10;						// Offset space from the mouse pointer.
var _floatBackground = "white";				// The background color of the floating division.
var _floatBorder = "solid 1px gray";		// The border style of the floating division.
var _floatFontFamily = "Arial,Helvetica";	// Caption font
var _floatFontSize = "9pt;"					// Caption font size
var _floatFontWeight = "normal";			// Caption font weight
var _floatFontStyle = "normal";				// Caption font style
var _floatFontColor	= "black";				// Caption font color
var _floatEventX;							// The original mouse X coordinate.
var _floatEventY;							// The original mouse Y coordinate.
var _floatObject;							// The HTML division that will float and contain the image;.
var _floatImage;							// The image to paint.
var _floatImageWait;						// The loading image
var _floatImagePictureName;					// The name of the image picture
var _floatImagePicture;						// The picture image
var _floatCaption;							// Caption text for the image, if any
var _floatLeftOffset = _floatOffset;		// Fixed left position relative to the mouse pointer.
var _floatTopOffset = _floatOffset;			// Fixed top position relative to the mouse pointer.
var _floatTimerID;							// Timer ID of delayed hide window method.
var _counter = 0;

function sriFloatHideImage()
{
	
	// Check to make sure that we have a division to hide.
	
	if (!_floatObject) {
		
		// This is a very unexpected situation.
		
		return;
	}
	
	// Clear the innerHTML in the float
	
	// _floatObject.innerHTML = "";

	// Set the stack to show that we want to hide the image, but do it after a 1/10 millisecond delay which allows
	// moving the mouse back over the area or the floating image to stop that.

	_floatTimerID = window.setTimeout("_floatObject.style.visibility = 'hidden'", 50);
}

function sriFloatMoveImage(e, y)
{
	
	// Check to make sure that we have a division to move
	
	if (!_floatObject) {
		
		// This is a very unexpected situation
		
		return;
	}
	
	// The division is positioned relative to the top of the document, not the client area,
	// so remember to offset it by the scrolled position.

	var scrollLeft = 0;
	var scrollTop = 0;
	
	/*
	if (typeof(window.pageYOffset) == 'number') {

		scrollLeft = window.pageXOffset;
		scrollTop = window.payYOffset;
		
	} else
	*/
	
	if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
			
		scrollLeft = document.body.scrollLeft;
		scrollTop = document.body.scrollTop;
		
	} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
		
		scrollLeft = document.documentElement.scrollLeft;
		scrollTop = document.documentElement.scrollTop;
	}
	
	// Get the current mouse position; the parameters in this function call are dual-use and
	// in one case may represent a mouse position passed by _sriFloatSizeImage or an event passed
	// in when the function is called from an <a> tag.

	var mouseX;
	var mouseY;
	
	if (y) {
		
		// e & y represent mouse coordinates passed from _sriFloatSizeImage.
		
		mouseX = e;
		mouseY = y;
	
	} else {
		
		// e may be an event object (DOM compliant browser) and if not, then
		// use the window.event object from IE.
	
		if (!e) {
			
			e = window.event || window.Event;
		}
	
		mouseX = e.clientX;
		mouseY = e.clientY;
	}
	
	// calculate the left and top offsets based on the relative values
	// built in _sriFloatSizeImage.
	
	_floatObject.style.left = (mouseX + _floatLeftOffset + scrollLeft) + "px";
	_floatObject.style.top = (mouseY + _floatTopOffset + scrollTop) + "px";
	_floatObject.style.visibility = "visible";
}

function _sriFloatImageWaitLoaded()
{
	
	// The wait image has finished loading (should beat the picture), display it.
	
	_floatImage = _floatImageWait;
	_sriFloatSizeImage();
	
	// Build the image and load the picture; we will return but get called back to size, position and
	// display the image once it is loaded.
	
	_floatImagePicture = new Image();
	_floatImagePicture.onload = _sriFloatImagePictureLoaded;
	_floatImagePicture.src = _floatImagePictureName;
}

function _sriFloatImagePictureLoaded()
{
	
	// The picture image has finished loading, display it.
	
	_floatImage = _floatImagePicture;
	_sriFloatSizeImage();
}

function _sriFloatSizeImage()
{
	
	// Our task here is to calculate the best size and position for the image.  The preferred position is to the
	// lower right of the mouse pointer by _float_offset pixels.  To calculate the true best position we divide
	// the browser client area vertically at the mouse pointer and select the larger half.  Then the horizontal
	// and vertical dimensions of that half are used to determine the dimensions of the image, if it needs to be
	// reduced.  The top offset of the image may be higher than the mouse pointer if the image would extend
	// past the lower border of the client area.
	//
	// Once the image size and relative position have been determined, they remain fixed even if the mouse pointer
	// moves.  Notice that the position is relative to the mouse pointer, so it will move if the mouse pointer
	// is moved.
	
	// Set up the division the first time through...
	
	if (!_floatObject) {
		
		// This is a very unexpected situation...
		
		return;
	}
	
	// Determine the mouse position in the client area.
	
	var mouseX = _floatEventX;
	var mouseY = _floatEventY;
	
	// Get the width and height of the browser client area.
	
	var clientWidth;
	var clientHeight;
	
	if (window.innerWidth) {
		
		clientWidth = window.innerWidth;
		clientHeight = window.innerHeight;
	
	} else if (document.documentElement && document.documentElement.clientWidth) {
		
		clientWidth = document.documentElement.clientWidth;
		clientHeight = document.documentElement.clientHeight;
		
	} else {
		
		clientWidth = document.body.clientWidth;
		clientHeight = document.body.clientHeight;
	}
	
	// Divide the client area vertically at the mouse and which half is bigger, and then decide how
	// wide the image can actually be.
	
	var totalMargin = (_floatPadding + _floatOffset) * 2;
	var maxWidth;
	var keepLeft = false;

	if (clientWidth - mouseX > _floatImage.width - totalMargin || clientWidth - mouseX > mouseX) {
		
		keepLeft = true;
		maxWidth = clientWidth - mouseX;
	
	} else {
	
		keepLeft = false;
		maxWidth = mouseX;
	}
	
	var maxImageWidth = Math.min(maxWidth - totalMargin, _floatImage.width);
	
	// The maximum height can't be more than the current client height.
	
	var maxImageHeight = Math.min(clientHeight - totalMargin, _floatImage.height);
	
	// Do we need to resize the image?
	
	var width = _floatImage.width;
	var height = _floatImage.height;
	
	if (maxImageWidth < width) {
		
		height = (maxImageWidth * height) / width;
		width = maxImageWidth;
	}
	
	if (maxImageHeight < height) {
		
		width = (maxImageHeight * width) / height;
		height = maxImageHeight;
	}
	
	// Fix the left offset relative to the mouse.
	
	if (keepLeft) {
		
		_floatLeftOffset = _floatOffset;
		
	} else {
		
		// Note we only use offset once here because the left margin is allowed for in the calculations above.
		
		_floatLeftOffset = -(width + _floatOffset + (_floatPadding * 2));
	}
	
	// Fix the top offset relative to the mouse; try to make it just below the mouse but move up as necessary.
	
	if (clientHeight - mouseY - (_floatOffset * 4) > height) {
		
		_floatTopOffset = _floatOffset;
	
	} else {
		
		// The "50" is added in here to make sure that enough space is below the picture bottom, otherwise when
		// the image appears on a downward mouse stroke the bottom immediately passes out of view.
		
		_floatTopOffset = (clientHeight - height - 50 - (_floatOffset * 4)) - mouseY;
	}
	
	// Write the inner html for the division
	
	
	var innerHTML = '<img src="' + _floatImage.src + '" width="' + width + '" height="' + height + '" border="0" />';
	
	if (_floatCaption) {
		
		innerHTML += '<br><div style="font-family: ' + _floatFontFamily + '; font-size: ' + _floatFontSize + '; font-weight: ' +
			_floatFontWeight + '; font-style: ' + _floatFontStyle + '; color: ' + _floatFontColor + '; margin-top: 5px;">' + _floatCaption + '</div>';
	}
	
	_floatObject.innerHTML = innerHTML;
	
	// OK, we're all set now to show the window
	
	sriFloatMoveImage(_floatEventX, _floatEventY);
}

function sriFloatShowImage(e, imagename, caption)
{
	
	// Stop the image from being hidden if we are pending that operation; calling this with an invalid or old ID
	// will not cause an error or exception
	
	window.clearTimeout(_floatTimerID);

	// Create the floating division at the end of the body HTML if we can't find it; if _floatObject is null it shouldn't
	// have been created but we handle the error case anyways, or the calling page already having declared it.
	
	if (!_floatObject) {
		
		if (!(_floatObject = document.getElementById("_floatImageDiv"))) {
			
			// This is what we expect, so we add the <div> tag to the end of the HTML
			
			document.body.innerHTML = '<div id="_floatImageDiv" style="position: absolute; visibility: hidden;">&nbsp;</div>' + document.body.innerHTML;
			
			if (!(_floatObject = document.getElementById("_floatImageDiv"))) {
				
				// This is extremely unexpected, and we can't really do anything about it so the script just won't work
				
				return;
			}
		
		}
		
		// Set the style for the <div> tag; doing it here picks up a tag provided by the document too
		
		_floatObject.style.padding = _floatPadding + "px";
		_floatObject.style.border = _floatBorder;
		_floatObject.style.backgroundColor = _floatBackground;
	}
	
	// Save the caption
	
	_floatCaption = caption;
	
	// If we already have the same image loaded, check the status
	
	if (_floatImage && _floatImage.src == imagename) {
		
		if (_floatObject.style.visibility != "visible") {
			
			// This will sync it with the mouse position and make it visible
			
			sriFloatMoveImage(e);			
		}
		
		return;
	}
	
	// Make the current image invisible while we do our work
	
	_floatObject.style.visibility = "hidden";
	
	// Determine the mouse position in the client area, and hang onto it for the callback to _sriFloatSizeImage.

	if (!e) {
	
		e = window.event || window.Event;
	}
	
	_floatEventX = e.clientX;
	_floatEventY = e.clientY;
	
	// Build the image and load the picture; we will return but get called back to size, position and
	// display the image once it is loaded.
	
	_floatImagePictureName = imagename;
	_floatImageWait = new Image();
	_floatImageWait.onload = _sriFloatImageWaitLoaded;
	_floatImageWait.src = "images/loadimage.gif";
}
