var Carousel = Class.create({
	initialize: function( element ){
		this.element = $(element);
		this.container = this.element.select( '.container' )[0];
		this.innerContainer = this.container.select( '.innerContainer' )[0];
		this.items = this.innerContainer.select( '.item' );
		this.firstItem = this.items[0];
		
		// Different init depending on the orientation of the carousel
		if(this.element.down('.leftButton')!=null) {
			this.orientation = 'horizontal';
			this.initHorizontal();
		} else {
			this.orientation = 'vertical';
			this.initVertical();
		}
		
		// Default value for scroll amount
		this.scrollSize = 1;
		
		// Read config from json
		var jsonspan = this.element.down('span.jsondata');
		
		if(jsonspan) {
			// We read the json configuration and set the new parameters
			var jsondata = this.getJSON(jsonspan);
			if(jsondata.scrollSize) {
				this.scrollSize = jsondata.scrollSize;
			}
		}
		
		this.currentScrollPos = 0;
		this.currentIndex = 0;
		this.currentItem = this.items[this.currentIndex];
		this.effect = null;

		this.checkNextActive();
		this.prevButton.observe('click', this.prevHandler.bindAsEventListener(this) );
		this.nextButton.observe('click', this.nextHandler.bindAsEventListener(this) );
		this.element.removeClassName('notInitialized');

	},
	
	initHorizontal: function() {
		// Get appropriate elements
		this.prevButton = this.element.select( '.leftButton' )[0];
		this.nextButton = this.element.select( '.rightButton' )[0];
		
		// Calculate the width of an element
		firstItem = this.items[0];
		this.itemGap = firstItem.getWidth();
		this.itemGap += parseInt(firstItem.getStyle('margin-left').replace('px',''));
		this.itemGap += parseInt(firstItem.getStyle('margin-right').replace('px',''));
		
		// Calculate the width of the whole carousel
		viewGap = this.container.getWidth();
		viewGap += parseInt(this.container.getStyle('margin-left').replace('px',''));
		viewGap += parseInt(this.container.getStyle('margin-right').replace('px',''));
		
		// Calculate how many items are shown in the carousel visible area
		this.viewedItems = Math.round(viewGap / this.itemGap);
	},
	
	initVertical: function() {
		// Get appropriate elements
		this.prevButton = this.element.select( '.upButton' )[0];
		this.nextButton = this.element.select( '.downButton' )[0];
		
		// Calculate the height of an element
		firstItem = this.items[0];
		this.itemGap = firstItem.getHeight();
		this.itemGap += parseInt(firstItem.getStyle('margin-top').replace('px',''));
		this.itemGap += parseInt(firstItem.getStyle('margin-bottom').replace('px',''));
		
		// Calculate the height of the whole carousel
		viewGap = this.container.getHeight();
		viewGap += parseInt(this.container.getStyle('margin-top').replace('px',''));
		viewGap += parseInt(this.container.getStyle('margin-bottom').replace('px',''));
		
		// Calculate how many items are shown in the carousel visible area
		this.viewedItems = Math.round(viewGap / this.itemGap);
	},
	
	prevHandler: function(e) {
		if( this.currentIndex >= this.scrollSize ) {
			this.scrollToIndex( this.currentIndex-this.scrollSize );
			this.currentScrollPos = this.currentScrollPos - 1;
		} else if (this.currentIndex > 0) {
			this.scrollToIndex(0);
			this.currentScrollPos = this.currentScrollPos - 1;	
		}
		this.checkNextActive();
		this.checkPrevActive();
	},

	nextHandler: function(e) {
		if( this.currentIndex+this.viewedItems+this.scrollSize <= this.items.length ) {
			this.scrollToIndex( this.currentIndex+this.scrollSize );
			this.currentScrollPos = this.currentScrollPos + 1;
		} else if ( this.currentIndex+this.viewedItems < this.items.length) {
			this.scrollToIndex( this.items.length-this.viewedItems );
			this.currentScrollPos = this.currentScrollPos + 1;	
		}
		this.checkNextActive();
		this.checkPrevActive();
	},

    checkNextActive: function() {
		this.debugThis();
		if( this.currentIndex+this.viewedItems < this.items.length  ) {
			this.nextButton.addClassName('active');	
		}else {
			this.nextButton.removeClassName('active');
		}
    },

    checkPrevActive: function() {
    	this.debugThis();
    	if( this.currentScrollPos + this.viewedItems > this.viewedItems ) {
			this.prevButton.addClassName('active');
		}else {
			this.prevButton.removeClassName('active');
		}
    },

    debugThis: function() {
    	/*
		console.log("this.scrollSize:" + this.scrollSize);
		console.log("this.currentScrollPos:" + this.currentScrollPos);
		console.log("this.viewedItems:" + this.viewedItems);
		*/
    },

    getCoordinate: function(index) {
        return index * (-this.itemGap);
    },

    scrollToIndex: function( index ) {
        var coordinate = this.getCoordinate(index);
        if(this.orientation=='horizontal') {
        	var currentCoordinate = parseInt(Element.getStyle(this.innerContainer, 'left')) || 0;
        } else {
        	var currentCoordinate = parseInt(Element.getStyle(this.innerContainer, 'top')) || 0;
        }
        var move = coordinate - currentCoordinate;
        if( null!=this.effect ) {
        	this.effect.cancel();
        }
        if(this.orientation=='horizontal') {
	        this.effect = new Effect.Move(this.innerContainer, {
	            duration: 0.3,
	            fps: 35,
	            x: move,
	            afterFinish: function() {
	        		this.innerContainer.setStyle({ left: coordinate + 'px' });
	        		this.effect = null;
	            }.bind(this)
	        });
        } else {
	        this.effect = new Effect.Move(this.innerContainer, {
	            duration: 0.3,
	            fps: 35,
	            y: move,
	            afterFinish: function() {
	        		this.innerContainer.setStyle({ top: coordinate + 'px' });
	        		this.effect = null;
	            }.bind(this)
	        });
        }
        this.currentIndex = index;
	},
	
	getJSON : function(jsonData) {
		var json = {};
		if (jsonData) {
			var plainData = '';
			if(jsonData.innerHTML!=undefined) {
				plainData = new String(jsonData.innerHTML);
			} else {
				plainData = new String(jsonData);
			}
			var attr = plainData.split('<!-- json:');
			if (attr.length >= 2) {
				var json_raw = attr[1].split('-->')[0];
				try {
					// The json_raw var is HTML encoded.
					json_raw = json_raw.unescapeHTML();

					// JS code in JSON object is not allowed
					json = json_raw.evalJSON(true);
				} catch (e) {
					console.error("JSON could not be parsed (%o)",e);
				}
			}
		}
		return json;
	}
});

