/* Handle variation selections and inventory handling */
var variationHandler = Class.create({
	reloadCallback: null,
	callbackContext: null,
	variationValueFields: null,
	symbolicVariationValueFields: null,
	availabilityInformation: null,
	availabilityInformationJSON: null,
	variationValues: null,
	selectedProduct: null,
	fixDisabledOptionFields: false,
	imagesForColors: null,
	
	/* Ctor */
	initialize: function(reloadCallback, callbackContext, availabilityInformation) {
		this.reloadCallback = reloadCallback;
		this.callbackContext = callbackContext;
		this.disabledOptionFieldFixCheck();
		this.initAvailabilityInformation(availabilityInformation);
		this.initVariationValues();
		var fitIcon = $('fitIcon');
		if (fitIcon) {
			var fitTab = $('passform');
			if (fitTab) {
				fitIcon.clickTabHandler = fitTab.tabHandler;
				fitIcon.onclick = function() {
					this.clickTabHandler.setTab('passform');
					return false;
				};
			}
		}
		this.reinit();
	},
	
	/* reinit variationHandler. Have to be done after selecting variant. Should be called
	   by reloadCallback function.
	*/
	reinit: function() {
		var that = this;
		
		var selProd = $('selectedProduct');
		if (selProd) {
			this.selectedProduct = selProd.value;
		} else {
			this.selectedProduct = null;
			selProd = null;
		}
		this.updateValuesWithAvailabilityInfos();
		
		$$('select.variationSelectionField').each(function(field) {
			field.variationHandler = that;
			field.onchange = that.selectVariationValue;
		});
		
		var colorSelectors = $$('.colorSelector.variantSelection a');
		var sizeSelectors = $$('.sizeSelector a');

		var imagesForColors = $F('imagesForColors');
		try {
			this.imagesForColors = eval(imagesForColors)[0];
		} catch (e) {
			this.imagesForColors = {};
		}
		// preload images
		for (color in this.imagesForColors) {
			var images = this.imagesForColors[color];
			images.normalImagePreloaded = new Image();
			images.normalImagePreloaded.src = images.image;
			images.backImagePreloaded = new Image();
			images.backImagePreloaded.src = images.imageBack;
			images.laydownImagePreloaded = new Image();
			images.laydownImagePreloaded.src = images.imageLaydown;
		} 

		this.symbolicVariationValueFields = [];
		colorSelectors.each(function(field) {
			field.variationHandler = that;
			that.symbolicVariationValueFields.push(field);
			field.observe('mouseover', that.colorMouseOverHandler);
			field.observe('mouseout', that.colorMouseOutHandler);
		});
		
		if (this.variationValues.get(Constants.catalog.colorVariantID) == null || this.variationValues.get(Constants.catalog.colorVariantID).size() == 0) {
			var selectedColorName = $('selectedColorName');
			if (selectedColorName) {
				selectedColorName.update('');
			}
		}
		
		sizeSelectors.each(function(field) {
			field.variationHandler = that;
			that.symbolicVariationValueFields.push(field);
		});

		this.symbolicVariationValueFields.each(function(field) {
			field.onclick = that.selectVariationValue;
		});
		
		var selectedProduct = this.getSelectedProduct();
		var productQuantity = $('productQuantity');
		if (productQuantity && selectedProduct) {
			var ats = selectedProduct.ats;
			if (ats != Constants.catalog.maxShownAvailableQuantity) {
				var options = productQuantity.options;
				var elToRem = new Array();
				for (var i = 0; i < options.length; i++) {
					if (options[i].value > ats) {
						elToRem.push($(options[i]));
					}
				}
				elToRem.each(function(el) {
					el.remove();
				});
			}
		}
		this.initIE6BadgePositionFix();
		initIE6HoverFix();
	},

	/* retrieve availability information provided by a JSON string */
	initAvailabilityInformation: function(availabilityInformation) {
		var availInfo = $(availabilityInformation);
		if (availInfo) {
			try {
				this.availabilityInformation = eval(availInfo.value)[0];
				this.availabilityInformationJSON = availInfo.value;
			} catch (ex) {
				this.availabilityInformation = {varAttrs:[],variants:{}};
				this.availabilityInformationJSON = '[{varAttrs:[],variants:{}}]';
			}
		}
	},
	
	/* provide available variation values as a easy-to-use hash */
	initVariationValues: function() {
		this.variationValues = $H();
		this.availabilityInformation.varAttrs.each(function(varAttrID) {
			var entry = $H();
			this.variationValues.set(varAttrID, entry);
		}.bind(this));
		for (prodID in this.availabilityInformation.variants) {
			var product = this.availabilityInformation.variants[prodID];
			for (varAttrID in product.varAttrs) {
				var value = product.varAttrs[varAttrID];
				var entry = this.variationValues.get(varAttrID);
				if (!entry) {
					entry = $H();
				}
				var valueEntry = entry.get(value.value);
				if (!valueEntry) {
					entry.set(value.value, value.displayValue);
				}
				this.variationValues.set(varAttrID, entry);
			}
		}
	},
	
	/* do we have to fix IE to handle disabled option fields */
	disabledOptionFieldFixCheck: function() {
		var ie = /msie\s(\d)/.test(navigator.userAgent.toLowerCase());
		if (ie) {
			var ieVersion = RegExp.$1;
			if (ieVersion < 8) {
				this.fixDisabledOptionFields = true;
			}
		}
	},
	
	/* handle disabled option fields with IE */
	fixIEOptionFields: function() {
		if (this.fixDisabledOptionFields) {
			var fields = $$('select.variationSelectionField option');
			if (fields) {
				fields.each(function(field) {
					if (field.disabled) {
						field.addClassName('disabledOptionIE');
					}
				});
			}
		}
	},
	
	initIE6BadgePositionFix: function() {
		if (evilBrowserInformation.isEvil && evilBrowserInformation.evilVersion < 7) {
			var image = $('normalImage');
			var badges = $$('#pt_productdetails .imageContainer .badges');
			if (badges.length > 0) {
				var offset = image.cumulativeOffset();
				badges.each(function(el) {
					el.setStyle({
						left: offset.left-200,
						top: offset.top
					});
				});
			}
		}
	},
	
	/* update rendered variation values and disable/mark unavailable and impossible combinations
	   using the information provided by the availability informations.
	*/
	updateValuesWithAvailabilityInfos: function() {
		var that = this;
		var selectedProduct = that.getSelectedProduct();
		this.variationValues.keys().each(function(varAttr) {
			var variationAttributeValues = that.variationValues.get(varAttr);

			var varAttrFields = $$('select.variationSelectionField option.var_' + varAttr);
			var varAttrSFields = $$('.varS_' + varAttr);

			// hide unavailable variation values
			that.disableUnavailableVarAttrFields(varAttrFields, varAttr, variationAttributeValues, 'var');
			that.disableUnavailableVarAttrFields(varAttrSFields, varAttr, variationAttributeValues, 'varS');
			
			// mark unavailable value selections
			if (selectedProduct && varAttr != Constants.catalog.colorVariantID) {
				that.markUnavailableSelections(varAttrFields, varAttr, variationAttributeValues, selectedProduct, 'var');
				that.markUnavailableSelections(varAttrSFields, varAttr, variationAttributeValues, selectedProduct, 'varS');
			}
		});
		this.fixIEOptionFields();
	},
	
	/* disable variation attributes that are unavailable (evaluated by availability information) */
	disableUnavailableVarAttrFields: function(varAttrFields, varAttr, variationAttributeValues, prefix) {
		var empty = true;
		var parentSelect = null;
		var parentKey = null;
		var parentLabel = null;
		if(varAttrFields[0]){
			parentSelect = varAttrFields[0].up();
			if(parentSelect && parentSelect.up('.value'))
				parentKey = parentSelect.up('.value').previous('.key');
			if(varAttrFields[0].up('.sizeSelector')){
				parentLabel = varAttrFields[0].up('.sizeSelector').previous('.labelVariationsSymbolic');
			}
		}
		
		varAttrFields.each(function(valueField) {
			var found = false;
			var keys = variationAttributeValues.keys();
			for (var i = 0; i < keys.length; i++) {
				var varVal = keys[i];
				if (prefix + '_' + varAttr + '_' + varVal == valueField.id) {
					found = true;
					empty = false;
					break;
				}
			}
			if (!found) {
				valueField.remove();
			}
		});
		if(empty){
			if(parentSelect)
				parentSelect.hide();
			if(parentKey)
				parentKey.hide();
			if(parentLabel)
				parentLabel.hide();
		}
	},
	
	/* mark impossible variation selections (evaluated by availability information) */
	markUnavailableSelections: function(varAttrFields, varAttr, variationAttributeValues, selectedProduct, prefix) {
		var that = this;
		varAttrFields.each(function(valueField) {
			var found = false;
			var value = null;
			var keys = variationAttributeValues.keys();
			for (var i = 0; i < keys.length; i++) {
				var varVal = keys[i];
				if (prefix + '_' + varAttr + '_' + varVal == valueField.id) {
					found = true;
					value = varVal;
					break;
				}
			}
			if (found) {
				if (!that.matchVariationValues(varAttr, selectedProduct, value)) {
					if (valueField.tagName == 'OPTION') {
						valueField.disabled = true;
						valueField.remove(); // we have to remove the option because the non-standard compliant (evil) browsers doesn't support disabled options.  
					} else if (valueField.tagName == 'TD') {
						valueField.addClassName('inactive');
						var links = valueField.select('a');
						links.each(function(link) {
							link.selectorDisabled = true;
						});
					} else if (valueField.tagName == 'A') {
						valueField.addClassName('inactive');
						valueField.selectorDisabled = true;
					}
				}
			}
		});
	},

	/* matchs the value to the selected product */
	matchVariationValues: function(varAttr, selectedProduct, value) {
		var expectedValues = $H();
		for (attribute in selectedProduct.varAttrs) {
			if (attribute != varAttr) {
				expectedValues.set(attribute, selectedProduct.varAttrs[attribute].value);
			} else {
				expectedValues.set(attribute, value);
			}
		}
		var found = false;
		for (productID in this.availabilityInformation.variants) {
			var product = this.availabilityInformation.variants[productID];
			var matches = 0;
			expectedValues.keys().each(function(attribute) {
				if (product.varAttrs[attribute].value == expectedValues.get(attribute)) {
					++matches;
				}
			});
			if (matches == expectedValues.size()) {
				found = true;
				break;
			}
		}
		return found;
	},
	
	/* handle variation value selection */
	selectVariationValue: function() {
		var that = this.variationHandler;
		var url = null;

		var disabled = false;

		if (this.tagName == 'A') {
			disabled = this.selectorDisabled && this.selectorDisabled == true;
		} else if (this.tagName == 'SELECT') {
			var value = this.value;
			this.select('option').each(function(field) {
				if (field.value == value) {
					if (field.hasClassName('disabledOptionIE')) {
						disabled = true;
					}
				}
			});
		} else {
			disabled = this.disabled;
		}

		if (!disabled) {
			if (this.tagName == 'A') {
				url = this.href;
			} else {
				url = this.value;
			}
			MiniCart.deactivateAddToCartButtons();
			that.reloadForVariationSelection(url);
		}
		
		return false;
	},
	
	/* send variation selection to server and reload product presentation */
	reloadForVariationSelection: function(selectURL) {
		var that = this;
		var queryParams = selectURL.toQueryParams();
		queryParams.availabilityInformation = this.availabilityInformationJSON;
		var url = selectURL.split('?')[0];
		new Ajax.Request(url, {parameters: queryParams, onSuccess: function(transport) {
			that.reloadSuccess(transport.responseText);
		}, onFailure: AjaxErrorHandler});
	},
	
	/* handle successful response for variation selection */
	reloadSuccess: function(content) {
		var contentParts = content.split(Constants.ajax.contentSplitter);
		var responseProlog = {quickView: false, productID: null, productDetailLink: null};
		var str = contentParts[0];
		str = removeXMLComments(str);
		try {
			responseProlog = eval(str)[0];
		} catch (e) {
		}
		if (!responseProlog.quickView) {
			$('productDetails').update(contentParts[1]);
			$('pageservices').update(contentParts[2]);
			$('differentViews').update(contentParts[3]);
		} else {
			$('quickviewData').update(contentParts[1]);
			$('differentViews').update(contentParts[2]);
			$('qvTitleProductID').update(responseProlog.productID);
			$('qvProdDetailLink').href = responseProlog.productDetailLink.replace(/&amp;\s*/g, '&');
		}
		this.reloadCallback(this.callbackContext);
	},
	
	/* handle mouse over on color swatches */
	colorMouseOverHandler: function() {
		var colorSwatch = this.select('img');
		var colorName = null;
		if (colorSwatch.length > 0) {
			colorName = colorSwatch[0].alt;
		}
		var colorName = this.select('img')[0].alt;
		if (colorName) {
			var colorNameField = $('selectedColorName');
			if (colorNameField) {
				this.storedColorName = colorNameField.textContent;
				colorNameField.textContent = colorName;
			}
		}
		if (!this.hasClassName('active')) {
			var colorValue = this.id.replace('varS_' + Constants.catalog.colorVariantID + '_', '');
			var imagesForValue = this.variationHandler.imagesForColors[colorValue];
			
			// Disable unavailable sizes
			
			// Find a product for this color
			var colorProduct = null;
			for (prodID in this.variationHandler.availabilityInformation.variants) {
				var colorProductColor = this.variationHandler.availabilityInformation.variants[prodID].varAttrs.variantColor.value;
				if(colorProductColor == colorValue){
					colorProduct = this.variationHandler.availabilityInformation.variants[prodID];
					break;
				}
			}
			varAttr = 'variantSize';
			var varAttrSFields = $$('.varS_' + varAttr);
			varAttrSFields.each(function(valueField){
				valueField.removeClassName('inactive');
			});						
			var variationAttributeValues = this.variationHandler.variationValues.get(varAttr);
			if(colorProduct && varAttrSFields){
				this.variationHandler.markUnavailableSelections(varAttrSFields, varAttr, variationAttributeValues, colorProduct, 'varS');
			}
			
			// Change images
			
			if (imagesForValue) {
				var normalImage = $('normalImage');
				var backImage = $('backImage');
				var laydownImage = $('laydownImage');
				
				if (normalImage) {
					this.storedNormalImage = normalImage.src; 
					normalImage.src = imagesForValue.normalImagePreloaded.src;
				}
				if (backImage) {
					this.storedBackImage = backImage.src;
					backImage.src = imagesForValue.backImagePreloaded.src;
				}
				if (laydownImage) {
					this.storedLaydownImage = laydownImage.src;
					laydownImage.src = imagesForValue.laydownImagePreloaded.src;
				}
			}
		}
	},
	
	/* handle mouse out on color swatches */
	colorMouseOutHandler: function() {
		// Reset images
		var storedColorName = this.storedColorName;
		if (storedColorName && storedColorName != null) {
			var colorNameField = $('selectedColorName');
			if (colorNameField) {
				colorNameField.textContent = storedColorName;
				this.storedColorName = null;
			}
		}
		if (!this.hasClassName('active')) {
			var normalImage = $('normalImage');
			var backImage = $('backImage');
			var laydownImage = $('laydownImage');
			var storedNormalImage = this.storedNormalImage;
			var storedBackImage = this.storedBackImage;
			var storedLaydownImage = this.storedLaydownImage;
			if (normalImage && storedNormalImage) {
				normalImage.src = storedNormalImage;
				this.storedNormalImage = null;
			}
			if (backImage && storedBackImage) {
				backImage.src = storedBackImage;
				this.storedBackImage = null;
			}
			if (laydownImage && storedLaydownImage) {
				laydownImage.src = storedLaydownImage;
				this.storedLaydownImage = null;
			}
		}
		// Reset sizes
		varAttr = 'variantSize';
		
		var varAttrSFields = $$('.varS_' + varAttr);		
		varAttrSFields.each(function(valueField){
			valueField.removeClassName('inactive');
		});
			
		var variationAttributeValues = this.variationHandler.variationValues.get(varAttr);
		if(varAttrSFields){
			this.variationHandler.markUnavailableSelections(varAttrSFields, varAttr, variationAttributeValues, this.variationHandler.availabilityInformation.variants[this.variationHandler.selectedProduct], 'varS');
		}		
	},
	
	/* returns the currently selected product */
	getSelectedProduct: function() {
		var product = null;
		if (this.selectedProduct != null) {
			product = this.availabilityInformation.variants[this.selectedProduct];
		}
		return product;
	}
});

