/***************************************************************************
 * gallery.js
 *     :
 ***************************************************************************/

/***************************************************************************
 * class ModuleGallery
 ***************************************************************************/
function ModuleGallery()
{
// Ensure this function is only called as a constructor.
	if (!(this instanceof ModuleGallery))
	{	return new ModuleGallery();	}
	return this;
}

// Inherit from class Object.
ModuleGallery.prototype = new Object();

// TODO: Move this.
ModuleGallery.prototype.StopPropagation =
function(eventObj)
{
// IE -> W3C:
	if (typeof(window.event) != 'undefined')
	{	eventObj = window.event;	}
	if (eventObj.target == null)
	{	eventObj.target  = eventObj.srcElement;	}

// Cancel the event.
	if (typeof(event) != 'undefined')
	{	eventObj.cancelBubble = true;	}
	else
	{	eventObj.stopPropagation();		}
}

/***************************************************************************
 * ModuleGallery::InitNode
 ***************************************************************************/
ModuleGallery.prototype.InitNode =
function(domNode)
{
// Parameter validation:
	if (domNode == null)
	{	return false;	}

// Gather information.
	var codeStr = '; '+
	              'if (typeof(event) != \'undefined\') '+
	              '{ event.cancelBubble = true; } '+
	              'else '+
	              '{ event.stopPropagation(); }';

// Prevent mouse events from bubbling past this node.
// TODO: All events?
	if (domNode.attachEvent)
	{
		domNode.attachEvent('onclick'    ,ModuleGallery.prototype.StopPropagation);
		domNode.attachEvent('onmouseover',ModuleGallery.prototype.StopPropagation);
		domNode.attachEvent('onmouseout' ,ModuleGallery.prototype.StopPropagation);
	}
	else
	{
		domNode.addEventListener('click'    ,ModuleGallery.prototype.StopPropagation,false);
		domNode.addEventListener('mouseover',ModuleGallery.prototype.StopPropagation,false);
		domNode.addEventListener('mouseout' ,ModuleGallery.prototype.StopPropagation,false);
	}

// Initialize the children.
	ModuleGallery.prototype.__InitNode(domNode);
	return true;
}
ModuleGallery.prototype.__InitNode =
function(domNode)
{
// For each child...
	var  count = domNode.childNodes.length;
	var  i;
	for (i = 0; i < count; ++i)
	{
	// Alter clickable children so the click event stops there.
		var childNode = domNode.childNodes[i];
		switch (childNode.nodeName.toLowerCase())
		{
		case 'a' :
		// Alter the mouse events.
		// TODO: All events?
			if (childNode.attachEvent)
			{
				childNode.attachEvent('onclick'    ,ModuleGallery.prototype.StopPropagation);
				childNode.attachEvent('onmouseover',ModuleGallery.prototype.StopPropagation);
				childNode.attachEvent('onmouseout' ,ModuleGallery.prototype.StopPropagation);
			}
			else
			{
				childNode.addEventListener('click'    ,ModuleGallery.prototype.StopPropagation,false);
				childNode.addEventListener('mouseover',ModuleGallery.prototype.StopPropagation,false);
				childNode.addEventListener('mouseout' ,ModuleGallery.prototype.StopPropagation,false);
			}

		// Make the link open in a new window.
			childNode.setAttribute('target','_blank');
			break;
		}

	// Process the children.
		if (childNode.hasChildNodes())
		{	ModuleGallery.prototype.__InitNode(childNode);	}
	}
}

/***************************************************************************
 * ModuleGallery::OnMouseOver
 ***************************************************************************/
ModuleGallery.prototype.OnMouseOver =
function(eventObj,currentTarget,photoData)
{
// IE -> W3C:
	if (typeof(event) != 'undefined')
	{	eventObj = event;	}
	if (eventObj.target == null)
	{	eventObj.target         = eventObj.srcElement;	}
	if (eventObj.currentTarget == null)
	{	eventObj.currentTarget  = currentTarget;	}

// Highlight the node.
	if (eventObj.currentTarget.className == '')
	{	eventObj.currentTarget.className  = 'highlight';	}
}

/***************************************************************************
 * ModuleGallery::OnMouseOut
 ***************************************************************************/
ModuleGallery.prototype.OnMouseOut =
function(eventObj,currentTarget,photoData)
{
// IE -> W3C:
	if (typeof(event) != 'undefined')
	{	eventObj = event;	}
	if (eventObj.target == null)
	{	eventObj.target         = eventObj.srcElement;	}
	if (eventObj.currentTarget == null)
	{	eventObj.currentTarget  = currentTarget;	}

// Un-highlight the node.
	if (eventObj.currentTarget.className == 'highlight')
	{	eventObj.currentTarget.className  = '';	}
}

/***************************************************************************
 * ModuleGallery::OnClick
 ***************************************************************************/