var ZoomImage = Class.create({
	intendedZoomFactor: 4,
	opening: false,
	open: false,
	closing: false,
	flyOff: null,
	flyDim: null,
	
	initialize: function() {
		this.div = $('scene7zoom');
		this.delails = $('jsProductDetails');
		if (this.div) {
			this.div.select('.base').each( function( elem ) {
				this.base = elem;
			}.bind(this) );
			this.div.select('.baseImage').each( function( elem ) {
				this.baseImage = elem;
			}.bind(this) );
			this.div.select('.marker').each( function( elem ) {
				this.marker = elem;			
			}.bind(this) );
			this.div.select('.flyout').each( function( elem ) {
				this.flyout = elem;			
			}.bind(this) );
			this.div.select('.flyoutObj').each( function( elem ) {
				this.flyoutObj = elem;			
			}.bind(this) );
			
			this.flyDim = this.flyout.getDimensions();
			this.flyOff = { left: 392, top: 0 }; //this.flyout.positionedOffset();
			
			this.div.select('.zoomImage').each( function( elem ) {
				this.zoomImage = elem;
				//this.zoomImage.observe('onload', this.handleZoomLoaded.bind(this) );
				
				this.cacheImage = new Image();
				this.cacheImage.onload = this.handleZoomLoaded.bind(this);
				
				this.zoomImage.config = null;
				this.zoomImage.loaded = false;
				if (this.zoomImage.hasClassName('noImageSet')) {
					this.zoomImage.removeClassName('noImageSet');
					this.zoomImage.config = this.zoomImage.getConfiguration('ImgLink', true);
					this.loadZoomImage(this.zoomImage.config.img);
					this.zoomImage.loaded = true;
				} else {
					this.zoomImage.loaded = true;
				}
			}.bind(this) );
			
			this.base.observe('mousemove', this.handleMouseMove.bind(this) );
			this.base.observe('mouseenter', this.handleMouseMove.bind(this) );
			this.div.observe('mouseleave', this.handleMouseLeave.bind(this) );
			this.flyout.observe('mousemove', this.handleMouseFlyout.bind(this) );
			this.flyout.observe('click', this.handleMouseLeave.bind(this) );
			//this.adjustMarkerSize();
		}
	},
	
	setImage: function( baseImageUrl, zoomImageUrl ) {
		//var zoomImageUrl = baseImageUrl.split('?')[0];
		this.baseImage.src = baseImageUrl;
		//SOLI-814 sfhe
		this.zoomImage.config = {
			img: zoomImageUrl
		};
				
		this.loadZoomImage(zoomImageUrl);
		this.zoomImageLoaded = true;
	},
	
	loadZoomImage: function( zoomImageUrl ) {
		this.zoomImage.src = zoomImageUrl;
		this.cacheImage.src = zoomImageUrl;
		
		/*var ajaxRequest = new Ajax.Request(zoomImageUrl+'req=imageprops,text', {
			method: 'post',
			evalJS: false,
			evalJSON: false,
			onComplete: function(transport) {
				var prop = getS7Response( transport.responseText );
				var width = prop['image.width'];
				var height = prop['image.height'];
				zoomImageUrl += 'wid=' + width + '&hei=' + height; 
				this.zoomImage.src = zoomImageUrl;
				this.cacheImage.src = zoomImageUrl;
		/*	}.bind(this)
		}); */
	},
	
	handleZoomLoaded: function() {
		this.adjustMarkerSize();
	},
	
	handleMouseFlyout: function( ev ) {
		ev.stop();
		this.delails.hide();
		if( !this.opening && this.open && !this.closing ) {
			this.closing = true;
			this.triggerEffects();
		}
	},
	
	handleMouseLeave: function( ev ) {
		ev.stop();
		//this.flyout.hide();
		//this.marker.hide();
		this.delails.show();
		if( !this.closing ) {
			this.closing = true;
			this.triggerEffects();
		}
		return false;
	},

	deferId: null,
	handleMouseMove: function( ev ) {
		// reload Zoom Image from scene7 //
		this.delails.hide();
		if (this.zoomImage.config && !this.zoomImage.loaded) {
			this.loadZoomImage(this.zoomImage.config.img);
		}
		ev.stop();
		if( null==this.deferId ) {
			var rect = this.getCoordinates( ev );
			this.deferId = this.update.bind( this, rect ).defer();
		}
		if( !this.open && !this.opening ) {
			this.opening = true;
			this.triggerEffects( rect );
		}

		return false;
	},
	
	triggerEffects: function( rect ) {
		if( this.opening && !this.closing ) {
			var markDim = this.marker.getDimensions();
			var markOff = this.marker.positionedOffset();
			if( rect ) {
				markOff = { left: rect.x1, top: rect.y1 };
			}

			this.setPosition( this.flyout, markOff.left, markOff.top );
			this.setDimensions( this.flyout, markDim.width, markDim.height );
			
			this.openEffect = new Effect.Parallel([
			    new Effect.Appear( this.marker, {sync: true, to: 0.5 } ),
			    new Effect.Appear( this.flyout, {sync: true, from: 0.5 } ),
			    new Effect.Move( this.flyout, { x: this.flyOff.left, y: this.flyOff.top, mode: 'absolute', sync: true } ),
			    new Effect.Morph( this.flyout, { 
			    	style: { width: this.flyDim.width+'px', height: this.flyDim.height+'px' }, 
			    	sync: true,
			    	afterFinish: (function(effect) {
			    		this.open = true;
			    		this.opening = false;
			    		this.triggerEffects();
			    	}).bind(this)
			    } )
			], { duration: 0.3 } );
		}
		if( this.closing && !this.opening ) {
			this.closeEffect = new Effect.Parallel([
			    new Effect.Fade( this.marker, {sync: true, from: 0.5 } ),
			    new Effect.Fade( this.flyout, { sync: true } ),
			    new Effect.Morph( this.flyout, { 
			    	style: { width: 1+'px' }, 
			    	sync: true,
			    	afterFinish: (function(effect) {
			    		this.open = false;
			    		this.closing = false;
			    		this.triggerEffects();
			    	}).bind(this)
			    } )
            ], { duration: 0.2 } );
		}
	},
	
	update: function( rect ) {
		this.deferId = null;
		this.setPosition( this.marker, rect.x1, rect.y1 );
		this.setPosition( this.flyoutObj, -rect.x2, -rect.y2 );
	},

	getCoordinates: function( ev ) {
		var off = this.baseImage.cumulativeOffset();
		var x = ev.pointerX() - off.left;
		var y = ev.pointerY() - off.top;
		var dim = this.baseImage.getDimensions();
		var markDim = this.marker.getDimensions();
		
		var rect = { x1:0, x2:0, y1:0, y2:0 }; 
		if( x >= dim.width + 1 - markDim.width/2 ) {
			rect.x1 = dim.width + 1 - markDim.width;
		}
		else if( x >= markDim.width/2 - 1 ) {
			rect.x1 = x - markDim.width/2;
		}
		else if( x >= 0 ) {
			rect.x1 = -1;
		}
		if( y >= dim.height + 1 - markDim.height/2 ) {
			rect.y1 = dim.height + 1 - markDim.height;
		}
		else if( y >= markDim.height/2 - 1 ) {
			rect.y1 = y - markDim.height/2;
		}
		else if( y >= 0 ) {
			rect.y1 = -1;
		}
		
		var zoomDim = this.zoomImage //.getDimensions();
		var flyDim = this.flyDim; // this.flyout.getDimensions();
		rect.x2 = Math.min( ( rect.x1 + 1 ) * this.zoomFactor, zoomDim.width - flyDim.width );
		rect.y2 = Math.min( ( rect.y1 + 1 ) * this.zoomFactor, zoomDim.height - flyDim.height );
		return rect;
	},
	
	adjustMarkerSize: function() {
		var zoomDim = this.cacheImage;
		var flyDim = this.flyDim; //this.flyout.getDimensions();
		var baseDim = this.baseImage.getDimensions();
		var divDim = this.div.getDimensions();
			
		var zoomFactor = Math.min( this.intendedZoomFactor, Math.max( zoomDim.width / baseDim.width, zoomDim.height / baseDim.height ) ); 
		
		var width = flyDim.width / zoomFactor;
		var height = flyDim.height / zoomFactor;
		
		if( width > divDim.width || height > divDim.height ) {
			if( width / height > divDim.width / divDim.height ) {
				zoomFactor *= width / divDim.width;
			}
			else {
				zoomFactor *= height / divDim.height;
			}
			width = flyDim.width / zoomFactor;
			height = flyDim.height / zoomFactor;
		}
		this.zoomFactor = zoomFactor;
		this.setDimensions( this.zoomImage, divDim.width * zoomFactor, divDim.height * zoomFactor );
		this.setDimensions( this.marker, width, height );
	},
	
	setDimensions: function( elem, width, height ) {
		elem.style.width = width + 'px';
		elem.style.height = height + 'px';
	},
	
	setPosition: function( elem, left, top ) {
		if (top) {
			elem.style.top = top + 'px';
		}
		if (left) {
			elem.style.left = left + 'px';
		}
	}
});

