/*
		File:			ProductHelper class
		Version:	2.8
		Desc:			This class handles common tasks on product thumbnail and detail pages.
		Requires:	/pages/v4/script/dhtml_lib.js
		Use:			If you need standard functionality, just add this to your page:
			
							EventHelper.AddEvent(window, 'load', ProductHelper.AutoInit, false);
							
							For more robust functionality, you can extend this class in a site-specific 
							script file taking advantage of prototype-based inheritance:
							
								ProductHelper.prototype.newOrExtendedFunction = function() {
									function goes here
								}
								
							Then initialize the ProductHelper, which will use your new function also:
								
								var fisherprice_sitename_ph = new ProductHelper();
								EventHelper.AddEvent(window, 'load', fisherprice_sitename_init, false);
								function fisherprice_sitename_init() {	
									fisherprice_sitename_ph.init();
								}
								
		Author:		Eric Shepherd
		Date:			April 2006
		Methods:	The following methods are in this class.
		
							AutoInit()
								Static setup member for generic functionality
									
							init()
								Setup and event listeners
														
							addLinkElements()
								Adds product link to images in a list of thumbnails
									
							swapImages(element, class reference, event)
								Switches out large image and caption text, calling child functions
								
							replaceText(element, string text)
								Replaces text in a given element using innerHTML
								
							replaceMedia(element, path, string mediatype)
								Replaces media - calls child functions depending on context
								
							getIndex(string path)
								Gets an image index out of an image href
								
							getProductNumber(string path)
								Gets a product number out of an image href
								
							setLargerImageHref(image index)
								Updates the href on the View Larger link if present
								
							renderFlashProductShot(product number, image index, element)
								Performs a switch of a Flash movie in a product shot context
								
							renderProductShot(path, element)
								Performs a switch of a product shot
																	
			Version History:
				
				0.9		Class began with addLinkElements function alone.
				1.0		Initial release (init, addLinkElements, activateElement, deactivateElement, swapImages).
				1.2		Added spawnHovers to duplicate hover behavior on related elements.
				1.3		Moved spawnHovers to dhtml_lib.js.
				1.5		Created replaceText and replaceMedia methods which are called by swapImages.
				2.0a	Adds switch statement to replaceMedia to handle Flash content in product pages - currently building.
				2.0b	TCW	replaceText now replaces the innerHTML rather than just the first node, b/c there could be other html inside that would get ignored.
				2.1		EBS		Added AutoInit static member so that class does not have to be instantiated on the page level.
				2.5		EBS		Added setter methods and changed variable names, eliminated deactivateElement and activateElement in favor of dhtml_lib generic functions.
				2.6		EBS		Changed replaceMedia method to create a new image and wait for it to load before placing into the DOM. This is so we don't see large images loading.
							progressively, and instead we can place a loading animation image behind the image while it loads.
				2.7		EBS		Added element property so that the ProductHelper knows what part of the current document it is supposed to act upon.
				2.8		EBS		Split replaceMedia() into several smaller methods so that custom overriding will be easier; overhauled documentation.
*/

function ProductHelper(element) {
			// element that this instance is affecting
	this._element = element ? element : document.getElementById('product-media');
			// variables used in addLinkElements function
	this._thumbThumbnailClassString = 'product';
	this._thumbThumbnailClass = /product/;
	this._thumbImageClass = /product-image/;
	this._thumbThumbnailContainer = 'dl';
	this._thumbProductNameElement = 'dt';
	this._thumbProductDescriptionElement = 'dd';
			// variables used in init function and product page thumbnails
	this._prodThumbnailContainer = 'product-thumbnails';
	this._prodThumbnailElements = 'li';
	this._prodThumbnailLinks = 'a';
	this._activeClass = 'active';
	this._activeRegexp = /active/;
	this._productShotId = 'product-shot';
	this._productShotImageContainer = 'dt';
	this._productShotCaptionContainer = 'dd';
	this._initialImageIndex = 0;
			// storage variable
	this._storage = '';
}

ProductHelper.prototype.setThumbThumbnailClassString = function(value) {
	this._thumbThumbnailClassString = value;
}

ProductHelper.prototype.setThumbThumbnailClass = function(value) {
	this._thumbThumbnailClass = value;
}

ProductHelper.prototype.setThumbImageClass = function(value) {
	this._thumbImageClass = value;
}

ProductHelper.prototype.setThumbThumbnailContainer = function(value) {
	this._thumbThumbnailContainer = value;
}

ProductHelper.prototype.setThumbProductNameElement = function(value) {
	this._thumbProductNameElement = value;
}

ProductHelper.prototype.setThumbProductDescriptionElement = function(value) {
	this._thumbProductDescriptionElement = value;
}

