/*
	content:
	- definitions of different tool-classes

	covered classes:
	- JSPulldown (baseclass for all pulldowns)
	- MetaPulldown (class for pulldowns in metanavigation)
	- CountrySelectPulldown (special case for country selection)
	- CountrySelect
	- ProdPager (paging-handler for product-presentation)		
	- PrefilledInput (inputfields with prefilled values as information)
	- TTip (Tooltip-class)
	- ImgButton
	- ListPage
	- AjaxLightBox
	- WishList
	- DragObj
	- DropZones
	- WishableProduct
	- WishedProduct
	- CookieManager
	- ImgPreload (preloading class)
	- Destroyer
	- general (mini-toolfunctions, init & config)
	- checkVoucher
*/



/* -------------------------------------------------------------------
	=JSPulldown
 ------------------------------------------------------------------ */

var JSPulldown = Class.create({
	initialize: function(handle, params){
		this.handle				= $(handle);			
		this.handleID	 		= this.handle.id;		
		
		this.pulldownID		= this.handleID+'-pd';
		this.pulldown			= $(this.pulldownID);		
		
		// params
		this.origTop 			= params.top ? params.top : 0; // hardcoded dependency to layout: needed for animations
		this.activation		= params.activation && ['mouseover','click'].indexOf(params.activation)>-1 ? params.activation : 'click';
		this.openAnimation	= params.animation ? ['open','both'].indexOf(params.animation)>-1 : false;
		this.closeAnimation	= params.animation ? ['close','both'].indexOf(params.animation)>-1 : false;
		this.pdnoclick			= params.pdnoclick == true ? true : false;
		this.noautoclose		= params.noautoclose == true ? true : false;
		this.selectprotect  	= params.selectprotect == true ? true : false;
		this.showselects		= this.selectprotect;
		
		// constants and status-vars
		this.animatingDirection	= 0; // 1=opening, -1=closing
		this.origHeight 			= 0; //this.pulldown.getHeight();		
		this.currentPos			= 0; // 0=closed, 1=opened
		
		this.closeTimer			= null;
		this.openTimer				= null;
		this.need2Init				= 'n';
		this.startedActive		= $$('#'+this.handleID+' a')[0].hasClassName('active');		
		
		// animation config
		this.pxPerSecond			= 200;								
		this.fps						= 25;		
		
		// bound function
		if (this.openAnimation || this.closeAnimation){
			this.boundClipIt 			= this.clipIt.bind(this);
			this.need2Init = 'y';
		}
	
		this.boundClosePulldown = this.startClosePulldown.bind(this);
		this.boundOpenPulldown 	= this.startOpenPulldown.bind(this);
		this.boundMouseOver		= this.mouseover.bind(this);
		this.boundMouseOut		= this.mouseout.bind(this);
		this.boundpdOpenListener	= this.pulldownOpenListener.bind(this);
		this.boundClick				= this.click.bind(this);
		
		this.initEventHandler();
		Destroyer.register(this.handle, 'JSPulldown', this);
	},
	destroy: function(){		
		Event.stopObserving(this.handle, "mouseover", this.boundMouseOver);
		Event.stopObserving(this.handle, "mouseover", this.boundMouseOut);		
		
		// deactivated condition : errors under IE in figurines assistant..  if (!this.handle.down('#'+this.pulldownID)){		
		Event.stopObserving(this.pulldown, "mouseover", this.boundMouseOver);
		Event.stopObserving(this.pulldown, "mouseover", this.boundMouseOut);
		
		Event.stopObserving(this.handle, "pulldown:opened", this.pulldownOpenListener);
		if (this.activation=='click'){
			Event.stopObserving(this.handle, "click", this.boundClick);
		}
		delete this.boundClosePulldown;
		delete this.boundOpenPulldown;
		delete this.boundMouseOver;
		delete this.boundMouseOut;
		delete this.boundpdOpenListener;
		delete this.boundClick;
		if (this.openAnimation || this.closeAnimation){
			delete this.boundClipIt;
		}
		
		Destroyer.unregister(this.handle, 'JSPulldown', this);
	},
	initAnimation: function(){
		this.origHeight 			= this.pulldown.getHeight();		
		this.transition			= Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal;
		
		// animation calc shortcuts
		this.durationInSeconds	= this.origHeight/this.pxPerSecond;
		this.secondsPerStep		= 1/this.fps;
		this.percentStepWidth 	= 1/(this.fps*this.durationInSeconds); 
	},	
	initEventHandler: function(){
		if (this.activation=='click'){
			$$('#'+this.handleID+' a')[0].href = 'javascript: void(0);';
			this.handle.observe('click', this.boundClick);
			// if defined, remove onclick event on pulldown
			if (this.pdnoclick && this.handle.down('#'+this.pulldownID)){
				this.pulldown.observe('click', function(e){ e.stopPropagation();});
			}
		}
		
		this.handle.observe('mouseover', this.boundMouseOver);
		this.handle.observe('mouseout', this.boundMouseOut);
		
		if (!this.handle.down('#'+this.pulldownID)){
			this.pulldown.observe('mouseover', this.boundMouseOver);
			this.pulldown.observe('mouseout', this.boundMouseOut);
		}
		
		this.handle.observe('pulldown:opened', this.boundpdOpenListener);		
	},
	mouseover: function(e){	
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		if (this.closeTimer)
			window.clearTimeout(this.closeTimer);
		if (this.activation=='mouseover')
			if (this.currentPos!=1)
				this.openTimer = this.boundOpenPulldown.delay(0.15);
	},
	mouseout: function(e){
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		if (!this.noautoclose){
			if (this.closeTimer)
				window.clearTimeout(this.closeTimer);
			this.closeTimer = this.boundClosePulldown.delay(0.5);					
		}
	},	
	click: function(e){	
		if (this.currentPos==1){
			this.startClosePulldown();
		} else if (this.currentPos==0){
			this.startOpenPulldown();
		} else {
			if (this.animatingDirection!=1){
				this.startOpenPulldown();
			} else {
				this.startClosePulldown();
			}			
		}
		
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		if (this.closeTimer)
			window.clearTimeout(this.closeTimer);
	},
	// callback-listener, when a pulldown opens 
	pulldownOpenListener: function(e){
		if (this.currentPos!=0 && e.memo.id!=this.handleID){				
			if (e.memo.selectprotect){
				this.showselects=false;
			}
			this.startClosePulldown();
		}
		
	},
	startOpenPulldown: function(){
		if (this.need2Init=='y'){
			this.need2Init = 'n';
			this.initAnimation();
		}
		
		if (this.selectprotect){
			hideSelects();
			this.showselects=true;
		}
		
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		if (this.closeTimer)
			window.clearTimeout(this.closeTimer);				
		
		if (this.openAnimation){
			if (this.animatingDirection!=1){
				this.animatingDirection = 1;
				this.openPulldown();
				if ((this.currentPos==0) || (this.currentPos==1))
					this.clipIt();
			}
		} else {
			this.currentPos = 1;
			this.animatingDirection = 0
			this.openPulldown();
			if (this.closeAnimation)
				this.clipIt();
		}
	},
	startClosePulldown: function(){		
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		if (this.closeTimer)
			window.clearTimeout(this.closeTimer);
			
		if (this.closeAnimation){
			if (this.animatingDirection!=-1){
				this.animatingDirection = -1;
				if (this.currentPos==1)
					this.clipIt();
			}
		} else {
			this.currentPos = 0;
			this.animatingDirection = 0
			this.endClosePulldown();
		}
	},
	openPulldown: function(){	
		if (storySWFReady) {
			/*console.log("Jetzt ist offen");*/
			sendLayerStateToFlash("OPENED");	
		}

		this.pulldown.show();
		
		var link = this.handle.down('a');
		if (!this.startedActive)
			link.addClassName('active');
		link.blur();
		
					
		var hdname 			= this.handleID;
		var selectprotect = this.selectprotect;
		$$('.pd-handle').each(function(e){
			e.fire('pulldown:opened', {id: hdname, selectprotect: selectprotect});
		});
	},
	endOpenPulldown: function(){					
		if (storySWFReady) {
			/*console.log("Jetzt ist offen");*/
			sendLayerStateToFlash("OPENED");	
		}		
	},
	endClosePulldown: function(){		
		if (storySWFReady) {
			/*console.log("Jetzt ist zu");*/
			sendLayerStateToFlash("CLOSED");	
		}	
		
		if (!this.startedActive)
			$$('#'+this.handleID+' a')[0].removeClassName('active');				
		this.pulldown.hide();	
		if (this.selectprotect && this.showselects){
			showSelects();
		}
		

	},	
	clipIt: function() {	
		this.currentPos 	= Math.max(0, Math.min(1, this.currentPos + this.animatingDirection*this.percentStepWidth));
		var factor 			= 1-this.transition(this.currentPos);		
		var crop 			= Math.ceil(factor*this.origHeight);				
		
		if (this.currentPos==1){
			this.endOpenPulldown();
		} else if (this.currentPos==0){
			this.endClosePulldown();
		}
		
		this.pulldown.setStyle({clip: 'rect('+crop+'px, auto, auto, auto)', top: (this.origTop-crop)+'px'});
		if ( (this.currentPos<1 && this.animatingDirection>0) || (this.currentPos>0 && this.animatingDirection<0) ){
			this.boundClipIt.delay(this.secondsPerStep);
		}
	}
});


