var g_modulePageImageRotate = false;
var g_modulePageImageTransition = false;
var g_modulePageImages = new Array();
var g_hdlModulePageImageLoadTimeout = null;
var g_hdlModulePageImageRotateTimeout = null;
var g_modulePageImageCurrentImage = 1;
var g_modulePageImageCount = 0;
var g_modulePageImagePageId = 0;
var MODULE_PAGE_IMAGE_GET_IMAGE_URL = '/page-image/retrieve-image';
var MODULE_PAGE_IMAGE_ROTATE_TIMEOUT = 7000; // timeout in milliseconds
var MODULE_PAGE_IMAGE_FADE_TIMEOUT = 1000; // timeout in milliseconds
var MODULE_PAGE_IMAGE_FADE_OPAQUE_FULL = -2;
var MODULE_PAGE_IMAGE_FADE_OPAQUE_TO_TRANSPARENT = -1;
var MODULE_PAGE_IMAGE_FADE_TRANSPARENT_TO_OPAQUE = 1;
var MODULE_PAGE_IMAGE_FADE_TRANSPARENT_FULL = 2;

function ModulePageImageRotateStart() { /* <<<( */

	// set rotation flag
	g_modulePageImageRotate = true;

	// begin rotation
	ModulePageImageRotateNext();

	return;
} /* )>>> */

function ModulePageImageLoadImage(imageIndex) { /* <<<( */

	var response = null;
	var requestUrl = MODULE_PAGE_IMAGE_GET_IMAGE_URL + '?sort-order=' + imageIndex + '&page-id=' + g_modulePageImagePageId;
	var xmlRequest = null;
	var imageId = 'module-page-image-image-container-' + g_modulePageImages[imageIndex - 1];
	var descriptionId = 'module-page-image-description-container-' + g_modulePageImages[imageIndex - 1];

	// clear any existing load timeout
	if (null != g_hdlModulePageImageLoadTimeout) {
		clearTimeout(g_hdlModulePageImageLoadTimeout);
		g_hdlModulePageImageLoadTimeout = null;
	}

	if (g_modulePageImageCurrentImage != imageIndex) {

		// check if currently in a transition
		if (true == g_modulePageImageTransition) {

			// try again in .3 seconds
			g_hdlModulePageImageLoadTimeout = setTimeout(function() {
					ModulePageImageLoadImage(imageIndex);
				}, 300);
		}
		else {
			// if not, load the new image

			// we are now in a transition
			g_modulePageImageTransition = true;

			if ((null == document.getElementById(imageId)) ||
				(null == document.getElementById(descriptionId)))
			{
				// build XML request to server
				xmlRequest = ModulePageImageGetXmlRequest();
				xmlRequest.onreadystatechange = function() {

					// check that request has completed
					if (4 == xmlRequest.readyState) {
						ModulePageImageCreateImage(xmlRequest, imageIndex);
						ModulePageImageDisplayImage(imageIndex);
					}
				}
				xmlRequest.open('GET', requestUrl, true);
				xmlRequest.send(null);
			}
			else {
				ModulePageImageDisplayImage(imageIndex);
			}
		}
	}

	return;
} /* )>>> */