ProductHelper.prototype.setProdThumbnailContainer = function(value) {
	this._prodThumbnailContainer = value;
}

ProductHelper.prototype.setProdThumbnailElements = function(value) {
	this._prodThumbnailElements = value;
}

ProductHelper.prototype.setProdThumbnailLinks = function(value) {
	this._prodThumbnailLinks = value;
}

ProductHelper.prototype.setActiveClass = function(value) {
	this._activeClass = value;
}

ProductHelper.prototype.setActiveRegexp = function(value) {
	this._activeRegexp = value;
}

ProductHelper.prototype.setProductShotId = function(value) {
	this._productShotId = value;
}

ProductHelper.prototype.setProductShotImageContainer = function(value) {
	this._productShotImageContainer = value;
}

ProductHelper.prototype.setProductShotCaptionContainer = function(value) {
	this._productShotCaptionContainer = value;
}

ProductHelper.prototype.setInitialImageIndex = function(value) {
	this._initialImageIndex = value;
}



// Property: inactiveLink
// Used for storage of currently selected thumbnail link and image
ProductHelper.inactiveLink = new Array();



// Function: AutoInit()
// Static method, auto-initializes the class for default behavior
// Call this from the page if no custom functionality is needed
// Returns:
// 	void
ProductHelper.AutoInit = function()
{
	if (!SupportTest.hasDom) return;
	var element = document.getElementById('product-media');
	if (typeof element != 'undefined') {
		var _ProductHelper = new ProductHelper(element);
		_ProductHelper.init();
	}
}



// Function: init()
// Initializes the event listeners, runs the addLinkElements function, 
// removes link from initial thumbnail on product page
// Returns:
// 	void
ProductHelper.prototype.init = function()
{ 
			// return if no dom support
	if (!SupportTest.hasDom) return;
			// run function to add links to thumbnail page images
	this.addLinkElements();
			// get the thumbnail box (container with the 60 product images on the product page)
	var theThumbnailContainer = document.getElementById(this._prodThumbnailContainer);
	if (theThumbnailContainer) {
				// get the individual thumb boxes and links
		var theEls = theThumbnailContainer.getElementsByTagName(this._prodThumbnailElements);
		var theLinks = theThumbnailContainer.getElementsByTagName(this._prodThumbnailLinks);
		theEl = theEls[this._initialImageIndex];
				// add event listener to swap larger images when thumbnails are clicked
		for (var i=0; i<theLinks.length; i++) {
			var thisReference = this; // required because scope will change from class to event
			EventHelper.AddEvent(theLinks[i], 'click', swapPtr = function(e) {thisReference.swapImages(this, thisReference, e); }, false);
			if (SupportTest.isSafari) theLinks[i].onclick = EventHelper.CancelClickSafari; //safari still doesn't support cancelDefault()
		}
				// call method to swap active and inactive thumbnails - we do this at init to remove link from first thumbnail		
		DomHelper.AddClassName(theEl, this._activeClass);
	}
}



// Function: addLinkElements()
// Adds a dynamic <a> tag to the image in a list of product thumbnails.
// This allows us to code the link only on the product name where it belongs.
// Returns:
// 	void
ProductHelper.prototype.addLinkElements = function()
{
	if (!SupportTest.hasDom) return; 
			// first, we get an array with all the <...class="product"> elements referenced
	var theThumbnailArray = DomHelper.GetElementsByClassName(this._thumbThumbnailClassString, this._thumbThumbnailContainer);

	var theProductName; // individual product name container (dt by default)
	var theProductDescriptions; // all the product description elements (dd by default)
	var theProductLink; // the link in the product name (a is assumed)
	var theProductHref; // the href of that link
	var theNewLink; // the new link to be inserted in the product image container (dd by default)
			// cycle through all the product thumbnail containers (dl's by default)
			// get the product name container (dt) and all the descriptions (dd) underneath
	for (var j=0; j<theThumbnailArray.length; j++) {
		theProductName = theThumbnailArray[j].getElementsByTagName(this._thumbProductNameElement)[0];
		theProductDescriptions = theThumbnailArray[j].getElementsByTagName(this._thumbProductDescriptionElement);
				// get the product <a> element and href
		theProductLink = theProductName.getElementsByTagName('a')[0];
		theProductHref = theProductLink.href;
				// cycle through all the descriptions (dd) in each product container (dl by default)
				// there could be many definitions (price, ages, etc) in addition to image
		for (var k=0; k<theProductDescriptions.length; k++) {
			if (theProductDescriptions[k].className.match(this._thumbImageClass)) {
						// get the image if it's an image container
				var theImg = theProductDescriptions[k].getElementsByTagName('img')[0];
						// create a new <a> element node with the href of the product
						// and append the image to this <a> node
				theNewLink = document.createElement('a');
				theNewLink.href = theProductHref;
				theNewLink.appendChild(theImg);
						// insert the new <a> tag containing the image into the image container
				theProductDescriptions[k].appendChild(theNewLink);
			}
		}
		DomHelper.SpawnHovers(theProductLink, theNewLink);
	}
}