/* -------------------------------------------------------------------
	=MetaPulldown
 ------------------------------------------------------------------ */
 
var MetaPulldown = Class.create(JSPulldown, {
	startOpenPulldown: function($super){
		// specific
		if (this.handle.getWidth() > this.pulldown.getWidth()+6 ){				
			this.pulldown.setStyle({width: (this.handle.getWidth() + 6) + 'px'});
		}
		
		$super();
	}
});


/* -------------------------------------------------------------------
	=CountrySelectPulldown
 ------------------------------------------------------------------ */
 
var CountrySelectPulldown = Class.create(MetaPulldown, {
	initEventHandler: function($super){
		this.boundCountrySelectReloaded = this.countrySelectReloaded.bind(this);
		this.pulldown.observe('countryselect:reloaded', this.boundCountrySelectReloaded);
				
		$super();
	},
	countrySelectReloaded: function(e){		
		this.initAnimation();
	},
	endOpenPulldown: function(){		
		this.pulldown.fire('countryselect:pdopened');
	}
});


/* -------------------------------------------------------------------
	=CountrySelect
 ------------------------------------------------------------------ */

var CountrySelect = Class.create({
	initialize: function(){
		this.elmID 		= 'meta-country-pd';
		this.elm			= $(this.elmID);
		this.area 		= this.elm.down('.sub-area');
	
		this.conf		= config.get(this.elmID);
		
		this.boundFormChanged 		= this.formChanged.bind(this);
		this.boundPulldownOpened 	= this.pulldownOpened.bind(this);
		this.boundAjaxSuccess 		= this.ajaxSuccess.bind(this);
		this.boundCloseLink			= this.closeLink.bind(this);
		
		this.animating = false;
		this.firstOpen = true;
		
		this.elm.observe('countryselect:pdopened', this.boundPulldownOpened);
		
		this.resetArea();		
	},
	resetArea: function(){
		this.form = this.elm.down('form');
		if (this.form){
			this.observer = new Form.EventObserver(this.form, this.boundFormChanged);
		}
		this.closelink = this.elm.down('a.close');
		if (this.closelink){
			this.closelink.href = 'javascript: void(0);';
			this.closelink.observe('click', this.boundCloseLink);
		}
	},
	closeLink: function(){	
		this.elm.fire('pulldown:opened')
	},
	formChanged: function(form, data){		
		// TODO: observer entfernen
		this.loadContent(form.serialize(true));
	},
	pulldownOpened: function(e){		
		if (this.firstOpen){			
			this.firstOpen = false;		
			//this.area.update();	
			this.loadContent({});			
		}
		
	},
	loadContent: function(formvalues){
		if (this.animating)
			return;
		var params = hashMerge(config.get('global_linkparams'), this.conf.linkparams, formvalues);

		this.animating = true;
		var that = this;

		new Effect.Opacity(this.area, { 
			
			duration: 0.5, 
			transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal,
				from: 1, 
					to: 0,
				afterFinish: function() {
				new Ajax.Request(that.conf.ajaxurl, {
					parameters: params,
					method: 'post',
					onSuccess: that.boundAjaxSuccess				
				});
			}
		});
				
		
		if (($$('.sub-boxnote')[0]) && ($$('.sub-boxchoice')[0])) {
			new Effect.Opacity($$('.sub-boxnote')[0], { 
				duration: 0.5, 
				transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal,
		     	from: 1, 
	   	   		to: 0
			});	
			new Effect.Opacity($$('.sub-boxchoice')[0], { 
				duration: 0.5, 
				transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal,
		     	from: 1, 
	   	   		to: 0
			});
			
			/* the last two effects seem redundant but are necessary for IE to behave at least almost correctly */
			
		}		
	},
	ajaxSuccess: function(response){  			
		this.area.update(response.responseText);
		var that = this;
		new Effect.Opacity(that.area, { 
			duration: 1, 
			transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal, 
	  		from: 0, 
  			to: 1,
  			afterFinish: function() {
				that.animating = false;
				that.resetArea();
				
				that.elm.fire('countryselect:reloaded');
			}
	  	});
	},
	cancelSelection: function() {
		this.firstOpen= true;
		new Effect.Opacity($('fade-handle'), {delay:1, duration:1, from:1, to:0});
		new Effect.Opacity($$('.warning')[0], {delay: 2, duration:0.1, from:1, to:0});
		/* this last effect seems redundant but is neccessary for IE to behave at least almost correctly */
	},
	continueSelection: function(form) {
		this.loadContent(form.serialize(true) ); 
	}
});



/* -------------------------------------------------------------------
	=ProdPager
 ------------------------------------------------------------------ */


var ProdPager = Class.create({
initialize: function(elm, initObject){	
	this.elm			= elm;
	this.elmID 		= elm.id;
		
	this.conf				= config.get(this.elmID);	
	this.elmWidth			= initObject.elmWidth || 134;	
	this.shownElms			= initObject.shownElms || 5;

	this.animating			= false;	
	this.currentActive	= null;
	
	this.lft 		= elm.down('.sub-lft a');
	this.rgt 		= elm.down('.sub-rgt a');
	
	this.lft.href = 'javascript: void(0);';
	this.rgt.href = 'javascript: void(0);';
	
	this.overlay = this.elm.down('.sub-overlay');
  	this.overlay.setOpacity(0);  	 
	this.boundFinishedCallback = this.finishedCallback.bindAsEventListener(this);
	
	this.resetList();		 
	this.initEventHandler();
},
resetList: function(){
	this.ul			= this.elm.down('ul');
	this.elms		= this.ul.childElements();
	this.maxHeight 	= this.elms.max(function(prod){
		return prod.getHeight();
	});
	this.elmsPerPage = Math.max(0, Math.min(this.elms.length-this.shownElms, this.shownElms));
	this.lftIndex	= 0;
	this.elm.down('.sub-mask').setStyle({height: this.maxHeight + 'px'});
	// singleprodpager: prevents bug with following text
	if (this.elm.hasClassName('mod-singleprodpager')){
		this.elm.setStyle({height: this.maxHeight + 'px'});
	}
	
	if (this.elms.length<=this.shownElms){
		this.lft.hide();
		this.rgt.hide();
	} else {
		this.lft.show();
		this.rgt.show();
	}
	
	/**
	 *  Start TP/SL: Calculating random start position for the product slider
	 */
	var randStartPos = parseInt((Math.random()*(this.elms.length-this.shownElms+1)*(-1)));
	this.ul.setStyle({left: randStartPos*this.elmWidth + 'px'});
	/**
	 *  End TP/SL
	 */	
	
	this.ul.observe('pager:finished', this.boundFinishedCallback);
},
initEventHandler: function(){
	this.lft.observe('click', this.turnpage.bindAsEventListener(this, 'lft'));
	this.rgt.observe('click', this.turnpage.bindAsEventListener(this, 'rgt'));	
	
	if (this.conf && this.conf.loadlinks){
		for (var i=0; i<this.conf.loadlinks.length; i++){
			var loadlink = $(this.conf.loadlinks[i].id);
			if (loadlink){
				if (loadlink.hasClassName('active')){
					this.currentActive = loadlink;
				}
				var linkparams = hashMerge(config.get('global_linkparams'), this.conf.linkparams, this.conf.loadlinks[i].linkparams);
				loadlink.href='javascript: void(0);';
				loadlink.observe('click', this.loadset.bindAsEventListener(this, (this.conf.loadlinks[i].ajaxurl ? this.conf.loadlinks[i].ajaxurl : this.conf.ajaxurl), linkparams, this.conf.loadlinks[i].desc));
			}
		}
	}
},
loadset: function(e, ajaxurl, params, desc){	
	if (this.animating)
		return;
	if (this.currentActive)
		this.currentActive.toggleClassName('active');	
	this.currentActive = e.element();
	this.currentActive.toggleClassName('active');
	this.overlay.show();
	this.animating = true;
	$('prodpager-caption').update(desc);
	var that = this;	
	new Effect.Opacity(this.overlay, { 
		duration: 0.5, 
      transition: Effect.Transitions.linear,
      from: 0, 
      to: 1,
      afterFinish: function() {
			new Ajax.Request(ajaxurl, {
				parameters: params,
				method: 'post',
				onSuccess: that.ajaxSuccess.bind(that)				
			});
		}
	});
	
},
ajaxSuccess: function(response){  	
	this.ul.stopObserving('pager:finished', this.boundFinishedCallback);
	this.ul.replace(response.responseText);
	this.resetList();					
	var that = this;
	new Effect.Opacity(that.overlay, { 
		duration: 1, 
		transition: Effect.Transitions.linear, 
  		from: 1, 
  		to: 0,
  		afterFinish: function() {
			that.overlay.hide();
			that.animating = false;
		}
  	});
},
turnpage: function(e, direction){
	if (this.animating)
		return;
	this.animating = true;
	var left=this.elmLeft(direction);
	for(var i=0; i<this.elmsPerPage-left; i++){
		this.move(direction);
	}
	var newPos = parseInt(this.ul.getStyle('left'))+((direction=='rgt' ? -1 : 1)*this.elmWidth*this.elmsPerPage);
	
	var that = this;
	this.ul.morph('left:'+newPos+'px', {
		delay: 0.4, 
		duration: this.elmsPerPage * 0.35, 
		transition: Effect.Transitions.sinoidal, 
		afterFinish: function() {
			that.ul.fire('pager:finished');
		}	
	});
},
finishedCallback: function(e){
	this.animating = false;
},
elmLeft: function(direction){
	if (direction=='lft'){
		return -1*(parseInt(this.ul.getStyle('left')) / this.elmWidth);
	} else {
		return Math.max(0, this.elms.length-this.shownElms+(parseInt(this.ul.getStyle('left')) / this.elmWidth));
	}
},
move: function(direction){
	if (direction=='lft'){
		var elmIndex2Remove = this.lftIndex-1;
		if (elmIndex2Remove<0)
			elmIndex2Remove = this.elms.length-1;	
		this.lftIndex = elmIndex2Remove;	
		
		var current = parseInt(this.ul.getStyle('left'));
		this.ul.setStyle({left: current-this.elmWidth+'px'});
		this.ul.insert({ top: this.elms[elmIndex2Remove].remove()});
		
	} else {
		var elmIndex2Remove = this.lftIndex;
		this.lftIndex++;
		if (this.lftIndex>this.elms.length-1)
			this.lftIndex = 0;
		var current = parseInt(this.ul.getStyle('left'));
		this.ul.setStyle({left: current+this.elmWidth+'px'});
		this.ul.insert({ bottom: this.elms[elmIndex2Remove].remove()});
		
	}
}
});