ModuleGallery.prototype.OnClick =
function(eventObj,currentTarget,photoData)
{
// IE -> W3C:
	if (typeof(event) != 'undefined')
	{	eventObj = event;	}
	if (eventObj.target == null)
	{	eventObj.target         = eventObj.srcElement;	}
	if (eventObj.currentTarget == null)
	{	eventObj.currentTarget  = currentTarget;	}

// Open a link associated with the photo, or open the photo's URL.
	if (photoData['link'])
	{
		var target = photoData['linkTarget'];
		if (target == '_blank')
		{
		// Open the link in a new window.
			window.open(photoData['link']);
		}
		else if (target == '_self' ||
		         target == '') // TODO: Is this good? Maybe we can use the
		{                      //       page's default target instead?
		// Open the link in the current window.
			window.location.href = photoData['link'];
		}
		else
		{
		// Open the link in a specified frame.
		// TODO: Implement me.
		}
	}
	else if (photoData['photo']['url'])
	{
	// Open the photo in a new window.
		window.open(photoData['photo']['url'],
		            '',// TODO: 'ModuleGallery::Photo',
		            'resizable=yes,'+
		            'scrollbars=yes,'+
		            'width=' +(40+photoData['photo']['width' ])+','+
		            'height='+(30+photoData['photo']['height']));
	}
	else
	{
	// Do nothing.
	// TODO: This should never happen, but can we log it?
	}
}

/***************************************************************************
 * ModuleGallery::SlideshowPlay
 ***************************************************************************/
ModuleGallery.prototype.SlideshowPlay =
function(slideshowObj)
{
// Parameter validation:
	if (slideshowObj == null)
	{	return false;	}

// Gather information.
	var jsVar         = slideshowObj['var'          ];
	var slideshowRate = slideshowObj['slideshowRate'];
	var slideCount    = slideshowObj.length;

// Display the first photo.
	ModuleGallery.prototype.Slideshow_SetPhoto(slideshowObj,0);

// Set up a transition to the next slideshow photo.
	if (slideCount >= 2)
	{
	// Only start the clock if there are two or more photos to switch between.
		window.setInterval('ModuleGallery.prototype.Callback_SlideshowNext(\''+jsVar+'\');',
		                   slideshowRate);
	}
	return true;
}

/***************************************************************************
 * ModuleGallery::SlideshowNext
 ***************************************************************************/
ModuleGallery.prototype.Callback_SlideshowNext =
function(slideshowId)
{
// Parameter validation:
	if (slideshowId == '')
	{	return false;	}
	var slideshowObj = eval(slideshowId);
	ModuleGallery.prototype.SlideshowNext(slideshowObj);
}

ModuleGallery.prototype.SlideshowNext =
function(slideshowObj)
{
// Parameter validation:
	if (slideshowObj == null)
	{	return false;	}

// Gather information.
	var jsVar  = slideshowObj['var'];
	var curIdx = slideshowObj['cur'];
	var count  = slideshowObj.length;

// If the current index is invalid, use the "init" index value.
	if ((curIdx <  0) ||
		(curIdx >= (count - 1)))
	{	curIdx  = -1;	}

// Is there a "next" photo to display?
	if (count < 2)
	{	return false;	}

// Advance to the next photo.
	ModuleGallery.prototype.Slideshow_SetPhoto(slideshowObj,curIdx+1);
}

ModuleGallery.prototype.Slideshow_SetPhoto =
function(slideshowObj,idx)
{
// Parameter validation:
	if (slideshowObj == null)
	{	return false;	}

// Gather information.
	var jsVar        = slideshowObj['var'];
	var curIdx       = slideshowObj['cur'];
	var newPhotoObj  = jQuery('#'+jsVar+'_'+idx);
	var newPhotoNode = newPhotoObj[0];

// Determine if a cross fade is needed.
	if (curIdx == -1 ||
		curIdx == idx)
	{
	// Bring the photo to the front of the stack.
		newPhotoNode.parentNode.appendChild(newPhotoNode);

	// Initialize the style.
		newPhotoObj.show();
	}
	else
	{
	// Gather (more) information.
		var oldPhotoObj  = jQuery('#'+jsVar+'_'+curIdx);
		var oldPhotoNode = oldPhotoObj[0];

	// Move the old photo to the front of the stack.
	// Position the new photo directly behind the old photo.
		var parentNode = newPhotoNode.parentNode;
		parentNode.appendChild(oldPhotoNode);
		parentNode.insertBefore(newPhotoNode,oldPhotoNode);

	// Initialize the style.
		newPhotoObj.show();
		oldPhotoObj.show();

	// Fade the old photo out so the new photo is visible.
		var transitionRate = slideshowObj['transitionRate'];
		oldPhotoObj.fadeOut(transitionRate,function()
		{
		// Move the new photo to the top of the stack.
			parentNode.appendChild(newPhotoNode);
		});
	}

// Update the current photo.
	slideshowObj['cur'] = idx;
	return true;
}