/* 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,
	productVideoContent: null,
	productVideoAlternateContent: null,
	minimumFlashVersion: null,
	flashPath: null,
	curSelectImage: null,
	curRemovedProducts: null,
	shownImage: null,
	tellAFriendOpen: null,
	
	/* Ctor */
	initialize: function(reloadCallback, callbackContext) {
		this.reloadCallback = reloadCallback;
		this.callbackContext = callbackContext;
		this.disabledOptionFieldFixCheck();
		this.reinit(null, null);
	},
	
	/* reinit variationHandler. Have to be done after selecting variant. Should be called
	   by reloadCallback function.
	*/
	reinit: function(productID, masterProductID) {
		var that = this;
		var selProd = $('selectedProduct');
		if (selProd) {
			this.selectedProduct = selProd.value;
		} else {
			this.selectedProduct = null;
			selProd = null;
		}
		
		this.initAvailabilityInformation('availability');
		
		if (this.availabilityInformation) {
			
			this.initVariationValues();
			this.updateValuesWithAvailabilityInfos();
			
			$$('select.variationSelectionField').each(function(field) {
				field.variationHandler = that;
				field.onchange = that.selectVariationValue;
			});
			
			var colorSelectors = $$('.colorSelector.variantSelection a');
			var sizeSelectors = $$('.sizeSelector a');

			this.symbolicVariationValueFields = [];
			colorSelectors.each(function(field) {
				field.variationHandler = that;
				that.symbolicVariationValueFields.push(field);
			});
			
			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');
		}
		
		this.initShowHandler();
		this.initTellAFriend();
		this.initRotImage();
		this.initProductVideo();
		this.initIE6BadgePositionFix();	
		
		//quickView.reinit();		
		IE6HoverFix.init(ClientSideConstants.IE6HoverFix.elements);		
		//MiniCart.registerAddToCartForms();
		this.initImageCarousels();
		this.initZoomImage();
		jQuery(function() {
			jQuery('.scroll-pane').jScrollPane({
				showArrows: true,
				verticalDragMinHeight: 11,
				verticalDragMaxHeight: 11
				});
		});
		
	},
	
	/* init Product Videos */
	initProductVideo: function() {
		var that = this;
		var productVideos = $$('.video');
		productVideos.each(function(productVideo) {
			if(productVideo && !productVideo.initialized){
				var flashVars = productVideo.select('#' + productVideo.down('div').id + ' .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.flashPath && this.minimumFlashVersion) {
					var params = { wmode: "opaque" };
				}
				var attributes = {};
				var productID = productVideo.down('div').id.split('_')[0];
				swfobject.embedSWF(this.flashPath, productID + "_video_alternate_content", "100%", "100%", "6.0.0",null,null,params,attributes);	
			}
			productVideo.initialized = true;
		});
		
	},
	
	/* init Rotate image */
	initRotImage: function() {
		var rotImages = $('rotImages');
		if (rotImages) {
			var imageArr = eval(rotImages.value);
			new RotImage($('rotimgbox'), imageArr, true);
		}
	},
	
	/* init Show Handler */
	initShowHandler: function() {
		var showHolders = $$('.jsShowHolder');
		showHolders.each(function(link) {
			link.observe('click', this.showLinkHandler.bind(this));
		}.bind(this));
	},
		
	/* show/hide linked elements by LinkOptions */
	showLinkHandler: function (ev) {
		Event.stop(ev);
		var link = ev.element();
		var config = link.getConfiguration('LinkOptions');
		if (config.hideSel) {
			$$(config.hideSel).each(function(item) {
				item.hide();
			});
		}
		if (config.show){
			if (Object.isArray(config.show)) {
				config.show.each(function(item) {
					$(item).show();
				});
			}
			else {
				$(config.show).show();
			}
		}
		if (config.hide){
			if (Object.isArray(config.hide)) {
				config.hide.each(function(item) {
					$(item).hide();
				});
			}
			else {
				$(config.hide).hide();
			}
		}
	},
	
	initImageCarousels: function() {
		$$('.imageSelector.notInitialized').each(function(carousel) {
			this.imageCarousel = new Carousel(carousel);
			carousel.select('.selectImageLink').each(function(e) {
				if(e.next('.largeImage')!=null) {
					e.observe('click', function(event) {
						var imageLink = event.findElement('.selectImageLink');
						this.selectImageHandler(imageLink);
					}.bind(this));
				}
			}.bind(this));
		}.bind(this));
	},
	
	initZoomImage: function() {
		
		this.zoomImage = new ZoomImage();		
	},
	
	selectImageHandler: function(element) {
		var largeImage = element.next('.largeImage');
		var zoomImage = element.next('.zoomImage');
		document.fire('tracking:onZoomView', {});
		largeImageUrl = (largeImage.innerText || largeImage.textContent).replace(/^\s+/g,'').replace(/\s+$/g,'');
		zoomImageUrl = (zoomImage.innerText || zoomImage.textContent).replace(/^\s+/g,'').replace(/\s+$/g,'');
		this.zoomImage.setImage( largeImageUrl, zoomImageUrl );
		var index = element.next('.index');
		var indexNumber = parseInt(index.innerHTML);
		this.imageIndex = indexNumber;
	},
	/*******************************/
	/*  Recommendations            */
	/*******************************/

	/* init add to cart button */
	initAddToCartButton: function() {
		var addToCartButton = $('jsAddToCartButton');
		/*if (!addToCartButton.initialized) {
			addToCartButton.observe('click', this.lookAddToCartHandler.bind(this));
			addToCartButton.initialized = true;
		}*/
		var idx = addToCartButton.placeholderIdx ? addToCartButton.placeholderIdx : addToCartButton.value.indexOf('@');
		if (idx != -1) {
			addToCartButton.value = addToCartButton.value.replace(addToCartButton.value.toArray()[idx],this.getSelectedProductsCount()); 
			addToCartButton.placeholderIdx = idx;
		}
	},
	
	/* click remove product */
	removeProductHandler: function(ev) {
		var removeButton = ev.element();
		var masterID = removeButton.next('input.masterid').value;
		this.removeProduct(masterID);
		this.setRemovedProducts();
		Event.stop(ev);
	},
	
	/* click add product */
	addProductHandler: function(ev) {
		var addButton = ev.element();
		var masterID = addButton.next('input.masterid').value;
		this.addProduct(masterID);
		this.setRemovedProducts();
		Event.stop(ev);
	},
	
	getLookPrice: function() {
		var url = $F('lookPriceURL');
		var params = {};
		var products = [];
		$$('input.pid').each(function(el) {
			if (!el.hasClassName('remove')) {
				products.push(el.value);
			}
		});
		params.pid = products;
		new Ajax.Request(url, {method: 'GET', parameters: params, onSuccess: this.lookPriceLoaded.bind(this)});
	},
	
	lookPriceLoaded: function(transport) {
		var contentParts = transport.responseText.split(Constants.ajax.contentSplitter);
		$$('.jsProductSetPrice1').each(function(el) {
			el.update(contentParts[0]);
		});
		$$('.jsProductSetPrice2').each(function(el) {
			el.update(contentParts[1]);
		});
	},
	
	round: function(x, n) {
		if (n < 1 || n > 14) return false;
		var e = Math.pow(10, n);
		var k = (Math.round(x * e) / e).toString();
		if (k.indexOf('.') == -1) k += '.';
		k += e.toString().substring(1);
		return k.substring(0, k.indexOf('.') + n+1);
	},
	
	
	/* encode productID */
	encodeProductID: function(productID) {
		return productID.replace(/\./g,'-');
	},
	
	/* decode productID */
	decodeProductID: function(productID) {
		return productID.replace(/\-/g,'.');
	},
	
	/* get selected product variants as string exclude current product*/
	getAllSelectedProducts: function(curProduct) {
		var products = $$('.pid');
		var selectedProducts = '';
		products.each(function(product) {
			if (!product.value.startsWith(this.decodeProductID(curProduct))) {
				selectedProducts += product.value + ';';
			}
		}.bind(this));
		return selectedProducts.substr(0,selectedProducts.length-1);
	},

	getSelectedProducts: function() {
		var products = $$('.pid');
		var selectedProducts = '';
		products.each(function(product) {
			if (!product.hasClassName('remove')) {
				selectedProducts += product.value + ';';
			}
		}.bind(this));
		return selectedProducts.substr(0,selectedProducts.length-1);
	},
	
	getSelectedProductsCount: function() {
		var products = $$('.pid');
		var selectedProductsCount = 0;
		products.each(function(product) {
			if (!product.hasClassName('remove')) {
				selectedProductsCount += 1;
			}
		}.bind(this));
		return selectedProductsCount;
	},
	


	/*******************************/
	/*  Availability               */
	/*******************************/
	
	/* 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:{}}]';
			}
		}
	},
	
	/*******************************/
	/*  Variation                  */
	/*******************************/

	/* 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 (Prototype.Browser.IE6) {
			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(varAttrSFields, varAttr, variationAttributeValues, 'var', false);
			that.disableUnavailableVarAttrFields(varAttrSFields, varAttr, variationAttributeValues, 'varS', true);
			
			// mark unavailable value selections
			if (selectedProduct && varAttr != Constants.catalog.colorVariantID) {
				// that.markUnavailableSelections(varAttrSFields, varAttr, variationAttributeValues, selectedProduct, 'var', false);
				that.markUnavailableSelections(varAttrSFields, varAttr, variationAttributeValues, selectedProduct, 'varS', true);
			}
		});
		this.fixIEOptionFields();
	},
	
	/* disable variation attributes that are unavailable (evaluated by availability information) */
	disableUnavailableVarAttrFields: function(varAttrFields, varAttr, variationAttributeValues, prefix, symbolic) {
		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) {
				var field = valueField;
				if (symbolic) {
					field = valueField.up('li');
				}
				// field.remove();
				valueField.addClassName('notavailable');
			}
		});
		if (empty && !symbolic) {
			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, symbolic) {
		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('notavailable');
						var links = valueField.select('a');
						links.each(function(link) {
							link.selectorDisabled = true;
						});
					} else if (valueField.tagName == 'A') {
						valueField.addClassName('notavailable');
						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' && this.hasClassName('notavailable')) {
			disabled = 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.getConfiguration('variations').url;
			} else {
				url = this.value;
			}
			that.reloadForVariationSelection(url);
		}
		
		return false;
	},
	
	/* send variation selection to server and reload product presentation */
	reloadForVariationSelection: function(selectURL) {
		StatusWindow.openProgressWindow();
		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});
	},
	
	/* returns the currently selected product */
	getSelectedProduct: function() {
		var product = null;
		if (this.selectedProduct != null) {
			product = this.availabilityInformation.variants[this.selectedProduct];
		}
		return product;
	},
	
	/* handle successful response for variation selection */
	reloadSuccess: function(content) {
		StatusWindow.close();
		var contentParts = content.split(Constants.ajax.contentSplitter);
		var responseProlog = {quickView: false, productID: null, productDetailLink: null};
		var str = contentParts[0];
		str = str.removeXMLComments();
		try {
			responseProlog = eval(str)[0];
		} catch (e) {
		}
		if (!responseProlog.quickView) {
			$('productDetails').update(contentParts[1]);
		} else {
			$('quickviewData').update(contentParts[1]);
		}
		this.reloadCallback(this.callbackContext, responseProlog.productID, responseProlog.masterProductID);
	},
	
		/* send variation selection to server and reload product presentation */
	reloadAddToCartInclude: 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.reloadAddToCardIncludeSuccess(transport.responseText);
		}, onFailure: AjaxErrorHandler});
	},
	
	/* handle successful response for variation selection */
	reloadAddToCardIncludeSuccess: function(content) {
		$('jsAddToCartInclude').update(content);
	},
	
	/* init tell a friend form */
	initTellAFriend: function() {
		var tellafriendsubmit = $('tellafriendsubmit');
		if (tellafriendsubmit && !tellafriendsubmit.tellafriendinit) {
			tellafriendsubmit.observe('click',this.tellafriendSubmitHandler.bind(this));
			tellafriendsubmit.up('form').observe('submit',this.tellafriendSubmitHandler.bindAsEventListener(this, 'isSubmit'));
			tellafriendsubmit.tellafriendinit = true;
		}
		$$('.jsTellAFriendLink').each(function(el) {
			if (!el.tellafriendinit) {
				el.observe('click', function(ev) {
					this.tellAFriendOpen = {
						rememberedImage: this.shownImage
					};
					var lookBackImage = $('jsLookBackImage');
					if (lookBackImage) {
						lookBackImage.up('.boxbttm').hide();
						var contentBox = lookBackImage.up('.contentbox');
						if (contentBox) {
							contentBox.removeClassName('noHover');
						}
					}
					Event.stop(ev);
				}.bind(this));
				el.tellafriendinit = true;
			}
		}.bind(this));
		$$('.jsTellAFriendCloseLink').each(function(el) {
			if (!el.tellafriendinit) {
				el.observe('click', function(ev) {
					if (this.tellAFriendOpen != null) {
						this.showImage(this.tellAFriendOpen.rememberedImage);
					}
					var lookBackImage = $('jsLookBackImage');
					if (lookBackImage) {
						lookBackImage.up('.boxbttm').show();
						var contentBox = lookBackImage.up('.contentbox');
						if (contentBox) {
							contentBox.addClassName('noHover');
						}
					}
					Event.stop(ev);
				}.bind(this));
				el.tellafriendinit = true;
			}
		}.bind(this));
	},
	
	
	/* send tell a friend to server and reload */
	tellafriendSubmitHandler: function(ev, isSubmit) {
		StatusWindow.openProgressWindow();
		Event.stop(ev);
		var queryParams = ev.element().up('form').serialize();
		var url = ev.element().up('form').action;
		new Ajax.Request(url, {parameters: queryParams, onSuccess: function(transport) {
			this.tellafriendSuccess(transport.responseText);
		}.bind(this), onFailure: AjaxErrorHandler});
	},
	
	/* handle successful response for tell a friend */
	tellafriendSuccess: function(content) {
		StatusWindow.close();
		$('jsTellAFriendForm').update(content);
		initComponents();
		this.initTellAFriend();
		var statusMsg = $('statusMsg');
		if (statusMsg != '' && statusMsg != null) {
			StatusWindow.message(statusMsg.value,null,'3000');
		}
	}
	
});

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,
	StatusWindow: null,

	/* Ctor */
	initialize: function(issetproduct) {
		if(issetproduct){
			var productMinis = $$('.setproduct');
		}
		else{
			var productMinis = $$('.quickViewProduct');
		}
		this.productMinis = new Array();
		this.productMinisByProductID = $H();
		var lastProductMini = null;
		productMinis.each(function(element) {
			if(issetproduct){
				// on product set pages use SetProduct as product mini
				var productMini = new SetProduct(this, element);
			}
			else{
				if (!element.hasClassName('rec')) {
					var productMini = new ProductMini(this, element, lastProductMini);
					
					// do not add productsets
					if(productMini.isLook == 'false'){
						this.productMinis.push(productMini);
						lastProductMini = productMini;
						var prodMiniArr = this.productMinisByProductID.get(productMini.productID);
						if (!prodMiniArr) {
							prodMiniArr = [];
						}
						prodMiniArr.push(productMini);
						this.productMinisByProductID.set(productMini.productID, prodMiniArr.uniq());
					} else {
						this.productMinis.push(productMini);
					}
				}
				else {
					new ProductMini(this, element, null);
				}
			}
			
		}.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();
			this.reloadSizes();
			this.alternativeImages();
		}
	},
	
	reinit : function () {
		var productMinis = $$('.prodMini');
		this.productMinis = new Array();
		this.productMinisByProductID = $H();
		var lastProductMini = null;
		/* FLWE TEMP FIX START */
		var maxElementsCount = 0;
		/* FIX ENDS */
		productMinis.each(function(element) {	
			/* FLWE TEMP FIX START */
			maxElementsCount ++;
			/*
			var flwetemp = element.select('input.productID');
			console.log(flwetemp[0].value);	
			console.log('maxElementsCount:' + maxElementsCount);
			*/	
			if(maxElementsCount >= 50 && Prototype.Browser.IE){
				/* Stop Prozessing */
			} 
			else {
				/* FIX ENDS */				
				if (!element.hasClassName('rec')) {	
					var productMini = new ProductMini(this, element, lastProductMini);					 
					this.productMinis.push(productMini);
					lastProductMini = productMini;				
					var prodMiniArr = this.productMinisByProductID.get(productMini.productID);
					
					if (!prodMiniArr) {					
						prodMiniArr = [];						
					}
	
					prodMiniArr.push(productMini);
					this.productMinisByProductID.set(productMini.productID, prodMiniArr.uniq());
	
				}
				else {
					new ProductMini(this, element, null);			
				}
			/* FIX ENDS */
			}
			/* FIX ENDS */
			
		}.bind(this));
	},
	
	/* alternative images */
	alternativeImages: function() {
		this.productMinis.each(function(productMini) {
			productMini.setAltImage();
		});
	},
	
	/* load available color swatches for the product minis using an AJAX request */
	reloadColorSwatches: function() {
		var productIDs = new Array();
		this.productMinis.each(function(productMini) {
			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 = str.removeXMLComments();
			
			responseProlog = eval(str)[0];
		} catch(e) {
		}

		var cnt = 1;
		for (productID in responseProlog.responseOrder) {
			var productMini = this.productMinisByProductID.get(productID);
			++cnt;
			if (responseProlog.responseOrder[productID].soldOut) {
				productMini.each(function(pm) {
					pm.setProductBadges(responseProlog.soldOutBadge);
				});
			}
		}

		IE6HoverFix.init(ClientSideConstants.IE6HoverFix.elements);
	},
	
	/* load available Sizes for the product minis using an AJAX request */
	reloadSizes: function() {
		var productIDs = new Array();
		this.productMinis.each(function(productMini) {
			productMini.setSizesWaitImage();
			productIDs.push(productMini.productID);
		});
		var queryParams = $H();
		queryParams.set('productID', productIDs);
		new Ajax.Request(this.productMinis[0].sizeLayerReloadURL, {parameters: queryParams, onSuccess: function(transport) {
			this.sizesLoaded(transport.responseText);
		}.bind(this), onFailure: AjaxErrorHandler});
	},
	
	/* handle successful sizes loading response */
	sizesLoaded: function(responseText) {
		var contentParts = responseText.split(Constants.ajax.contentSplitter);
		var responseProlog = {responseOrder: []};
		try {
			var str = contentParts[0];
			str = str.removeXMLComments();
			
			responseProlog = eval(str)[0];
		} catch(e) {
		}

		var cnt = 1;
		for (productID in responseProlog.responseOrder) {
			var productMini = this.productMinisByProductID.get(productID);
			productMini.each(function(pm) {
				pm.setSizes(contentParts[cnt].strip());
			});
			++cnt;
			if (responseProlog.responseOrder[productID].soldOut) {
				productMini.each(function(pm) {
					pm.setProductBadges(responseProlog.soldOutBadge);
				});
			}
		}
	},
	
	
	showProduct: function(pid,productsetid) {
		this.loadQuickView({quickViewURL: Constants.url.quickViewURL + escape(pid) + '&productsetid=' + escape(productsetid)});
	},
	
	/* event handler for quick view open requests */
	loadQuickView: function(productMini, productId, url) {
		if (productMini) {
			if (this.quickViewOverlay) {
				this.quickViewOverlay.hide();
			}
			StatusWindow.openProgressWindow();
			var params = productMini.quickViewURL.toQueryParams();
			if (productId != null) {
				params.pid = productId;
			}
			var queryParamPos = productMini.quickViewURL.indexOf('?');
			
			var url = queryParamPos == -1 ? productMini.quickViewURL : productMini.quickViewURL.substr(0, queryParamPos);
			
			new Ajax.Request(url, {method: 'GET', parameters: params, 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]);
		this.quickViewOverlay = new Overlay('quickview');
		this.quickViewOverlay.show();
		this.varHandler = new variationHandler(this.reloadCallback, this, this.currentlyShownProductMini.isLook);
		this.initializeNavigationButtons();
		initComponents();
		this.reinit();
		//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, productID, masterProductID) {
		callbackContext.varHandler.reinit(productID, masterProductID);
		callbackContext.quickViewOverlay.reinit('quickview');
		callbackContext.reinit();
		initComponents();
	}

});