var SingleProdPager = Class.create(ProdPager, {

	initialize: function($super, elm){	

		$super(elm, {
			elmWidth: 124,
			shownElms: 4}
		);
		
		if (this.elms.length==3){
			this.ul.setStyle({left: 55+'px'});
		} else if (this.elms.length==2){
			this.ul.setStyle({left: 115+'px'});
		} else if (this.elms.length==1) {
			this.ul.setStyle({left: 175+'px'});
		}
	}
	
});



/* -------------------------------------------------------------------
	=PrefilledInput
 ------------------------------------------------------------------ */
 /*
	- params: 
			node-element
	- realizes prefilled content that automatically is emptied when input gains focus 
		and will be put back if input loses focus and content is empty
	- takes hint-text out of element-title (not from value!)
	- tooltip-content taken out of element-title
	- init: every element with class "hintcontent" will be processed
*/
var PrefilledInput = Class.create({
	initialize: function(elm){
		this.elm 		= elm;
		this.origValue = this.elm.title;
		
		// no title, no need
		if (!this.origValue)
			return;
		
		this.elm.observe('focus', this.focus.bind(this));
		this.elm.observe('blur', this.blur.bind(this));
		if (this.elm.value==this.origValue) this.elm.addClassName('faded');				
	},
	focus: function(e){
		if (this.elm.value==this.origValue) {
			this.elm.value='';
			this.elm.removeClassName('faded');
		}
	},
	blur: function(e){
		if (this.elm.value=='') {
			this.elm.value=this.origValue;
			this.elm.addClassName('faded');
		}
	}
});


/* -------------------------------------------------------------------
	=TTip
 ------------------------------------------------------------------ */
/*
	- params: 
			node-element
	- realizes a js-tooltip
	- tooltip-content taken out of element-title
	- init: every element with class "ttip" will be tooltipped
*/
var TTip = Class.create({
	initialize: function(elm){
		this.elm 			= elm;
		this.area			= null;
		this.openTimer		= null;
		this.displayed		= false;		
		
		this.content 	= this.elm.title;
		// no title -> no tooltip
		
		if (!this.content)
			return;				
			
		// empty title to prevent browser-tooltip			
		this.elm.writeAttribute({title:""});		
		
		// remove alt of surrounded images
		if ((this.elm.tagName != 'INPUT') && (this.elm.down('img'))){		
			this.elm.down('img').alt="";
		}
		
		this.boundMouseMove 	= this.mousemove.bind(this);
		this.boundShow 		= this.show.bind(this);
		this.boundOut 			= this.mouseout.bind(this);
		this.boundOver 		= this.mouseover.bind(this);
								
		this.elm.observe('mouseout', this.boundOut);
		this.elm.observe('mouseover', this.boundOver);
		Destroyer.register(elm, 'TTip', this);
	},	
	destroy: function(){
		Event.stopObserving(this.elm, "mouseout", this.boundOut);
		Event.stopObserving(this.elm, "mouseover", this.boundOver);
		if (this.displayed)
			this.elm.stopObserving('mousemove', this.boundMouseMove); 		
		delete this.boundMouseMove;
		delete this.boundShow;
		delete this.boundOut;
		delete this.boundOver;
		
		Destroyer.unregister(this.elm, 'TTip', this);
	},
	// mousemove-handler for poisitioning of tooltip
	mousemove: function(e){
		this.xCord = Event.pointerX(e);											
		this.yCord = Event.pointerY(e);
		if (this.displayed){
			this.area.setStyle({left: this.xCord + this.deltaX + "px", top: this.yCord + this.deltaY + "px"});	
		}		
	},
	// mouseover to start tooltip-timer 
	mouseover: function(e){
		// special case: ttip actual deactivated
		if (this.elm.hasClassName('untip')) return;
		this.elm.observe('mousemove', this.boundMouseMove);											
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		
		if (!this.displayed){			
			if (this.elm.hasClassName('ttip-nodelay')){
				this.show();
			} else {
				this.openTimer = this.boundShow.delay(0.3);
			}			
		}
		this.xCord = Event.pointerX(e);											
		this.yCord = Event.pointerY(e);
		
	},
	// mouseout to hide tooltip
	mouseout: function(e){		
		if (this.elm.hasClassName('untip')) return;									
		if (this.openTimer)
			window.clearTimeout(this.openTimer);
		this.hide();
	},
	// show tooltip
	show: function(){		
		this.displayed	= true;
		if (!this.area && !(this.area=$('ttip-area'))){
			this.buildArea(this.xCord + 12, this.yCord + 12);
		}
				
		this.area.setStyle({width: 'auto'});
		this.area.down(2).update(this.content);
		
		var height = this.area.getHeight();
		var width = this.area.getWidth();
		
		if (width>200){
			this.area.setStyle({width: '200px'});
			width = 200;
		}		

		var distance2Bottom = ( document.viewport.getHeight() + document.viewport.getScrollOffsets().top - (this.yCord + 12 + height) );
		if (distance2Bottom<30){
			this.deltaY = -height -12;
		} else {
			this.deltaY = 12;
		}
		
		var distance2Right = ( document.viewport.getWidth() + document.viewport.getScrollOffsets().left - (this.xCord + 12 + width) );
		if (distance2Right<30){
			this.deltaX = -width -12;
			//this.area.setStyle({textAlign: 'right'});
		} else {
			this.deltaX = 12;
			//this.area.setStyle({textAlign: 'left'});
		}
		this.area.setStyle({left: this.xCord + this.deltaX + "px", top: this.yCord + this.deltaY + "px"});																							
		
		this.area.show();
		var width = this.area.getWidth();
		
		if (width>200){
			this.area.setStyle({width: '200px'});
		}
		
		
	},
	// hide tooltip
	hide: function(){
		this.elm.stopObserving('mousemove', this.boundMouseMove); 
		this.displayed=false;		
		if (this.area)
			this.area.hide();
	},
	// construct tooltip-area, if not already done
	buildArea: function(left, top){
		this.area = new Element('div', {id: 'ttip-area', style: 'left: '+left+'px; top: '+top+'px; display: none;'}).insert(new Element('div', {className: 'sh-out'}));
		this.area.down().insert(new Element('div',{className: 'sh-in'}));
		this.area.down(1).insert(new Element('div',{className: 'sub-content'}));
		document.body.insertBefore(this.area, document.body.childNodes[0]);									
		Element.extend(this.area); // IE needs element to be manually extended
	}
});