// Function: swapImages()
// Called on click of image thumbnails, this switches out the large image and caption text
// Parameters:
// 	el - the link that was clicked
// 	thisReference - the class
// 	e - the event
// Returns:
// 	void
ProductHelper.prototype.swapImages = function(el, thisReference, e) 
{
				// set new active class and call function to switch active thumbnails
	var activeEl = DomHelper.AscendDom(el, this._prodThumbnailElements);

	if (!activeEl.className.match(this._activeRegexp)) {		
				// set variables for this image click
		var theLink = el.href;
		var theMediaTypes = el.className.match(/mt_\w+/);
		var theMediaType = theMediaTypes != null ? theMediaTypes[0] : null;
		var theThumbnailContainer = document.getElementById(this._prodThumbnailContainer);
		var theThumbnailElements = theThumbnailContainer.getElementsByTagName(this._prodThumbnailElements);
		
		
				// restore previous inactive link from class variable to the (previously) active container element (li by default)
		for (i=0; i<theThumbnailElements.length; i++) {
			if (theThumbnailElements[i].className.match(this._activeRegexp)) {
				DomHelper.RemoveClassName(theThumbnailElements[i], this._activeClass);
			}
		}
		
		DomHelper.AddClassName(activeEl, this._activeClass);
		
				// switch image and caption - first, get references, then call methods
		var theShot = document.getElementById(this._productShotId); // dl by default
		var theImageParent = theShot.getElementsByTagName(this._productShotImageContainer)[0]; // dt of image by default
		var theCaptionEl = theShot.getElementsByTagName(this._productShotCaptionContainer)[0]; // dd of caption by default
		var theNewCaption = el.title.replace('\\','');	
				// replace text and media
		this.replaceText(theCaptionEl, theNewCaption);
		this.replaceMedia(theImageParent, theLink, theMediaType, el); // replace function swaps in image or flash movie
				// cancel default action
	}
	
	EventHelper.CancelDefault(e);
}



// Function: replaceText()
// Replaces text in a given element
// Parameters:
// 	el - the element in which to replace text
// 	text - the string of text to place in the element
// Returns:
// 	void
ProductHelper.prototype.replaceText = function(el, text)
{
	el.innerHTML = text;
}



// Function: replaceMedia()
// The parent function for an image swap - directs traffic to Flash or image replace depending on context
// Parameters:
// 	el - the element in which to place the new media
// 	href - the href of the newly selected media
// 	mediatype - the flag to determine what kind of switch we are doing
// Returns:
// 	void
ProductHelper.prototype.replaceMedia = function(el, href, mediatype, linkElement)
{
	var index = this.getIndex(href);
	var productnumber = this.getProductNumber(href);

	this.setLargerImageHref(index);	

			// switch based on media type - default is an image
	if ((mediatype == null) || ((typeof UFO != 'object') && (typeof swfobject != 'object')) ) mediatype = 'default';
			//alert(mediatype);
	switch(mediatype) {

		case 'mt_productshotdemo' : 
			this.renderFlashProductShot(productnumber, index, el, linkElement);
			break;
			
		//case 'mt_filedemo' :
				//filename = filename.replace('.jpg', '.swf');
				//tempMovie = movieDemo.movie;
				//movieDemo.movie = moviePath + productnumber + '_' + index + '.swf';
				//UFO.create(movieDemo, el.id);
				//var timer = setInterval(function() {
					//movieDemo.movie = tempMovie;
					//clearInterval(timer);
				//}, 1000);
			//break;
			
		default : 
			this.renderProductShot(href, el);
			break;
	}
}



// Function: getIndex()
// Gets the image index out of a Fisher-Price image href
// Assumes path/to/image/[productnumber]_[type]_[index].jpg
// Parameters:
// 	href - the path to parse for the image index
// Returns:
// 	the image index
ProductHelper.prototype.getIndex = function(href)
{
	var pathparts = href.split('/');
	var filename = pathparts[pathparts.length-1];
	var fileparts = filename.split(/[-_]/);
	var last = fileparts[fileparts.length-1];
	var dots = last.split('.');
	return dots[0];
}