/* This class represents a product mini */
var ProductMini = Class.create({

	element: null,
	quickViewURL: null,
	quickViewHandler: null,
	predecessor: null,
	successor: null,
	masterProductID: null,
	productID: null,
	categoryID: null,
	sizeLayerReloadURL: null,
	isLook: null,
	linkedLookProducts: null,
	imagesForSwatches: new Object(),
	originalImage: null,

	/* Ctor */
	initialize: function(qvHandler, element, predecessor) {
		if (element && !element.productMini) {
			element.productMini = this;
			this.element = element;
			this.quickViewHandler = qvHandler;
			if (predecessor) {
				predecessor.successor = this;
				this.predecessor = predecessor;
			}

			var masterProductID = this.element.select('input.masterProductID');
			if (masterProductID.length > 0 && masterProductID[0].value != null) {
				this.masterProductID = masterProductID[0].value;
			}
			
			var productID = this.element.select('input.productID');
			if (productID.length > 0 && productID[0].value != null) {
				this.productID = productID[0].value;
			}
			
			var categoryID = this.element.select('input.categoryID');
			if (categoryID.length > 0 && categoryID[0].value != null) {
				this.categoryID = categoryID[0].value;
			}
			
			var sizeLayerReloadURL = this.element.select('input.sizeLayerReloadURL');
			if (sizeLayerReloadURL.length > 0 && sizeLayerReloadURL[0].value != null) {
				this.sizeLayerReloadURL = sizeLayerReloadURL[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.observe('click', this.quickViewLinkClick.bind(this));
				}.bind(this));
			}

			var isLook = this.element.select('input.isLook');
			if (isLook.length > 0 && isLook[0].value != null) {
				this.isLook = isLook[0].value;
			}
			
			var linkedLookProducts = this.element.select('input.linkedLookProducts');
			if (linkedLookProducts.length > 0 && linkedLookProducts[0].value != null) {
				this.linkedLookProducts = linkedLookProducts[0].value;
				$$('.' + this.linkedLookProducts).each(function(el) {
					el.observe('click', this.quickViewLinkClick.bind(this));
				}.bind(this));
			}
			
			var altImageURL = this.element.select('input.altimageURL');
			if (altImageURL.length > 0 && altImageURL[0].value != null) {
				this.altImageURL = altImageURL[0].value;
			}
		}
	},
	
	/* 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.colorswitcher');
		if (colorSelector.length > 0) {
			colorSelector[0].update(waitImage);
		}
	},
	
	/* set the sizes AJAX loading image */
	setSizesWaitImage: function() {
		var waitImage = new Element('img', {src: Constants.url.staticRoot + 'images/ajax-loader-white.gif'});
		var sizeLayer = this.element.select('div.productsizes');
		if (sizeLayer.length > 0) {
			sizeLayer[0].update(waitImage);
		}
	},
	
	/* set the loaded product sizes */
	setSizes: function(sizesContent) {
		
		var sizesSelector = this.element.select('div.productsizes');
		if (sizesSelector.length > 0) {
			sizesSelector[0].update(sizesContent);
		}
	},
	
	/* 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(ev) {
		this.quickViewHandler.loadQuickView(this);
		Event.stop(ev);
	},
	
	/* set alternative images */
	setAltImage: function() {
		if (this.altImageURL) {
			this.element.select('.jsImageSwitcher').each(function(el) {
				el.productMini = this;
				el.observe('mouseover', this.altImageMouseOverHandler.bindAsEventListener(el) );
				el.observe('mouseout', this.altImageMouseOutHandler.bindAsEventListener(el) );				
			}.bind(this));
		}
	},
	
	/* 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;	
				}
			}
		}
	},
	/* event handlers for alternative hover image mouse over and out */
	altImageMouseOverHandler: function(ev) {
		
		var prodImg = ev.findElement('.prodImg');
		var altImg = this.productMini.altImageURL;
		if(prodImg != null && altImg != null && prodImg.src != altImg){
			this.originalImage = prodImg.src;
			prodImg.src = altImg;
		}

	},
	altImageMouseOutHandler: function(ev) {
		var prodImg = ev.findElement('.prodImg');
		if(prodImg != null && this.originalImage != null && prodImg.src != this.originalImage){
			prodImg.src = this.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;
	}
});
/* This class represents a product set */
var SetProduct = Class.create({

	element: null,
	productSetID: null,
	productID: null,
	quickViewURL: null,
	quickViewHandler: null,

	/* Ctor */
	initialize: function(qvHandler,element) {
		if (element) {
			this.element = element;
			this.quickViewHandler = qvHandler;
			var productSetID = this.element.select('input.productSetID');
			if (productSetID.length > 0 && productSetID[0].value != null) {
				this.productSetID = productSetID[0].value;
			}
			
			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.onclick = this.quickViewLinkClick.bind(this);
				}.bind(this));
				this.element.select('li').each(function(el) {
					el.addClassName('pointer');
					el.onclick = this.quickViewLinkClick.bind(this);
				}.bind(this));
			}
		}
	},

	/* event handler for a quick view button click */
	quickViewLinkClick: function() {
		document.fire('tracking:onQuickviewClick');
		this.quickViewHandler.loadQuickView(this);
		return false;
	}
	
});
function initQuickView(issetproduct) {
	quickView = new QuickViewHandler(issetproduct);
}

document.observe('dom:loaded', function() {
	initQuickView(false);
	// issetproduct for product set detail page
	initQuickView(true);
});