/* -------------------------------------------------------------------
	=ImgButton
 ------------------------------------------------------------------ */
 
var ImgButton = Class.create({
	initialize: function(elm){
		this.elm 	= elm;
		this.src 	= this.elm.src;
		this.hoverImg = new Image();
		this.hoverImg.src = this.manipulateSrc(this.src, '_h');
		
		this.clickImg = new Image();
		this.clickImg.src = this.manipulateSrc(this.src, '_c');
		
		this.elm.observe('mouseover', this.mouseover.bind(this));
		this.elm.observe('mouseout', this.mouseout.bind(this));
		this.elm.observe('mousedown', this.click.bind(this));
	},
	manipulateSrc: function(str, postfix){
		return str.replace(/(\.[^.]{3,4})$/g, postfix+"$1");
	},	
	mouseover: function(e){
		this.elm.src = this.hoverImg.src;
	},
	mouseout: function(e){
		this.elm.src = this.src;
	},
	click: function(e){
		this.elm.src = this.clickImg.src;
		this.elm.blur();
	}	
});	

/* -------------------------------------------------------------------
	=ListPage
 ------------------------------------------------------------------ */
 /*
	- params: 
			group-element
	- realizes a listpage
*/

var ListPage = Class.create({
	initialize: function(elm){
		this.elm 			= elm;
		this.elmID			= elm.id;
		this.conf			= config.get(this.elmID);
		this.draggables 	= new Array();				
		
		// content visible also without resizing
		this.resize.bind(this).delay(0.1);				
	}, 
	resize: function(){
		/**
		 * TP/SL: Resize function was adapted for asia websites
		 * <p> was replaced by <div> and width is not touched
		 */
		
		var prods = $$('#'+this.elmID+' .listed-prod');
		var maxheight = 0;
		var prodPerRow = 4;
		var prodcount 	= prods.length;
		
		if (prodcount==0)
			return;															
		
		var groupcount 		= Math.ceil(prodcount/prodPerRow);
		//var imgWidth 			= 19;
		//var imgMargin			= 3;
		//var linkWidth			= prods[0].down('.pulldown').down('a').getWidth();		
		//var newFixingWidth 	= linkWidth+imgWidth+imgMargin+3;		
		var that 				= this;
				
		for (var g=0; g < groupcount; g++){
			
			var r =$R(g*prodPerRow, Math.min(prodcount-1, (g+1)*prodPerRow-1));
			
			var maxheight = 0;
			var minheight = 0;			
						
			r.each(function(index){				
				var height = prods[index].down('div').getHeight();
				maxheight = Math.max(maxheight, height);
				minheight = Math.min(minheight, height);				

				//var pd 		= prods[index].down('.pulldown');
				//var fixing 	= pd.up('div');
				//var img 		= fixing.down('img');					
				
				//pd.setStyle({width: px2em(linkWidth)+'em'});								
				//fixing.setStyle({width: px2em(newFixingWidth)+'em'});									
				//img.setStyle({marginRight: (px2em(imgMargin)+'em')});
			});
			
			if (minheight != maxheight){
				r.each(function(index){										
					prods[index].down('div').setStyle({height: maxheight+'px'})
				});
			}																
		}			
	}
});
 
 
 
 /* -------------------------------------------------------------------
	=AjaxLightBox
 ------------------------------------------------------------------ */
 var AjaxLightbox = Class.create({
	initialize: function(){
		this.overlay 		= null;
		this.lightbox		= null;
		this.area			= null;
		
		this.active			= false;
		this.animating		= false;
		
		this.queue			= new Array();
		
		this.boundAjaxSuccess 	= this.ajaxSuccess.bind(this);
		this.boundClose			= this.close.bind(this);
		
		if (navigator.platform.match(/Mac/g)) {
			this.opac = 1;
		} else {
			this.opac = 0.9;
		}
			
	},	
	destroy: function(){		
		delete this.boundAjaxSuccess;
		delete this.boundClose;
		if (this.closelink){
			Event.stopObserving(this.closelink, "click", this.boundClose);
		}
		// todo: in this tree, there could be more elements to destroy 
		if (this.overlay){
			this.overlay.remove();
		}
	},
	show: function(ajaxurl, params, css){
		if (this.animating)
			return;
		this.animating = true;				
		
		this.css = css;
		
		/* not yet initialized */
		if (!this.overlay){
									
			var objBody = $$('body')[0];
			this.overlay = objBody.insert({top: Builder.node('div',{id:'lightbox-wrap'}, [
				Builder.node('div',{id:'lightbox', 'class': this.css}, [
					Builder.node('div',{'class':'sh-out'}, [
						Builder.node('div',{'class':'sh-in'})
					])
				])
			])});			
			this.wrap = $('lightbox-wrap');
			this.area = this.wrap.down('.sh-in');

			this.wrap.setOpacity(0);
			this.wrap.hide();						

			objBody.insert({top: Builder.node('div',{id:'lightbox-overlay'})});

			this.overlay = $('lightbox-overlay');
			this.overlay.setOpacity(0);

		} else {
			$('lightbox').removeClassName($('lightbox').className);
			$('lightbox').addClassName(this.css);
		}
		
		var arrayPageSize = getPageSize();
		this.overlay.setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });
		this.overlay.show();		
		this.active = true;

		// hide all form fields
		$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

		var linkparams = hashMerge(config.get('global_linkparams'), $H(params));
		
		var that = this;
		new Effect.Opacity(this.overlay, { 
			duration: 1,  
			transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal,
			from: 0, 
			to: this.opac, /* changed from 0.9 by MATZE */
			afterFinish: function() {
				new Ajax.Request(ajaxurl, {
					parameters: linkparams,
					method: 'post',
					onSuccess: that.boundAjaxSuccess					
				});
			}
		});
	},
	ajaxSuccess: function(response){ 
		this.wrap.show();
		this.wrap.setOpacity(0);
		this.area.update(response.responseText);
		sanitizeSubFeatures.delay(2);

		// vertikales zentrieren
		var viewPortY = document.viewport.getHeight();
		var scrollY = document.viewport.getScrollOffsets()[1];
		var elmY = $('lightbox').getHeight();

		if (elmY<viewPortY){
			$('lightbox').setStyle({'top': ((scrollY+Math.round((viewPortY-elmY)/2))+'px')});
		} else {
			$('lightbox').setStyle({'top': (Math.max(40, (scrollY-Math.round((elmY-viewPortY)/2)))+'px')});
		}
		
		var that = this;
		new Effect.Opacity(that.wrap, { 
			duration: 0.5, 
			transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal, 
			from: 0, 
			to: 1,
			afterFinish: function() {
				that.animating = false;
				that.closelink = that.area.down('a.close');
				if (that.closelink){
					that.closelink.observe('click', that.boundClose);
				}
			}
		});
	},
	close: function(e){
		if (this.animating)
			return;
		
		if (this.closelink){
			this.closelink.stopObserving('click', this.boundClose);
		}
		
		this.animating = true;
		
		var that = this;
		this.wrap.setOpacity(0);
		this.wrap.hide();			
				
		
		new Effect.Opacity(this.overlay, { 
			duration: 0.5, 
			transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal, 
			from: this.opac, 
			to: 0,
			afterFinish: function() {
				that.animating = false;	
				that.overlay.hide();
				that.active = false;
				// show all formfields
				$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
				if (that.queue.length>0) {
					window.alb.show(that.queue[0], that.queue[1], that.queue[2]);
					that.queue.clear();
				}
			}
		});
	}
});


/* -------------------------------------------------------------------
	=wishlist
 ------------------------------------------------------------------ */