function ModulePageImageCreateImage(xmlRequest, imageIndex) { /* <<<( */

	var response = null;
	var container = null;
	var image = null;
	var altText = '';
	var filename = '';
	var description = '';
	var parentContainer = null;
	var descriptionContainer = null;
	var imageId = 0;
	var currChild = null;
	var newNode = null;

	// check that response was received
	if (null != xmlRequest.responseXML) {

		// get response
		response = xmlRequest.responseXML.documentElement;

		// check that the response was a success
		if ((null != response.getElementsByTagName('message')) &&
			('success' == response.getElementsByTagName('message')[0].getAttribute('type')))
		{
			// create image
			if ((0 < response.getElementsByTagName('alt-text').length) &&
				(0 < response.getElementsByTagName('alt-text')[0].childNodes.length))
			{
				altText = response.getElementsByTagName('alt-text')[0].childNodes[0].nodeValue;
			}
			if ((0 < response.getElementsByTagName('image').length) &&
				(0 < response.getElementsByTagName('image')[0].childNodes.length))
			{
				filename = response.getElementsByTagName('image')[0].childNodes[0].nodeValue;
			}
			if ((0 < response.getElementsByTagName('description').length) &&
				(0 < response.getElementsByTagName('description')[0].childNodes.length))
			{
				description = response.getElementsByTagName('description')[0].childNodes[0].nodeValue;
			}

			parentContainer = document.getElementById('module-page-image-container');
			if (null != parentContainer) {

				container = document.createElement('div');
				container.id = 'module-page-image-image-container-' + imageIndex;
				container.className = 'module-page-image-image-container';
				container.style.opacity = '0';
				container.style.filter = 'alpha(opacity = 0)';
				container.style.display = 'none';
				container = parentContainer.appendChild(container);

				image = document.createElement('img');
				image.className = 'module-page-image-image';
				image.src = filename;
				image.alt = altText;
				image = container.appendChild(image);

				descriptionContainer = document.createElement('div');
				descriptionContainer.id = 'module-page-image-description-container-' + imageIndex;
				descriptionContainer.className = 'module-page-image-description-container';
				descriptionContainer.style.opacity = '0';
				descriptionContainer.style.filter = 'alpha(opacity = 0)';
				descriptionContainer = parentContainer.appendChild(descriptionContainer);

				// copy each child node into the container
				for (var currChild = 0; response.getElementsByTagName('description')[0].childNodes.length > currChild; currChild++) {

					// get reference to current child for improved readability
					childNode = response.getElementsByTagName('description')[0].childNodes[currChild];

					// copy node
					newNode = ModulePageImageCopyNode(childNode, true);
					
					// if copy succeeded, append to container
					if (null != newNode) {
						descriptionContainer.appendChild(newNode);
					}
				}

				// add image to array
				g_modulePageImages[imageIndex - 1] = imageIndex;
			}
		}
		else {
			// failure
			alert("Sorry, the image could not be\n loaded from the server.\nPlease refresh the page and try again.");
		}
	}

	return;
} /* )>>> */

function ModulePageImageDisplayImage(imageIndex) { /* <<<( */

	var previousImageId = 'module-page-image-image-container-' + g_modulePageImages[g_modulePageImageCurrentImage - 1];
	var previousDescriptionId = 'module-page-image-description-container-' + g_modulePageImages[g_modulePageImageCurrentImage - 1];
	var nextImageId = 'module-page-image-image-container-' + g_modulePageImages[imageIndex - 1];
	var nextDescriptionId = 'module-page-image-description-container-' + g_modulePageImages[imageIndex - 1];
	var filename = '';

	// check that image exists
	if ((null != document.getElementById(nextImageId)) && (null != document.getElementById(nextDescriptionId))) {

		// update current image index
		g_modulePageImageCurrentImage = imageIndex;

		// set background to fade to
		filename = document.getElementById(nextImageId).getElementsByTagName('img')[0].src;
		document.getElementById('module-page-image-container').style.backgroundImage = 'url(\'' + filename + '\')';
		document.getElementById('module-page-image-container').style.backgroundRepeat = 'no-repeat';

		// hide current text
		setTimeout(function() {
			ModulePageImageFadeOut(previousDescriptionId, function() {
					ModulePageImageFadeIn(nextDescriptionId, function() {
							g_modulePageImageTransition = false;
						});
				});
			}, 200);

		// hide old image
		setTimeout(function() {
				ModulePageImageFadeOut(previousImageId, ModulePageImageCurrentImageDisplay);
			}, 500);

		// set next rotation
		if (true == g_modulePageImageRotate) {
			g_hdlModulePageImageRotateTimeout = setTimeout(ModulePageImageRotateNext, MODULE_PAGE_IMAGE_ROTATE_TIMEOUT);
		}
	}

	return;
} /* )>>> */