var quickView = null;

/* Handler for quickview overlays and product mini behavior */
var QuickViewHandler = Class.create({

	productMinis: null,
	productMinisByProductID: null,
	quickViewOverlayElement: null,
	quickViewOverlay: null,
	varHandler: null,
	diffViewHandler: null,
	currentlyShownProductMini: null,
	searchInfos: null,

	/* Ctor */
	initialize: function() {
		var productMinis = $$('.prodMini');
		this.productMinis = new Array();
		this.productMinisByProductID = $H();
		var lastProductMini = null;
		productMinis.each(function(element) {
			var productMini = new ProductMini(this, element, lastProductMini);
			this.productMinis.push(productMini);
			lastProductMini = productMini;
			this.productMinisByProductID.set(productMini.productID, productMini);
		}.bind(this));
		var searchInfoValue = $('searchInfos') ? $F('searchInfos') : '[{searchCategoryID:null}]';
		this.searchInfos = {searchCategoryID:null};
		try {
			this.searchInfos = eval(searchInfoValue)[0];
		} catch(e) {
		}
		var qvOverlayElement = $('quickview');
		if (qvOverlayElement) {
			this.quickViewOverlayElement = qvOverlayElement;
		}
		if (this.productMinis && this.productMinis.length != 0) {
			this.reloadColorSwatches();
		}
	},
	
	/* load available color swatches for the product minis using an AJAX request */
	reloadColorSwatches: function() {
		var productIDs = new Array();
		this.productMinis.each(function(productMini) {
			productMini.setColorSwatchWaitImage();
			productIDs.push(productMini.productID);
		});
		var queryParams = $H();
		queryParams.set('productID', productIDs);
		if (this.searchInfos.searchCategoryID != null) {
			queryParams.set('cgid', this.searchInfos.searchCategoryID);
		}
		new Ajax.Request(Constants.url.colorSwatchReloadURL, {parameters: queryParams, onSuccess: function(transport) {
			this.colorSwatchesLoaded(transport.responseText);
		}.bind(this), onFailure: AjaxErrorHandler});
	},
	
	/* handle successful color swatch loading response */
	colorSwatchesLoaded: function(responseText) {
		var contentParts = responseText.split(Constants.ajax.contentSplitter);
		var responseProlog = {responseOrder: []};
		try {
			var str = contentParts[0];
			str = removeXMLComments(str);
			
			responseProlog = eval(str)[0];
		} catch(e) {
		}

		var cnt = 1;
		for (productID in responseProlog.responseOrder) {
			var productMini = this.productMinisByProductID.get(productID);
			productMini.setColorSwatches(contentParts[cnt].strip());
			++cnt;
			if (responseProlog.responseOrder[productID].soldOut) {
				productMini.setProductBadges(responseProlog.soldOutBadge);
			}
		}
		initIE6HoverFix();
	},
	
	/* event handler for quick view open requests */
	loadQuickView: function(productMini) {
		if (productMini) {
			StatusWindow.openProgressWindow();
			new Ajax.Request(productMini.quickViewURL, {onSuccess: function(transport) {
				this.quickViewLoaded(transport.responseText, productMini);
			}.bind(this), onFailure: AjaxErrorHandler});
		}
	},
	
	/* handle successful quick view response */
	quickViewLoaded: function(responseText, productMini) {
		StatusWindow.close();
		this.currentlyShownProductMini = productMini;
		var contentParts = responseText.split(Constants.ajax.contentSplitter);
		this.quickViewOverlayElement.update(contentParts[0]);
		$('differentViews').update(contentParts[1]);
		this.quickViewOverlay = new Overlay('quickview');
		this.quickViewOverlay.show();
		tabHandlerInit();
		this.varHandler = new variationHandler(this.reloadCallback, this, 'availability');
		this.diffViewHandler = new DifferentViewsHandler();
		this.initializeNavigationButtons();
		MiniCart.registerAddToCartButton($('addToCartButton'));
	},
	
	/* init the navigation buttons on quick view overlay (previous and next links) */
	initializeNavigationButtons: function() {
		$$('#quickview .prevArticle').each(function(element) {
			element.onclick = this.navButtonPrevious.bind(this);
			if (!this.currentlyShownProductMini.predecessor) {
				element.style.visibility = 'hidden';
			} else {
				element.style.visibility = 'visible';
			}
		}.bind(this));
		$$('#quickview .nextArticle').each(function(element) {
			element.onclick = this.navButtonNext.bind(this);
			if (!this.currentlyShownProductMini.successor) {
				element.style.visibility = 'hidden';
			} else {
				element.style.visibility = 'visible';
			}
		}.bind(this));
		$$('#quickview .divider').each(function(element) {
			if (!this.currentlyShownProductMini.successor || !this.currentlyShownProductMini.predecessor) {
				element.style.visibility = 'hidden';
			} else {
				element.style.visibility = 'visible';
			}
		}.bind(this));
	},
	
	/* Event handler for "previous" navigation link click */
	navButtonPrevious: function() {
		this.quickViewOverlay.hide();
		this.loadQuickView(this.currentlyShownProductMini.predecessor);
		return false;
	},
	
	/* Event handler for "next" navigation link click */
	navButtonNext: function() {
		this.quickViewOverlay.hide();
		this.loadQuickView(this.currentlyShownProductMini.successor);
		return false;
	},
	
	/* handle variation selection and reinit variation handler */
	reloadCallback: function(callbackContext) {
		callbackContext.varHandler.reinit();
		tabHandlerInit();
		initNonFunctionalLink();
		callbackContext.diffViewHandler = new DifferentViewsHandler();
		MiniCart.registerAddToCartButton($('addToCartButton'));
	}

});