var WishList = Class.create({
	initialize: function(){	
		this.cm = null;
		
		this.cookieName 	 = 'UserInformationAsia';
		this.cookieAttribute = 'WISHLISTSKU';		
	
		this.elmID 		= 'tile-wishlist';
		this.elm			= $(this.elmID) || false; 
		this.dragWish 	= new Array();				
		this.wished		= [];
		
		this.conf 		= config.get('wishlist');
				
		if (this.elm){				
			this.updateView(false,false);
			
			DropZones.add($$('body')[0], {
				accept: 'wished'
				,onDrop: function(drag, drop, e){ }
			});
			DropZones.add($('tile-wishlist'), {
				accept: ['wished','wishable']
				,onDrop: function(drag, drop, e){ }
			});
		}
		
		this.boundUpdateView = this.updateView.bind(this, false);
	},
	addElement: function(e, params){	
		if (!this.cm)
			this.cm = new CookieManager();
			
		var prodstring = this.cm.getCookieAttr(this.cookieName, this.cookieAttribute);		
		if (prodstring){		
			var values = prodstring.split(',');			
		} else {
			var values = [];
		}
		
		values.push(params.prodid + '~' + params.image);		
		values = values.uniq(); 		
		
		//this.cm.setCookie(this.cookieName, values.join(','), 0);
		
		this.cm.setCookieAttr(this.cookieName, this.cookieAttribute, values.join(','), 0);
		
		this.updateView(false,params.prodid);	
	},
	removeElement: function(e, params){
		if (!this.cm)
			this.cm = new CookieManager();
			
		var prodstring = this.cm.getCookieAttr(this.cookieName, this.cookieAttribute);
		if (prodstring){		
			var values = prodstring.split(',');			
		} else {
			var values = [];
		}		
		
		var newValues = values.without(params.prodid + '~' + params.image);
		
		//this.cm.setCookie(this.cookieName, newValues.join(','), 0);
		this.cm.setCookieAttr(this.cookieName, this.cookieAttribute, newValues.join(','), 0);
		
		this.updateView(params.prodid,false);
	},
	// called after refresh
	initdropzone: function(){
		//this.img
		if (!this.elm)
			return;
		var imgs = this.elm.down('.sub-dropzone').descendants();
		var that = this;
		this.wished = [];
		for(var i=0; i<imgs.length; i++){
			if (imgs[i].tagName=='IMG')
				this.wished.push(new WishedProduct(imgs[i]));			
		}
	},						
	updateView: function(RemoveProductSKU, AddProductSKU){
		if (this.elm){			
			var params = hashMerge(config.get('global_linkparams'), this.conf.linkparams);
			
			if (!this.cm)
				this.cm = new CookieManager();
			var prodstring = this.cm.getCookieAttr(this.cookieName, this.cookieAttribute);
			if (prodstring){		
				var values = prodstring.split(',');			
			} else {
				var values = [];
			}
			// clearing whishlist if there are some products in it
			$('wishlist-replacer').innerHTML = '';
			if(values.length == 0) $('wishlist-default').show();
			else $('wishlist-default').hide();
			
			
			// Getting the product template and replace the standarddocumentId with the #{documentId} placeholder 

			var productTemplate = $('template_wishlist_product');
			//productTemplate.down('img').setStyle({height:'50px', width:'50px'});
			var imagePath = productTemplate.down('img').src;
			
			var i = 1;
			var that = this;
			values.each(function(item) {
				
				//productTemplate.show();
				item = item.split('~');
				sku = item[0];
				imageId = item[1];

				//apapting style for right product
				if((i%3)==0) productTemplate.down('img').addClassName('right');
				else productTemplate.down('img').removeClassName('right');
				i++;
				
				// Replacing decoded charecters within the template	
				templ = productTemplate.innerHTML;
				templ = templ.replace(/%7B/g,'{');
				templ = templ.replace(/%7D/g,'}');
				templ = templ.replace(/%23/g,'#');
				var templ = new Template(templ);
				var templ_copy = templ.evaluate({sku: sku});
				// replacing the document id from missing image to correct image
				templ_copy = templ_copy.replace(new RegExp(that.conf.missing_image_id,"g"), imageId);
				$('wishlist-replacer').innerHTML += templ_copy;
				
				// Setting configuration for new wished product
				config.set('wishlist-item-'+sku, {linkparams: {prodid: sku, image: imageId}});				
			});
			
			// refreshing dropzones if wishlist is available
			if (window.wishlist) this.initdropzone();
			
			params.set('products', values.join(','));
			
			// setting postvalues toadd or remove products within the ajax request
			if(AddProductSKU) var params = {AddProductSKU: AddProductSKU};
			if(RemoveProductSKU) var params = {RemoveProductSKU: RemoveProductSKU};
			
			
			if (!this.cm)
				this.cm = new CookieManager();
			var isLoggedIn = this.cm.getCookie('IsLoggedIn');
			
			if((isLoggedIn == 'Yes') && (AddProductSKU || RemoveProductSKU)) {
				var that = this;
				new Ajax.Request(this.conf.ajaxurl_show, {
					parameters: params,
					method: 'post',
					onSuccess: function(response){
						var len = that.wished.length;
						for(var i=0; i<len; i++){								
							that.wished[i].destroy();
							delete that.wished[i];
						}
						that.wished = [];
						//if (AddProductSKU || RemoveProductSKU) new Effect.Highlight($("wishlist-replacer"), {startcolor:'#dedede', endcolor:'#ffffff', restorecolor:'#ffffff'});
						wishlist.initdropzone();
					}			
				});
				
			}
			
		}		
	}
});


/* -------------------------------------------------------------------
	=DragObj
 ------------------------------------------------------------------ */
 
var DragObj = Class.create({
	initialize: function(elm, params){	
		this.elm 			= elm;
		this.elmID 			= elm.id;	
		this.dragHandle 	= null;
		
		this.params = params || {};
		
		this.dragging 	= false;
		this.mousePos	= [-1,-1]
		
		this.elm.setStyle({cursor: 'hand'});		
		
		this.boundMouseDown 	= this.mouseDown.bindAsEventListener(this);
		this.boundMouseUp 	= this.mouseUp.bindAsEventListener(this);
		this.boundMouseMove 	= this.mouseMove.bindAsEventListener(this);
		
		this.elm.observe('mousedown', this.boundMouseDown);				
	},
	destroy: function(){
		Event.stopObserving(this.elm, "mousedown", this.boundStartDrag);
		delete this.boundMouseDown;
		delete this.boundMouseUp;
		delete this.boundMouseMove;
	},
	mouseDown: function(e){
		if (!Event.isLeftClick(e))
			return;
		
		this.startPos = [Event.pointerX(e), Event.pointerY(e)];
		
		document.observe('mousemove', this.boundMouseMove);
		document.observe('mouseup', this.boundMouseUp);
			
		Event.stop(e);
	},
	startDrag: function(point){
		this.dragHandle = Builder.node('div',{id:'drag-handle', style: 'width:50px; height:50px; position: absolute; cursor: hand; top:'+point[1]+'px; left:'+point[0]+'px; z-index:1000'}, [
							Builder.node('div',{style: 'width:50px; height:50px; position: absolute; top:0px; left:0px;'}),
							Builder.node('img',{id:'drag-img', width:'50', height:'50', src:this.elm.readAttribute('src')})
						]);
		Element.extend(this.dragHandle);
		$$('body')[0].insert({top: this.dragHandle});
		
		window.focus();
		
		this.dragHandle.setOpacity(0.8);		
		this.dragging = true;		
	},
	mouseUp: function(e){
		Event.stopObserving(document, "mousemove", this.boundMouseMove);
		Event.stopObserving(document, "mouseup", this.boundMouseUp);
		if (this.dragHandle)
			this.dragHandle.remove();
		this.dragging = false;
		
		DropZones.show(this.mousePos, this.elm);
		
		dropped = DropZones.fire(e, this.elm); 
		if (!dropped) dropped = false;
      
		if(dropped && this.params.onDropped) this.params.onDropped(this.elm, dropped);
	},
	mouseMove: function(e){	
		Event.stop(e);
		var newMousePos = [Event.pointerX(e), Event.pointerY(e)];
		
		if (!this.dragging){
			if (Math.abs(this.startPos[0]-newMousePos[0])+Math.abs(this.startPos[1]-newMousePos[1]) > 20){
				this.startDrag(newMousePos);				
			}
			return;
		}
				
		if ( (newMousePos[0] == this.mousePos[0]) && (newMousePos[1] == this.mousePos[1]) ){
			return;
		}
		
		this.mousePos = newMousePos;
		
		this.dragHandle.setStyle({left: this.mousePos[0] - 50/2 +'px', top: this.mousePos[1] - 50/2 +'px'});
	}
});


/* -------------------------------------------------------------------
	=DropZones
 ------------------------------------------------------------------ */

/* already an instance - not a class! */
var DropZones = {
	zones: [],
	currentActive: null,

	add: function(elm, params) {
		if (!params) 
			params = {};
		zone = {elm: elm};
		zone.onDrop = params.onDrop && Object.isFunction(params.onDrop) ? params.onDrop : null;
		zone.accept = params.accept ?  [params.accept].flatten() : null;

		Element.makePositioned(elm); // fix IE
		this.zones.push(zone);
	},
	show: function(point, elm) {
		if(!this.zones.length) return;
		var zone, affected = [];
    
		this.zones.each(function(zone){
			if(DropZones.isAffected(point, elm, zone))
			affected.push(zone);
		});

		if(affected.length>0)
			zone = DropZones.findDeepestChild(affected);
		if(this.currentActive && this.currentActive != zone) 
			this.deactivate(this.currentActive);
		if (zone) {
			Position.within(zone.elm, point[0], point[1]);
			if (zone != this.currentActive) DropZones.activate(zone);
		}
	},	
	findDeepestChild: function(zones){
		deepest = zones[0];
      
		for (i = 1; i < zones.length; ++i)
			if (Element.isParent(zones[i].elm, deepest.elm))
				deepest = zones[i];
    
		return deepest;
	},
	isAffected: function(point, elm, zone) { 		
		return (
      (zone.elm!=elm) &&
      ((!zone.accept) || (Element.classNames(elm).detect( 
          function(v) { return zone.accept.include(v) } ) )) && 
      Position.within(zone.elm, point[0], point[1]) );
  	},
	activate: function(zone) {		
		this.currentActive = zone;
	},
	deactivate: function(zone) {		
		this.currentActive = null;
	},
	fire: function(e, elm) {
		if(!this.currentActive) return;
		Position.prepare();

		if (this.isAffected([Event.pointerX(e), Event.pointerY(e)], elm, this.currentActive))
			if (this.currentActive.onDrop) {
				this.currentActive.onDrop(elm, this.currentActive.elm, e); 
				return this.currentActive.elm; 
			}
	}
};					