function ModulePageImageGetXmlRequest() { /* <<<( */

	var obj_xml_request = null;

	// firefox, Opera, Safari
	try {
		obj_xml_request = new XMLHttpRequest();
	}
	catch (e) {

		// Internet Explorer
		try {
			obj_xml_request = new ActiveXObject('Msxml2.XMLHTTP');
		}
		catch (e) {

			// Internet Explorer (alternative)
			try {
				obj_xml_request = new ActiveXObject('Microsoft.XMLHTTP');
			}
			catch (e) {
				alert('Sorry, your browser does not support AJAX.');
			}
		}
	}

	return obj_xml_request;
} /* )>>> */

function ModulePageImageFadeOut(elementId, callback) { /* <<<( */

	// get DOM reference to element
	var element = document.getElementById(elementId);

	// check that element was given
	if (null != element) {

		// check if element has not been faded or is opaque
		if ((null == element.fadeState) || (MODULE_PAGE_IMAGE_FADE_OPAQUE_FULL == element.fadeState)) {

			// if not, element is opaque
			element.fadeState = MODULE_PAGE_IMAGE_FADE_OPAQUE_TO_TRANSPARENT;
			element.fadeTimeLeft = MODULE_PAGE_IMAGE_FADE_TIMEOUT;
		}

		// check if element is fading in
		if (MODULE_PAGE_IMAGE_FADE_TRANSPARENT_TO_OPAQUE == element.fadeState) {

			// if so, switch the fade state and adjust the fade timeout
			element.fadeState = MODULE_PAGE_IMAGE_FADE_OPAQUE_TO_TRANSPARENT;
			element.fadeTimeLeft = MODULE_PAGE_IMAGE_FADE_TIMEOUT - element.fadeTimeLeft;
		}

		// check that element is not fully transparent
		if (MODULE_PAGE_IMAGE_FADE_TRANSPARENT_FULL != element.fadeState) {

			// start fade cycle
			setTimeout(function() {
					ModulePageImageFadeOutAnimate(new Date().getTime(), elementId, callback);
				}, 33);
		}
	}

	return;
} /* )>>> */

function ModulePageImageFadeOutAnimate(lastTick, elementId, callback) { /* <<<( */

	var currTick = new Date().getTime();
	var elapsedTicks = currTick - lastTick;
	var element = document.getElementById(elementId);
	var newOpacityValue = 0;

	if (null != element) {

		// check that element is fading out
		if (MODULE_PAGE_IMAGE_FADE_OPAQUE_TO_TRANSPARENT != element.fadeState) {
			// if not, call fade out setup
			ModulePageImageFadeOut(elementId);
		}
		else {

			// check if no time is left to fade
			if (elapsedTicks >= element.fadeTimeLeft) {

				// update opacity and fade state
				element.style.opacity = '0';
				element.style.filter = 'alpha(opacity = 0)';
				element.fadeTimeLeft = 0;
				element.fadeState = MODULE_PAGE_IMAGE_FADE_TRANSPARENT_FULL;
				element.style.display = 'none';
				if (null != callback) {
					callback();
				}
			}
			else {
				// there is time left, fade accordingly
				element.fadeTimeLeft -= elapsedTicks;

				// get new opacity value
				newOpacityValue = element.fadeTimeLeft / MODULE_PAGE_IMAGE_FADE_TIMEOUT;

				// update opacity and fade state
				element.style.opacity = newOpacityValue;
				element.style.filter = 'alpha(opacity = ' + (newOpacityValue * 100) + ')';

				// begin next fade state
				setTimeout(function() {
						ModulePageImageFadeOutAnimate(currTick, elementId, callback);
					}, 33);
			}
		}
	}

	return;
} /* )>>> */