/* This class represents a product mini */
var ProductMini = Class.create({

	element: null,
	quickViewURL: null,
	quickViewHandler: null,
	predecessor: null,
	successor: null,
	productID: null,
	imagesForSwatches: new Object(),
	originalImage: null,

	/* Ctor */
	initialize: function(qvHandler, element, predecessor) {
		if (element) {
			this.element = element;
			this.quickViewHandler = qvHandler;
			if (predecessor) {
				predecessor.successor = this;
				this.predecessor = predecessor;
			}

			var productID = this.element.select('input.productID');
			if (productID.length > 0 && productID[0].value != null) {
				this.productID = productID[0].value;
			}

			var quickViewURL = this.element.select('input.quickviewURL');
			if (quickViewURL.length > 0 && quickViewURL[0].value != null) {
				this.quickViewURL = quickViewURL[0].value;
			}
			if (this.quickViewURL) {
				this.element.select('.quickviewBtn').each(function(el) {
					el.addClassName('active');
					el.onclick = this.quickViewLinkClick.bind(this);
				}.bind(this));
			}
		}
	},
	
	/* set the color swatch AJAX loading image */
	setColorSwatchWaitImage: function() {
		var waitImage = new Element('img', {src: Constants.url.staticRoot + 'images/ajax-loader.gif'});
		var colorSelector = this.element.select('div.colorSelector');
		if (colorSelector.length > 0) {
			colorSelector[0].update(waitImage);
		}
	},
	
	/* set the loaded color swatches */
	setColorSwatches: function(colorSwatchContent) {
		
		var colorSelector = this.element.select('div.colorSelector');
		if (colorSelector.length > 0) {
			colorSelector[0].update(colorSwatchContent);

			var imgList = colorSelector[0].select('img');
			imgList.each(function(el) {
				el.observe('error', function() {
					this.src = Constants.url.colorSwatchBroken;
				});
			});
			
			var aList = colorSelector[0].select('a');
			aList.each(function(el) {
				// preload product images and add mouseoverhandler
				var pImageUrls = el.select('input');
				if(pImageUrls.length > 0){
					var image = new Image();
					image.src = pImageUrls[0].value;
					if(image != null)
						this.imagesForSwatches[el.href] = image;
					pImageUrls[0].remove();
					el.observe('mouseover', this.swatchMouseOverHandler);
					el.observe('mouseout', this.swatchMouseOutHandler);	
					el.productMini = this;					
				}
				
			}.bind(this));
			
		}
	},
	
	/* set product badges */
	setProductBadges: function(badges) {
		var badgeElements = this.element.select('span.productBadges');
		if (badgeElements.length > 0) {
			badgeElements[0].update(badges);
		}
	},
	
	/* event handler for a quick view button click */
	quickViewLinkClick: function() {
		this.quickViewHandler.loadQuickView(this);
		return false;
	},
	
	/* event handlers for colorswatch mouse over and out */
	swatchMouseOverHandler: function() {
		var ancestor = this.ancestors()[0];
		if(ancestor != null && this.href != null){
			var imageContainer = ancestor.previous('.imageContainer');
			if(imageContainer != null){
				var prodImg = imageContainer.select('.prodImg');
				if(prodImg != null && this.productMini.imagesForSwatches[this.href] != null){
					this.productMini.originalImage = prodImg[0].src;
					prodImg[0].src = this.productMini.imagesForSwatches[this.href].src;
				}
			}
		}
	},
	swatchMouseOutHandler: function() {
		var ancestor = this.ancestors()[0];
		if(ancestor != null && this.href != null){
			var imageContainer = ancestor.previous('.imageContainer');
			if(imageContainer != null){
				var prodImg = imageContainer.select('.prodImg');
				if(prodImg != null && this.productMini.imagesForSwatches[this.href] != null){
					prodImg[0].src = this.productMini.originalImage;	
				}
			}
		}
	}
		
});