/* -------------------------------------------------------------------
	=WishableProduct
 ------------------------------------------------------------------ */
 
var WishableProduct = Class.create({
	initialize: function(elm){	
		this.elm 	= elm;
		this.elmID 	= elm.id;
		this.conf = config.get(this.elmID);
				
		if (this.conf && this.conf.linkparams){
			this.boundDrop = this.drop.bind(this);
		
			this.dragObj = new DragObj(elm, {
				onDropped: this.boundDrop
			});				
		}
		
		Destroyer.register(elm, 'WishableProduct', this);
	},	
	destroy: function(){		
		if (this.conf && this.conf.linkparams){
			this.dragObj.destroy();
			delete this.boundDrop;
			delete this.dragObj;
		}
		Destroyer.unregister(this.elm, 'WishableProduct', this);
	},
	drop: function(drag, dropped){
		add2WishList(this.conf.linkparams);
	}
});


/* -------------------------------------------------------------------
	=WishedProduct
 ------------------------------------------------------------------ */
var WishedProduct = Class.create({
	initialize: function(elm){	
		this.elm 	= elm;
		this.elmID 	= elm.id;
		// show element because template is hidden
		this.elm.show();
		this.conf = config.get(this.elmID);			
		
		if (this.conf && this.conf.linkparams && window.wishlist){
			this.boundDrop = this.drop.bind(this);
		
			this.dragObj = new DragObj(elm, {
				onDropped: this.boundDrop
			});				
		}
		
		Destroyer.register(elm, 'WishedProduct', this);
	},
	destroy: function(){
		this.dragObj.destroy();
		delete this.boundDrop;
		delete this.dragObj;
		Destroyer.unregister(this.elm, 'WishedProduct', this);
	},
	drop: function(drag, dropped){
		if (dropped.id!='tile-wishlist') {
			window.wishlist.removeElement(null, this.conf.linkparams);
		}
	}
});


/* -------------------------------------------------------------------
	=CookieManager
 ------------------------------------------------------------------ */