function ModulePageImageFadeIn(elementId, callback) { /* <<<( */

	// get DOM reference to element
	var element = document.getElementById(elementId);

	// check that element was given
	if (null != element) {

		// check if element has not been faded or is transparent
		if ((null == element.fadeState) || (MODULE_PAGE_IMAGE_FADE_TRANSPARENT_FULL == element.fadeState)) {

			// if not, assume element is transparent
			element.fadeState = MODULE_PAGE_IMAGE_FADE_TRANSPARENT_TO_OPAQUE;
			element.fadeTimeLeft = MODULE_PAGE_IMAGE_FADE_TIMEOUT;
			element.style.opacity = '0';
			element.style.filter = 'alpha(opacity = 0)';
			element.style.display = 'block';
		}

		// check if element is fading out
		if (MODULE_PAGE_IMAGE_FADE_OPAQUE_TO_TRANSPARENT == element.fadeState) {

			// if so, switch the fade state and adjust the fade timeout
			element.fadeState = MODULE_PAGE_IMAGE_FADE_TRANSPARENT_TO_OPAQUE;
			element.fadeTimeLeft = MODULE_PAGE_IMAGE_FADE_TIMEOUT - element.fadeTimeLeft;
		}

		// check that element is not fully opaque
		if (MODULE_PAGE_IMAGE_FADE_OPAQUE_FULL != element.fadeState) {

			// start fade cycle
			setTimeout(function() {
					ModulePageImageFadeInAnimate(new Date().getTime(), elementId, callback);
				}, 33);
		}
	}

	return;
} /* )>>> */

function ModulePageImageFadeInAnimate(lastTick, elementId, callback) { /* <<<( */

	var currTick = new Date().getTime();
	var elapsedTicks = currTick - lastTick;
	var element = document.getElementById(elementId);
	var newOpacityValue = 0;

	if (null != element) {

		// check that element is fading in
		if (MODULE_PAGE_IMAGE_FADE_TRANSPARENT_TO_OPAQUE != element.fadeState) {
			// if not, call fade in setup
			ModulePageImageFadeIn(elementId);
		}
		else {

			// check if no time is left to fade
			if (elapsedTicks >= element.fadeTimeLeft) {

				// update opacity and fade state
				element.style.opacity = '1';
				element.style.filter = 'alpha(opacity = 100)';
				element.fadeTimeLeft = 0;
				element.fadeState = MODULE_PAGE_IMAGE_FADE_OPAQUE_FULL;
				if (null != callback) {
					callback();
				}
			}
			else {
				// there is time left, fade accordingly
				element.fadeTimeLeft -= elapsedTicks;

				// get new opacity value
				newOpacityValue = 1 - (element.fadeTimeLeft / MODULE_PAGE_IMAGE_FADE_TIMEOUT);

				// update opacity and fade state
				element.style.opacity = newOpacityValue;
				element.style.filter = 'alpha(opacity = ' + (newOpacityValue * 100) + ')';

				// begin next fade state
				setTimeout(function() {
						ModulePageImageFadeInAnimate(currTick, elementId, callback);
					}, 33);
			}
		}
	}

	return;
} /* )>>> */

	function ModulePageImageCurrentImageDisplay() { /* <<<( */

		var imageId = 'module-page-image-image-container-' + g_modulePageImages[g_modulePageImageCurrentImage - 1];

		document.getElementById(imageId).style.opacity = '1';
		document.getElementById(imageId).style.filter = 'alpha(opacity = 100)';
		document.getElementById(imageId).style.display = 'block';
		document.getElementById(imageId).fadeState = MODULE_PAGE_IMAGE_FADE_OPAQUE_FULL;

		return;
	} /* )>>> */

function ModulePageImageRotateStop() { /* <<<( */

	g_modulePageImageRotate = false;

	// clear timeout to stop the rotation
	if (null != g_hdlModulePageImageRotateTimeout) {
		clearTimeout(g_hdlModulePageImageRotateTimeout);
		g_hdlModulePageImageRotateTimeout = null;
	}

	return;
} /* )>>> */