// Function: getProductNumber()
// Gets the product number out of a Fisher-Price image href
// Assumes path/to/image/[productnumber]_[type]_[index].jpg
// Parameters:
// 	href - the path to parse for the product number
// Returns:
// 	the product number
ProductHelper.prototype.getProductNumber = function(href) 
{
	var pathparts = href.split('/');
	var filename = pathparts[pathparts.length - 1];
	var fileparts = filename.split(/[-_]/);
	return fileparts[0];
}



// Function: setLargerImageHref()
// Sets the larger image's new href on a swap of the product images
// Parameters:
// 	index - the newly clicked image's href
// Returns:
// 	void
ProductHelper.prototype.setLargerImageHref = function(index) 
{
	var theLargerLinks = DomHelper.GetElementsByClassName('product-view-larger', this._productShotCaptionContainer, this._element);
	if (theLargerLinks.length > 0) {
		var theLink = theLargerLinks[0].getElementsByTagName('a')[0];
		var theHref = theLink.getAttribute('href');
		theHref = theHref.replace(/image=\w*/, 'image=' + index);
		theLink.setAttribute('href', theHref);
	}
}



// Function: renderFlashProductShot()
// Performs a switch of a Flash movie for a product shot
// Parameters:
// 	productnumber - the current product's number for use in the Flash paths
// 	index - the newly selected image index
// 	el - the element in which to place the Flash movie
// Returns:
// 	void
ProductHelper.prototype.renderFlashProductShot = function(productnumber, index, el, linkElement)
{
	//movieDemo.flashvars = 'audioPath=/content/v4/us/audio/&imgPath=/img/product_shots/&pn='+productnumber+'&index='+index+'';
	// TODO: get the US out of there...
	//UFO.create(movieDemo, el.id);
	
	// flashImage - a public variable defined on the page. e.g. \pages\v4\default\imaginext\dinosaurs\product.aspx
	if(typeof UFO == 'object'){
		flashImage.movie = linkElement.rel;
		UFO.create(flashImage, el.id);
	}
	if(typeof swfobject == 'object'){
		flashImage.flashArgs.swfUrl = linkElement.rel;
		swfobject.embedSWF(
				flashImage.flashArgs.swfUrl,
				flashImage.flashArgs.id, 
				flashImage.flashArgs.width, 
				flashImage.flashArgs.height, 
				flashImage.flashArgs.version, 
				flashImage.flashArgs.expressInstallSwfUrl, 
				flashImage.flashVars, 
				flashImage.flashParams, 
				flashImage.flashAttrs
			);
	}
}



// Function: renderProductShot()
// Renders a standard product shot switch on a product page
// Parameters:
// 	href - the path of the newly selected product image
// 	el - the element in which to place the newly selected larger image
// Returns:
// 	void
ProductHelper.prototype.renderProductShot = function(href, el)
{
	var theImage = document.createElement('img');
	var tmp = new Date();
	var suffix = tmp.getTime();
	theImage.src = href +'?' + suffix;
	
	var theSpan = document.createElement('span');
	theSpan.id = 'product-image-flash';
	theSpan.style.visibility = "visible";
	theSpan.appendChild(theImage);
	
	var theChildren = el.childNodes;
	try {
		var c = el.removeChild(theChildren[0]);
	} catch (e) {
			// the exception is thrown when clicks happen too fast, so we catch it.
			// TODO: this still causes the wrong image to be highlighted if the clicks happen too fast, but at least the page doesn't blow up.
	}
	imageAppended = false;
			// fallback for ie, which borks the load event sometimes
			// warning - ie only does this because of a scope error, which is why it's conditionally set
	if (SupportTest.isIE) {
		var imageLoaded = setInterval(appendImage, 1000);
	
		function appendImage() {
			if (imageAppended == false) {
				el.appendChild(theSpan);
				imageAppended = true;
				clearInterval(imageLoaded);
			}
		}
	}
			// onload event for image to show - for all nice browsers
	theImage.onload = function() {
		if (imageAppended == false) {
			el.appendChild(theSpan);
			imageAppended = true;
					// clear the interval just in case ie had to use it, but it only exists for ie
			if (SupportTest.isIE) {
				clearInterval(imageLoaded);
			}
		}
	}
}



/* DEPRECATED!!! */
/* Please use DomHelper functions in dhtml_lib.js */
ProductHelper.prototype.popup = function(u, n, w, h, e) { var win = window.open(u,n,'scrollbars, resizable, toolbar=no, width='+w+',height='+h); EventHelper.CancelDefault(e); } 
ProductHelper.prototype.newWin = function(e) { var win = window.open(this.href, 'popup', 'location=no,scrollbars,menubar,resizable,toolbar=no'); EventHelper.CancelDefault(e); }