var CookieManager = Class.create({    
	initialize: function(){
    	this.BROWSER_IS_OPERA = (navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	},
	getCookie: function(cookieName){
		var result = null;
		for (var i = 0; i < document.cookie.split('; ').length; i++){
			var crumb = document.cookie.split('; ')[i].split('=');
			if (crumb[0] == cookieName && crumb[1] != null){
				result = crumb[1];
				break;
			}
		}

		if (this.BROWSER_IS_OPERA && result != null){
			result = result.replace(/%22/g, '"');
		}
		return result;
	},
	getCookieAttr: function(cookieName, cookieAttr){
		var result = null;
		var cookieValue = unescape(this.getCookie(cookieName));
		if (cookieValue && cookieValue.length>0){
			
			var pairs = cookieValue.split('|');
			for (var i=0; i<pairs.length; i++){			
				var pair = pairs[i].split('=');				
				if (pair[0]==cookieAttr){
					result = pair[1];
				}
			}		
		}		
		
		return result;
	}, 
	setCookie: function(cookieName, cookieValue, cookieLifeTime){
		if (this.BROWSER_IS_OPERA){
			cookieValue = cookieValue.replace(/"/g, "%22");
		}
		if (cookieValue==''){
			this.clearCookie(cookieName);
			return;
		}
		
		var date = new Date();
		date.setTime(date.getTime() + (cookieLifeTime * 24*60*60*1000));
		var expires = cookieLifeTime>0 ? ('; expires=' + date.toGMTString()) : '';		
		document.cookie = cookieName + '=' + cookieValue + expires + '; path=/';     
	},
	setCookieAttr: function(cookieName, cookieAttr, cookieAttrValue, cookieLifeTime){
		if (this.BROWSER_IS_OPERA){
			cookieAttr = cookieAttr.replace(/"/g, "%22");
		}
		
		var asso = new Hash();
				
		var cookieValue = unescape(this.getCookie(cookieName));
		if (cookieValue && cookieValue.length>0){
			var pairs = cookieValue.split('|');
			for (var i=0; i<pairs.length; i++){				
				var pair = pairs[i].split('=');				
				if (pair.length>1)
					asso.set(pair[0], pair[1]);
			}							
		}

		asso.set(cookieAttr, cookieAttrValue);
		
		if (cookieAttrValue==''){
			asso.unset(cookieAttr);			
		}
		
		var cookieStr 	= '';
		var keys 		= asso.keys();
		var values 		= asso.values();
		if (keys && keys.length>0){						
			for(var i=0; i<values.length; i++){
				cookieStr+=keys[i]+'='+values[i]+((i<values.length-1)?'|':'');
			}
		}
				
		this.setCookie(cookieName, escape(cookieStr), cookieLifeTime);		
	},
	clearCookie: function(cookieName){
		document.cookie = cookieName + '=;expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';
	}
});


/* -------------------------------------------------------------------
	=ImgPreload
 ------------------------------------------------------------------ */
var ImgPreload = {
	imgs: new Hash(),			
	
	// preload an img (key, imgsrc)
	preload: function(vname, src){		
		if (!this.imgs.get(src)){
			var img = new Image();
			img.src = src;					
			this.imgs.set(vname, img)
		}
	},
	// replace src of img with id 'id' with saved src
	replace: function(id, vname){
		if (this.imgs.get(vname)){
			$(id).src = this.imgs.get(vname).src;
		}
	}								
}
// simple shortcut for giftcard-preview
function showGCard(vname){
	ImgPreload.replace('giftcardbig', vname);
}
			
/* -------------------------------------------------------------------
	=Destroyer
 ------------------------------------------------------------------ */
 
var Destroyer = {
	obj: new Hash(),
	genericPrefix: 'deystroygeneric_',
	genericNr: 		0,
	classHint: 		'destroyableObj',
	
	
	// register an element with attache destroyable object 
	register: function(elm, objName, ref2Obj){		
		var id = elm.id;		
		if (!id){		
			id = this.genericPrefix+(++this.genericNr);
			elm.id = id;
		}	
		
		//console.log('register: #'+id+': '+objName);
		
		if (!Object.isArray(this.obj.get(id))){
			this.obj.set(id, []);
		}

		var tmp = this.obj.get(id);
		if (!Object.isArray(tmp))	tmp = [];
		tmp.push([objName, ref2Obj]);
		this.obj.set(id, tmp);
		
		elm.addClassName(this.classHint);
	},
	// destroy each registered object below an element
	destroySubElmObjects: function(elm){	
		var subElms	= [];
		var index 	= 0;
		var tmp 		= null;
		
		// gathering of elements depending on existance of an id
		if (elm.id){
			subElms = $$('#'+elm.id+' .'+this.classHint);
		} else {			
			while (tmp = elm.down('.'+this.classHint, index++)){
				subElms.push(tmp);
			}
		}

		for(var i=subElms.length-1; i>=0; i--){
			this.destroyElmObjects(subElms[i]);
		}
	},	
	// destroy every object bundled with an given element
	destroyElmObjects: function(elm){

		var id = elm.id;
		if (!id)
			return;

		var elmObjects = this.obj.get(id);
		if (Object.isArray(elmObjects)){		
			for(var i=0; i<elmObjects.length; i++){			
				if (Object.isFunction(elmObjects[i][1].destroy)){
					if (elmObjects[i][1].destroy) elmObjects[i][1].destroy();
				}
			}
		}
	},
	// unregister destroyable object
	unregister: function(elm, objName, ref2Obj){		
		var id = elm.id;
		if (!id)
			return;
		
		//console.info('unregister: #'+id+': '+objName);
		
		var elmObjects = this.obj.get(id);			
		
		if (Object.isArray(elmObjects)){
			var prevLength = elmObjects.length;
			var newArray = [];
			for(var i=0; i<prevLength; i++){				
				if ((elmObjects[i][0]!=objName) || (elmObjects[i][1]!=ref2Obj)){
					newArray.push(elmObjects[i]) 
				}				
			}
			if (newArray.length==0){
				this.obj.unset(id);
				elm.removeClassName(this.classHint);
			} else {
				this.obj.set(id, newArray);
			}
		}		
	}
};	

// destroy everything after pageunload
Event.observe(window, 'unload', function(){
	Destroyer.destroySubElmObjects($$('body')[0]);
});

/* -------------------------------------------------------------------
	=general
 ------------------------------------------------------------------ */
// px -> em
function px2em(px){
	var back = px/11;	
	return back;
}

// popupopener
function openPopup(url, params){
	var params;
	if (!params)
		params = {};	

	// handle default-values
	if (!params.name) params.name = 'popup';
	params.width	= params.width ? parseInt(params.width) : 640;
	params.height	= params.height ? parseInt(params.height) : 400;		
	params.scrollbars	=  ['yes','no'].indexOf(params.scrollbars)>-1  	? params.scrollbars 	: 'no';	
	params.location	=  ['yes','no'].indexOf(params.location)>-1  	? params.location 	: 'no';	
	params.menubar		=  ['yes','no'].indexOf(params.menubar)>-1  		? params.menubar 		: 'no';	
	params.status		=  ['yes','no'].indexOf(params.status)>-1  		? params.status 		: 'no';		
	params.toolbar		=  ['yes','no'].indexOf(params.toolbar)>-1  		? params.toolbar 		: 'no';			
	
	var paramstring = "width="+params.width+",height="+params.height+",scrollbars="+params.scrollbars+",location="+params.location+",menubar="+params.menubar+",status="+params.status+",toolbar="+params.toolbar;	
	var pop = window.open(url, params.name, paramstring);
	pop.focus();			
}

// merges variable length of hashes
function hashMerge(){
	var back = new Hash();
	if (arguments.length>0){
		for (var i=0; i<arguments.length; i++){
			if (arguments[i]){
				back = back.merge(arguments[i]);
			}
		}	
	}

	return back;
}

/* calculates content-dimensions */
function getPageSize(){
  
  var xScroll, yScroll;

	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	
//	if (self.innerHeight) {	// all except Explorer
//		if(document.documentElement.clientWidth){
//			windowWidth = document.documentElement.clientWidth; 
//		} else {
//			windowWidth = self.innerWidth;
//		}
//		windowHeight = self.innerHeight;
//	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
//		windowWidth = document.documentElement.clientWidth;
//		windowHeight = document.documentElement.clientHeight;
//	} else if (document.body) { // other Explorers
//		windowWidth = document.body.clientWidth;
//		windowHeight = document.body.clientHeight;
//	}	
	
	// using Prototype's viewport measurement instead of proprietary one above 
	windowWidth = document.viewport.getWidth();
	windowHeight = document.viewport.getHeight();
	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}
	
	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = xScroll;		
	} else {
		pageWidth = windowWidth;
	}
	
	return [pageWidth,pageHeight];
}

/* show lightbox */
function showLightBox(url, params, classparam){
	if (!window.alb){
		window.alb = new AjaxLightbox();
	}
	
	var css		= 'alert';
	if ((typeof(classparam) != 'undefined') ) {
		css = classparam;
	}	
	
	if(!window.alb.active) {
		window.alb.show(url, params, css);
	} else {
		window.alb.queue.push(url);
		window.alb.queue.push(params);
		window.alb.queue.push(css);
		window.alb.close();
	}
}

/* wishlist hinzufuegen */
function add2WishList(params){
	if (window.wishlist){
		window.wishlist.addElement(null, params);
	}						
}

/* sanitizes the sub-features (e.g. print, recommmend) position in IE6 */
function sanitizeSubFeatures(ie6down){
	if(ie6down==null)
		ie6down = isIE6OrLess();	
	if(ie6down) {
		$$('.headblock .sub-features').each(function(elm){
			if (elm) elm.style.bottom = '0';
		});
	}
}



var config = new Hash();

// array with anonymous init-functions
var initFunctions = new Array();

// big standard-initfunction
initFunctions.push(function(){
	var ie6down = isIE6OrLess();	

	$('meta-sites', 'meta-service', 'meta-account').each(function(elm){
		if (elm) new MetaPulldown(elm, {top: 21, activation: 'click', animation: 'both'});
	});
	
	if ($('meta-country')){
		new CountrySelectPulldown($('meta-country'), {top: 21, activation: 'click', animation: 'both', pdnoclick: true, noautoclose: true, selectprotect: ie6down});
		countryselect = new CountrySelect();
	}	
	
	$$('#mnav .pd-handle').each(function(elm){
		if (elm) new JSPulldown(elm, {top: 27, activation: 'mouseover', animation: 'open', selectprotect: ie6down});
	});

	$$('#snav .pd-handle').each(function(elm){
		if (elm) new JSPulldown(elm, {top: 20, activation: 'click', animation: 'both'});
	});
		
	$$('.pulldown').each(function(elm){
		if (elm) new JSPulldown(elm, {top: 18, activation: 'click', animation: 'both'});
	});

	$$('.mod-prodpager').each(function(elm){
		if (elm) new ProdPager(elm, {});
	});

	$$('.mod-singleprodpager').each(function(elm){
		if (elm) new SingleProdPager(elm);
	});	

	$$('.hintcontent').each(function(elm){
		if (elm) new PrefilledInput(elm);
	});

	$$('.wishable').each(function(elm){
		if (elm) new WishableProduct(elm);
	});
	
	if(isIE6OrLess() != true){
		$$('.ttip').each(function(elm){
			if (elm) new TTip(elm);
		});
	}
	
	$$('.imgbutton').each(function(elm){
		if (elm) new ImgButton(elm);
	});
	
	sanitizeSubFeatures.delay(2, ie6down);
	
	showSifr();

});

function switchThumbnail(elm, source) {
	this.elm = elm;
	this.src = source;

	var img = new Image();
	img.src = this.src;
	
	$('detail-img').setAttribute('src', img.src);

	Element.extend(this.elm);
	
	this.elm.up().up().down('.active').removeClassName('active');
	this.elm.up().addClassName('active');	
	this.elm.blur();	
	
	if (this.elm.up(1).down(0).hasClassName('active')) {
		this.elm.up(2).down(".sub-featurebuttons").setStyle({visibility: 'visible'});
		$('img_link_zoom').removeClassName('unlink');
		$('detail-img').removeClassName('untip');
	} else {
		this.elm.up(2).down(".sub-featurebuttons").setStyle({visibility: 'hidden'});
		$('img_link_zoom').addClassName('unlink');
		$('detail-img').addClassName('untip');
	}
}


function hoverMe(idRoot) {
	this.root = idRoot;
	
	$(this.root + '_reg').hide();
	$(this.root + '_hov').show();
}

function unhoverMe(idRoot) {
	this.root = idRoot;
	
	$(this.root + '_hov').hide();
	$(this.root + '_reg').show();
}

function showSifr() {
	if( (typeof sIFR == "function") && (config.get('sifr')) ){
		sIFR();
		sIFR.replaceElement("h3.sIFR-wantsFlash .S1R, h3.sIFR-wantsFlash .S2R", named({sFlashSrc: config.get('sifr').pathprefix + "didot_regular.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center", sWmode: "opaque"}));
		sIFR.replaceElement("h3.sIFR-wantsFlash .S1I, h3.sIFR-wantsFlash .S2I", named({sFlashSrc: config.get('sifr').pathprefix + "didot_italic.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center", sWmode: "opaque"}));
		sIFR.replaceElement("div.sIFR-wantsFlash", named({sFlashSrc: config.get('sifr').pathprefix + "didot_italic.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center"}));
	};
}

function showSifrLayered() {
	if((typeof sIFR == "function") && (config.get('sifr')) ){
		sIFR();
		sIFR.replaceElement("h3.sIFR-wantsFlash .S1R, h3.sIFR-wantsFlash .S2R", named({sFlashSrc: config.get('sifr').pathprefix + "didot_regular.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center"}));
		sIFR.replaceElement("h3.sIFR-wantsFlash .S1I, h3.sIFR-wantsFlash .S2I", named({sFlashSrc: config.get('sifr').pathprefix + "didot_italic.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center"}));
		sIFR.replaceElement("div.sIFR-wantsFlash", named({sFlashSrc: config.get('sifr').pathprefix + "didot_italic.swf", sColor: "#4a4a4a", sFlashVars: "textalign=center"}));
	};
}

// print call out of feature-line
function printPage() {
	window.print();
}


// recommend call out of feature-line
function recommend(params){
	var tmp = config.get('paths');
	if (tmp && tmp.recommend){	
		showLightBox(tmp.recommend, params, 'zoom');
	}
}


function checkVoucher(ajaxurl) {
	new Ajax.Request(ajaxurl, {
		parameters: $('vouchercode').serialize(true),
		method: 'post',
		onSuccess: function(transport){
			var response = transport.responseText || "Validation offline. Please try again later.";
		  	if (response.strip()=="ok") {
		  		document.voucher.submit();
				$('vouchererror').hide();		  		
		  	} else {
			  	$('vouchererror').update(response);
			  	$('vouchererror').show();
		  	}
		},
		onFailure: function(){ 
			$('vouchererror').update('No connection. Please try again.');
			$('vouchererror').show();
		}				
	});	
}

function recommendPage(ajaxurl) {
	new Ajax.Request(ajaxurl, {
		parameters: $('recommendform').serialize(true),
		method: 'post',
		onSuccess: function(transport){
			var response = transport.responseText || "<p class=#error'>Recommendation service offline. Please try again later.</p>";
		  	$('recommenddiv').update(response);
		},
		onFailure: function(){ 
			var elm = document.createElement('p')
			var txt = document.createTextNode('No connection. Please try again.');
			elm.appendChild(txt);
			elm.addClassName('error');
			$('recommenddiv').insertBefore(elm, $('recommendform'));
		}				
	});	
}

function subscribeNewsletter(ajaxurl) {
	new Ajax.Request(ajaxurl, {
		parameters: $('subscribeform').serialize(true),
		method: 'post',
		onSuccess: function(transport){
			var response = transport.responseText || "<p class=#error'>Registration service offline. Please try again later.</p>";
		  	$('replaceme').update(response);
		},
		onFailure: function(){ 
			var elm = document.createElement('p')
			var txt = document.createTextNode('No connection. Please try again.');
			elm.appendChild(txt);
			elm.addClassName('error');
			$('subscribediv').insertBefore(elm, $('subscribeform'));
		}				
	});	
}

function unsubscribeNewsletter(ajaxurl) {
	new Ajax.Request(ajaxurl, {
		parameters: $('unsubscribeform').serialize(true),
		method: 'post',
		onSuccess: function(transport){
			var response = transport.responseText || "<p class=#error'>Registration service offline. Please try again later.</p>";
		  	$('replaceme').update(response);
		},
		onFailure: function(){ 
			var elm = document.createElement('p')
			var txt = document.createTextNode('No connection. Please try again.');
			elm.appendChild(txt);
			elm.addClassName('error');
			$('unsubscribediv').insertBefore(elm, $('unsubscribeform'));
		}				
	});	
}


// checks, if ie6 or less (feedback: true|false)
function isIE6OrLess(){
	var agt=navigator.userAgent.toLowerCase();
	var is_major = parseInt(navigator.appVersion);
	var is_minor = parseFloat(navigator.appVersion);
	var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	return (is_ie && (is_major == 4) && (agt.search(/msie [56]\./)!=-1) );
}

// hides all selects
function hideSelects(){
	$$('select').each(function(elm){

		if (elm) elm.setStyle({ visibility: 'hidden' });
	});
	if ($('select_countrymeta')) $('select_countrymeta').setStyle({ visibility: 'visible' });
}

// shows all selects
function showSelects(){
	$$('select').each(function(elm){		
		if (elm) elm.setStyle({ visibility: 'visible' });
	});
}


 // ------- Private vars -------
var storySWFReady = false;

// called to notify the page that the SWF has set it's callbacks
function storySWFIsReady() {
// record that the SWF has registered it's functions (i.e. that JavaScript
// can safely call the ActionScript functions)
	storySWFReady = true;
}



/* These functions are necessary for the Virtual Tout Layer (loaded via AJAX) to work */

function makeActive(elm) {
	Element.extend(elm);
	$$('#tourlayer .sub-positioner a.active').each(function(elms){
		elms.removeClassName("active");
	});
	elm.addClassName("active");
}

function showViewpoint(num) {
	swfobject.embedSWF(config.get("tourconf").swf_path, "tourcontainer", "380", "280", "8.0.0", false, {"path": config.get("tourconf").content_path[num]}, {wmode: "transparent"}, {});
}

function correctPagefooter() {
	// correct pagefooter
	var pf = $('page-footer');
	if (pf){
		if (!pf.up('#wrap-bottom')){
			var arrayPageSize = getPageSize();
			var height = pf.getHeight();
			var arrayOffset = pf.cumulativeOffset();
			if (arrayOffset[1]+height<arrayPageSize[1]){
				pf.setStyle({position: 'relative', top: (arrayPageSize[1] - arrayOffset[1] - height) + 'px'})
			}
		}
	}		
}

/* initializing on dom:loaded... */
document.observe('dom:loaded', function(){
	if (!window._init){
		// save, that init-process already done
		window._init = true;
		
		for (var i=0; i<initFunctions.length; i++){
			initFunctions[i]();
		}				
	}
});
/* ...  or if not available also window.load */
Event.observe(window, 'load', function(){
	if (!window._init){
		window._init = true;
		
		for (var i=0; i<initFunctions.length; i++){
			initFunctions[i]();
		}				
	} 
	
	correctPagefooter();
	
});

/**
 *  Start TP/SL: Changing specific styles for IE6

 */

function openLightbox( linkId, classname ){
	var ajaxLink = $(linkId);
	(window.alb = !window.alb ? new AjaxLightbox() : window.alb).show( ajaxLink, {}, classname || 'zoom' );
}

var Slideshow = Class.create({
	
	initialize: function(){
		
		this.forward = $('slForward');
		this.backward = $('slBackward');
		this.container = $('galleryContainer');
		
		if( !this.container ) 
			return;
		
		if( this.forward )
			this.forward.observe( 'click', this.nextImage.bind( this ) );

		if( this.backward )
			this.backward.observe( 'click', this.prevImage.bind( this ) );
	},
	
	nextImage: function( e ){
		this.load( this.forward.readAttribute( 'href' ));
		Event.stop( e );
	},
	
	prevImage: function( e ){
		this.load( this.backward.readAttribute( 'href' ));
		Event.stop( e );
	},
	
	load: function( url ){
		if( !url )
			return;
		
		var ajax = new Ajax.Request( url, {
			method: 'get',
		  	onSuccess: function( transport ) {
					
				var that = this;
				var imgBox = $('imagebox');

				new Effect.Opacity( imgBox, { 
					duration: 0.5, 
					transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal, 
					from: 1, 
					to: 0,
					afterFinish: function() {

						imgBox.setOpacity(0);
						that.container.update( transport.responseText );

						new Effect.Opacity( $('imagebox'), { // ie8 needs a fresh selected element, can't reuse imgBox
							duration: 0.5, 
							transition: Effect.Transitions.EaseFromTo ? Effect.Transitions.EaseFromTo : Effect.Transitions.sinoidal, 
							from: 0,
							to: 1
						});
						
					}
				});
			}.bind( this )
		} );
	}
});

initFunctions.push(function() {
		if(isIE6OrLess() == true) {
			
			// changing pulldown backgrounds because alpha-pngs are used
			var arrOutElements = new Array('#page-head .sh-out','.sh-out-pulldown','#snav-category-pd .sh-out','#snav-explore-pd .sh-out');
			arrOutElements.each(function(OutElement) {
				$$(OutElement).each(function(Element) {
						Element.setStyle({backgroundImage:'none'});
						Element.setStyle({padding:'0px'});
				});
			});
			
			// changing pulldown backgrounds because alpha-pngs are used
			var arrInElements = new Array('#page-head .sh-in','.sh-in-pulldown','#snav-category-pd .sh-in','#snav-explore-pd .sh-in');
			arrInElements.each(function(InElement) {
				$$(InElement).each(function(Element) {
					Element.setStyle({backgroundImage:'none'});
					Element.setStyle({borderRight:'#CCC 1px solid'});
					Element.setStyle({borderLeft:'#CCC 1px solid'});
					Element.setStyle({borderBottom:'#CCC 1px solid'});
					Element.setStyle({padding:'0px'});
					Element.setStyle({margin:'0px 5px 8px 5px'});
				});
			});
			
		}
		
		// If user is logged in adapt the metanavigation my account
		if (!this.cm)
			this.cm = new CookieManager();
		var isLoggedIn = this.cm.getCookie('IsLoggedIn');

		if(isLoggedIn == 'Yes') {
			if($('meta_li_login')) $('meta_li_login').hide();
			if($('nav_li_login')) $('nav_li_login').hide();			
			if($('meta_li_register')) $('meta_li_register').hide();
			if($('nav_li_register')) $('nav_li_register').hide();
		} else {
			if($('meta_li_logout')) $('meta_li_logout').hide();
			if($('nav_li_logout')) $('nav_li_logout').hide();
			if($('meta_li_profile')) $('meta_li_profile').hide();
			if($('nav_li_profile')) $('nav_li_profile').hide();
		}
});
/**
 *  End TP/SL
 */