/* Handler for detail view images switching */
var DetailViewHandler = Class.create({

	images: null,

	/* Ctor */
	initialize: function(element) {
		if (element) {
			this.images = [];
			var cnt = 0;
			$$('#detailBtns li').each(function(el, i) {
				var links = el.select('a');
				if (links && links.length > 0) {
					var link = links[0];
					if (link.href && link.href.indexOf('#') != -1) {
						var img = $(link.href.substring(link.href.indexOf('#') + 1));
						if (img) {
							var data = {li: el, 'img': img};
							this.images.push(data);
							++cnt;
							link.detailViewCnt = cnt;
							link.detailViewHandler = this;
							link.onclick = this.clickHandler;
						}
					}
				}
			}.bind(this));
			this.setImage(1);
		}
	},
	
	/* Show image */
	setImage: function(imgNo) {
		this.images.each(function(obj, i) {
			if (i + 1 == imgNo) {
				obj.img.show();
				obj.li.addClassName('active');
			} else {
				obj.img.hide();
				obj.li.removeClassName('active');
			}
		});
	},
	
	/* Handle click */
	clickHandler: function(el) {
		this.detailViewHandler.setImage(this.detailViewCnt);
		return false;
	}
});

/* Handler for the product views overlay (enlarged view, ...) */
var DifferentViewsHandler = Class.create({

	differentViewsOverlay: null,
	productVideoContent: null,
	productVideoAlternateContent: null,
	minimumFlashVersion: null,
	flashPath: null,

	/* Ctor */
	initialize: function() {
		this.reinit();
	},
	
	/* reinit a already instantiated DifferentViewsHandler */
	reinit: function() {
		this.differentViewsOverlay = new Overlay('differentViews');
		this.initDetailView();
		this.initRotImage();
		this.initProductVideo();
		this.removeProductVideo();	
		this.registerWindowCloseVideoEvent();	
		this.attachDifferentViewsTabHooks();
	},
	
	initDetailView: function() {
		var detailView = $('av_detail');
		if (detailView) {
			new DetailViewHandler(detailView);
		}
	},
	
	/* initialize handling of the rotate image functionality */
	initRotImage: function() {
		var rotImages = $('rotImages');
		if (rotImages) {
			var imageArr = eval(rotImages.value);
			new RotImage($('rotimgbox'), imageArr, true);
		}
	},
	
	initProductVideo: function() {
		var productVideo = $('av_video');
		if(productVideo){
			var flashVars = productVideo.select('.flashVars');
			if(flashVars){
				if(flashVars.length > 0){
					this.flashPath = flashVars[0].innerHTML;	
				}
				else this.flashPath = "";			
				if(flashVars.length > 1){
					this.minimumFlashVersion = flashVars[1].innerHTML;
				}
				else this.minimumFlashVersion = "1.0.0";
				flashVars.each(function(obj) {
						obj.remove();
					});
			}
			
			if(!this.productVideoContent)
				this.productVideoContent = productVideo.innerHTML;
		}
	},
	
	removeProductVideo: function() {		
		var productVideo = $('av_video');
		if (productVideo) {
			productVideo.childElements().each(function(obj) {
				obj.remove();
			});
		}
	},
	
	insertProductVideo: function() {
		var productVideo = $('av_video');
		if (productVideo) {
			productVideo.innerHTML = this.productVideoContent;
		}
		if(this.flashPath && this.minimumFlashVersion)
			swfobject.embedSWF(this.flashPath, "av_video_alternate_content", "100%", "100%", "6.0.0");	
	},

	registerWindowCloseVideoEvent: function() {
		var diffViewsOverlay = $('differentViews');
		if(diffViewsOverlay){
			var windowClose = diffViewsOverlay.select('.differentViewsCloseHandler');
			if(windowClose && windowClose.length > 0){
				windowClose[0].observe('click', function(){
					this.removeProductVideo();
				}.bind(this));
			}
		}
	},

	/* attach hooks for handling of diff view tab selections and register open handlers */
	attachDifferentViewsTabHooks: function() {
		// attach hooks for tab handling
		var tabViews = [{id: 'av_frontView', hook: this.imageViewTabHook.bind(this)},
						{id: 'av_backView' , hook: this.imageViewTabHook.bind(this)},
						{id: 'av_detail'   , hook: this.detailViewTabHook.bind(this)},
						{id: 'av_zoom'     , hook: this.zoomTabHook.bind(this)},
						{id: 'av_rotate'   , hook: this.rotateTabHook.bind(this)},
						{id: 'av_video'    , hook: this.videoTabHook.bind(this)}];
		
		var _tabHandler = null;
		
		tabViews.each(function(obj) {
			var el = $(obj.id);
			if (el && el.tabHandler) {
				el.tabHandler.registerTabHook(el, obj.hook);
			}
			if (el && _tabHandler == null) {
				_tabHandler = el.tabHandler;
			}
		});
		
		// attach hooks for overlay link handling
		if (_tabHandler != null) {
			var data = [{id: 'zoomNormalImage'     , tab: 'av_frontView'},
						{id: 'zoomNormalImageIcon' , tab: 'av_frontView'},
						{id: 'zoomBiggerLink'      , tab: 'av_frontView'},
						{id: 'viewDetails'         , tab: 'av_detail'},
						{id: 'zoomLaydownImage'    , tab: 'av_zoom'},
						{id: 'zoomLaydownImageIcon', tab: 'av_zoom'},
						{id: 'zoomLink'            , tab: 'av_zoom'},
						{id: 'zoomBackImage'       , tab: 'av_backView'},
						{id: 'zoomBackImageIcon'   , tab: 'av_backView'},
						{id: 'view3dLink'          , tab: 'av_rotate'},
						{id: 'videoLink'           , tab: 'av_video'}
						];
			
			data.each(function(o) {
				var el = $(o.id);
				if (el && el.overlayHandler) {
					el.overlayHandler.registerOverlayHook(el, this.selectTabOverlayHook, {tab : o.tab, tabHandler: _tabHandler});
				}
			}.bind(this));
		}
	},
	
	/* the IDs of different views tabs */
	tabViewButtonNames : ['detailBtns', 'zoomBtns', 'rotateBtns'],
	
	/* handle the selection of a tab */
	tabButtonHandler : function(tabToShow) {
		this.removeProductVideo();
		this.tabViewButtonNames.each(function(id) {
			var el = $(id);
			if (el) {
				if (id == tabToShow) {
					el.show();
				} else {
					el.hide();
				}
			}
		});
	},
	
	/* called when a image view (front view, back view) was selected */
	imageViewTabHook: function() {
		this.tabButtonHandler(null);
	},
	
	/* called when a video view was selected */
	videoTabHook: function() {
		this.tabButtonHandler(null);
		this.insertProductVideo();
	},	
	
	/* called when a detail view tab was selected */
	detailViewTabHook: function() {
		this.tabButtonHandler('detailBtns');
	},	
	
	/* called when the zoom tab was selected */
	zoomTabHook: function() {
		this.tabButtonHandler('zoomBtns');

		var zoomImg = $('zoomimg');
		if (zoomImg && !zoomImg.zoomInitialized) {
			new ZoomImage(zoomImg);
			zoomImg.zoomInitialized = true;
		}
	},
	
	/* called when the 360° view was selected */
	rotateTabHook: function() {
		this.tabButtonHandler('rotateBtns');
	},
	
	/* called when a link was selected that should open the diff views overlay */
	selectTabOverlayHook: function(element, options) {
		options.tabHandler.setTab(options.tab);
	}
});

function initQuickView() {
	var quickView = new QuickViewHandler();
}

document.observe('dom:loaded', function() {
	initQuickView();
});