function ModulePageImageRotateNext() { /* <<<( */

	var nextImage = g_modulePageImageCurrentImage + 1;

	// clear timeout in the event that subsequent calls were made to this function
	if (null != g_hdlModulePageImageRotateTimeout) {
		clearTimeout(g_hdlModulePageImageRotateTimeout);
		g_hdlModulePageImageRotateTimeout = null;
	}

	// check if at the end of the image list
	if (g_modulePageImageCount < nextImage) {
		// if so, loop to beginning
		nextImage = 1;
	}

	// load next image
	ModulePageImageLoadImage(nextImage);

	return;
} /* )>>> */

function ModulePageImageRotatePrev() { /* <<<( */

	var prevImage = g_modulePageImageCurrentImage - 1;

	// clear timeout in the event that subsequent calls were made to this function
	if (null != g_hdlModulePageImageRotateTimeout) {
		clearTimeout(g_hdlModulePageImageRotateTimeout);
		g_hdlModulePageImageRotateTimeout = null;
	}

	// check if at the beginning of the image list
	if (1 > prevImage) {
		// if so, loop to end
		prevImage = g_modulePageImageCount;
	}

	// load next image
	ModulePageImageLoadImage(prevImage);

	return;
} /* )>>> */

function ModulePageImageRotateToggle() { /* <<<( */

	var playPauseButton = document.getElementById('module-page-image-control-play-pause');

	if (null != playPauseButton) {

		// check status to determine action
		if ((null == playPauseButton.getAttribute('isPlay')) || ('false' == playPauseButton.getAttribute('isPlay'))) {
			// currently set to pause, change to play
			playPauseButton.setAttribute('isPlay', 'true');
			playPauseButton.className = 'module-page-image-control-play';
			ModulePageImageRotateStop();
		}
		else {
			// currently set to play, change to pause
			playPauseButton.setAttribute('isPlay', 'false');
			playPauseButton.className = 'module-page-image-control-pause';
			ModulePageImageRotateStart();
		}
	}

	return;
} /* )>>> */

function ModulePageImageCopyNode(copyNode, isDeepCopy) { /* <<<( */

	var newNode = null;
	var childNode = null;

	if (null != copyNode) {

		if (1 == copyNode.nodeType) { // element

			newNode = document.createElement(copyNode.tagName.toLowerCase());

			if ('' != copyNode.getAttribute('id')) {
				newNode.setAttribute('id', copyNode.getAttribute('id'));
			}
			if ('' != copyNode.getAttribute('name')) {
				newNode.setAttribute('name', copyNode.getAttribute('name'));
			}
			if ('' != copyNode.getAttribute('alt')) {
				newNode.setAttribute('alt', copyNode.getAttribute('alt'));
			}
			if ('' != copyNode.getAttribute('title')) {
				newNode.setAttribute('title', copyNode.getAttribute('title'));
			}
			if ('' != copyNode.getAttribute('href')) {
				newNode.setAttribute('href', copyNode.getAttribute('href'));
			}
			if ('' != copyNode.getAttribute('src')) {
				newNode.setAttribute('src', copyNode.getAttribute('src'));
			}
			if ('' != copyNode.getAttribute('className')) {
				newNode.setAttribute('className', copyNode.getAttribute('className'));
			}
			if ('' != copyNode.getAttribute('style')) {
				newNode.setAttribute('style', copyNode.getAttribute('style'));
			}
		}
		else if (3 == copyNode.nodeType) { // text

			newNode = document.createTextNode(copyNode.nodeValue);
		}
		else {
			newNode = null;
			childNode = null;
		}

		if (true == isDeepCopy) {
			for (var index = 0; copyNode.childNodes.length > index; index++) {
				childNode = ModulePageImageCopyNode(copyNode.childNodes[index], true);
				if (null != childNode) {
					newNode.appendChild(childNode);
				}
			}
		}
	}

	return newNode;
} /* )>>> */

// start the rotation when the window loads
if (null == window.onload) {

	window.onload = function() {
		g_hdlModulePageImageRotateTimeout = setTimeout(ModulePageImageRotateStart, 5000);
	}
}
else {
	var currFunction = window.onload;
	window.onload = function() {
		currFunction();
		g_hdlModulePageImageRotateTimeout = setTimeout(ModulePageImageRotateStart, 5000);
	}
}

