/* All java script logic for the Demandware reference application.
 *
 *
 * The code relies on the prototype.js and scriptaculous.js libraries to
 * be also loaded.
 */

// IMPORTANT!!! This removes flickering of background images in IE
try {
	document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}

/*
 * Register more initializations here
 */
window.onload = function()
{
	// Don't initialize things this way!!! It's bad, evil and not recommended.
}

/* Extend element */
Element.addMethods({
	
	/* Return dimensions of an element */
	dimensions : function(element) {
		var vpOffset = element.viewportOffset();
		return {
			minX: vpOffset.left,
			minY: vpOffset.top,
			maxX: vpOffset.left + element.getWidth(),
			maxY: vpOffset.top + element.getHeight()
		};
	},

	/* checks if a element overlaps another one */
	overlaps : function(element, el) {
		var elDim = el.dimensions();
		var myDim = element.dimensions();

		return (((myDim.minX >= elDim.minX && myDim.minX <= elDim.maxX) || (myDim.maxX > elDim.minX && myDim.minX < elDim.maxX)) &&
        	((myDim.minY >= elDim.minY && myDim.inY <= elDim.minY) || (myDim.maxY > elDim.minY && myDim.minY < elDim.maxY)));
	}
});

/**
 * Event.simulate(@element, eventName[, options]) -> Element
 *
 * - @element: element to fire event on
 * - eventName: name of event to fire (only MouseEvents and HTMLEvents interfaces are supported)
 * - options: optional object to fine-tune event properties - pointerX, pointerY, ctrlKey, etc.
 *
 * $('foo').simulate('click'); // => fires "click" event on an element with id=foo
 *
 * @see http://github.com/kangax/protolicious/blob/e5091a8051d57d62ae54bb906b16435fa638d75d/event.simulate.js
 **/
(function(){
  
	var eventMatchers = {
		'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
		'MouseEvents': /^(?:click|mouse(?:down|up|over|move|out))$/
	}
	var defaultOptions = {
		pointerX: 0,
		pointerY: 0,
		button: 0,
		ctrlKey: false,
		altKey: false,
		shiftKey: false,
		metaKey: false,
		bubbles: true,
		cancelable: true
	}
  
	Event.simulate = function(element, eventName) {
		var options = Object.extend(defaultOptions, arguments[2] || { });
		var oEvent, eventType = null;
    
		element = $(element);
    
		for (var name in eventMatchers) {
			if (eventMatchers[name].test(eventName)) { eventType = name; break; }
		}
 
		if (!eventType)
			throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
 
		if (document.createEvent) {
			oEvent = document.createEvent(eventType);
		if (eventType == 'HTMLEvents') {
			oEvent.initEvent(eventName, options.bubbles, options.cancelable);
		} else {
			oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
					options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
					options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
		}
		element.dispatchEvent(oEvent);
	} else {
		options.clientX = options.pointerX;
		options.clientY = options.pointerY;
		oEvent = Object.extend(document.createEventObject(), options);
		element.fireEvent('on' + eventName, oEvent);
	}
	return element;
}
  
  Element.addMethods({ simulate: Event.simulate });
})()

/*
 * This function is used to submit forms in iBoxes and reload the content.
 */
function formSubmitToiBox(form, showLoadingPanel) {
	
	if (!$(form)) return;
	
	if (showLoadingPanel) {
		iBox.showLoading();
	}
	
	form.request({
		onComplete: function(transport) {
			iBox.show(transport.responseText);
		}
	});
}

/*
	Opens a new window with the provided url and dimension. Used
	for Scene7 and other situations.

	@param url the url to open
	@param width the window width
	@param height the window height
*/
function openPopup( url, width, height )
{
	if (url != null)
	{
		if (width != null && height != null)
		{
			window.open(url, "", "width=" + width +", height=" + height +", scrollbars=no, resizable=yes");
		}
		else
		{
			window.open(url, "", "scrollbars=no, resizable=yes");
		}
	}
}


/*
 * Support for the compare window
 */
ProductCompare = {
	openPopup: function( url ) {
		window.open(
			url,
			'product_compare',
			'width=800,height=600,scrollbars=yes,resizable=yes',
			true /* replace history in the popped up window */
		).focus();
	}
}


/*
 * Functionality around the mini cart.
 */
var MiniCart = {
	// flag, whether cart is open or not
	isDown: false,

	// timer for automatic close of cart item view
	timer: null,
	
	// the arrow in the minicart
	navlnk : null,
	
	// the image in the minicart
	cartlnk : null,	
	
	isSliding : false,
	
	init: function() {
		this.navlnk = $('navlnk');
		this.cartlnk = $('cartlnk');
		this.minicarthead = $('minicarttotal');

		if (!(this.navlnk || this.cartlnk)) {
			return;
		}
		Event.observe(this.navlnk,'click',this.handleClick.bind(this));
	
		Event.observe(this.cartlnk,'click',this.handleClick.bind(this));
		//Event.observe(this.cartlnk,'mouseover',this.handleMouseOver.bind(this));
		Event.observe(this.cartlnk,'mouseout',this.handleMouseOut.bind(this));
		Event.observe(this.navlnk,'mouseover',this.handleMouseOver.bind(this));
		Event.observe(this.cartlnk,'mouseover',this.handleMouseOver.bind(this));
	},
	setContent: function(req) {
        // replace the content
        var minicart = $('minicart');
        minicart.innerHTML = req.responseText;
        //minicart.setStyle({width: (MiniCart.getWidth()+4)+'px'});
        this.init();
    },

	
	cartOpen: function()
	{
    	if (this.isSliding!=true && !this.isDown) {
			this.isSliding=true;
			Effect.SlideDown('minicartcontent',{afterFinish:function(){
				this.timer = setTimeout( 'MiniCart.cartClose()', 2500 );		
				this.isDown=true;	
				this.cartlnk.style.backgroundPosition='0px -33px';
				this.navlnk.removeClassName('activeimg');
				this.navlnk.addClassName('inactiveimg');		
				this.isSliding=false;
			}.bind(this)});
    	}
	},	
	cartAdd: function(form, progressImageSrc) {
        //this.state = this.OPENING;
        // get the data of the form as serialized string
        var postdata = Form.serialize(form);
        // disable form
        Form.disable(form);

        /*var AddToBasketFrame = document.createElement("iframe");
        AddToBasketFrame.id ="AddToBasketFrame";
        AddToBasketFrame.src = MiniCart.analytics;
        AddToBasketFrame.className = "hidden";
        document.getElementsByTagName("body")[0].appendChild(AddToBasketFrame);
        */            
        
        // callback handler for ajax request
        var handlerFunc = function(req) {
            Form.enable(form);
            // insert data
            MiniCart.setContent(req);
            // clear timer
            if (MiniCart.timer != null) {
                clearTimeout(MiniCart.timer);
                if (!MiniCart.isSliding) MiniCart.isDown = false;
            }
            // change link to tab
            /*MiniCart.showTab();
            MiniCart.setLinkText();
            // open the minicart
            Effect.SlideDown('minicartcontent', {duration: 1.0});
            setTimeout('MiniCart.state = MiniCart.OPEN; MiniCart.showCloseButton();', 1000);
            // after a time out automatically close it
            MiniCart.timer = setTimeout( 'MiniCart.cartClose(); MiniCart.state=MiniCart.CLOSING', 8000 );
            */
            MiniCart.cartOpen();
            if (trackCart)
                trackCart();
        }

        var errFunc = function(req) {
            Form.enable(form);
            location.href=MiniCart.cartURL + '?MiniCartError=payment';
        }
        // add the product
        new Ajax.Request( MiniCart.url, {method:'post', postBody:postdata, onSuccess:handlerFunc, onFailure:errFunc});
    },

	cartClose: function()
	{
		this.isSliding=true;
		if ( this.timer != null )
		{
			clearTimeout( this.timer );
			this.timer = null;

			Effect.SlideUp('minicartcontent',{afterFinish:function(){
				this.isDown=false;	
				this.cartlnk.style.backgroundPosition='0px 0px';
				this.navlnk.removeClassName('inactiveimg');
				this.navlnk.addClassName('activeimg');		
				this.isSliding=false;
			}.bind(this)});
		}
	},
	
	handleMouseOver: function() {
		this.cartlnk.style.backgroundPosition='0px -33px';
		MiniCart.cartOpen();
	},
	
	handleMouseOut: function() {
		this.cartlnk.style.backgroundPosition='0px 0px';
	},
	
	handleClick: function() {
		if(!MiniCart.isSliding)
		{
			if (MiniCart.isDown) {
				MiniCart.cartClose();
			}
			else {
				MiniCart.cartOpen();
			}
		}
	}
}

var TopNavSelection = {
	initialize : function() {
		var selectedContentID = $('currentlySelectedContentId');
		$$('#mainmenu li a').each(function(element) {
			var params = element.href.toQueryParams();
			// when cid was not found as a parameter
			// try to parse it from the url
			if((!("cid" in params) || params.cgid == "") && element.href.match(/([^/]*),[^,]*,pg\.html/)) {
				params.cid = RegExp.$1;
			}
			if (element.href.endsWith('#')) {
				params.cid = null;
			}
			
			if (params.cid && selectedContentID && selectedContentID.value == params.cid) {
				element.up().addClassName('active');
			}
		});
	}
};

var SearchButton = {
	
	searchbtn : null,
	searchinput : null,
	hasFocus : false,
	
	hovertop : 20,
	outtop : 3,
	
	initialize : function() {
		this.searchbtn = $('SearchButton');
		this.searchinput = $('SearchInput');

		if (this.searchbtn && this.searchinput) {
			this.searchbtn.observe('mouseover', this.btnOver.bindAsEventListener(this, true));
			this.searchbtn.observe('mouseout', this.btnOver.bindAsEventListener(this, false));
			this.searchinput.select('input')[0].observe('focus', this.inputFocus.bindAsEventListener(this, true));
			this.searchinput.select('input')[0].observe('blur', this.inputFocus.bindAsEventListener(this, false));
		}
	},
	
	btnOver : function(ev, over) {
		if (over) {
			this.searchbtn.select('span').each(function(el) {
   				el.setStyle({
   					backgroundPosition: '0px -' + SearchButton.hovertop + 'px',
   					color: '#FFFFFF'
   				});
   			}); 
   			this.searchinput.setStyle({backgroundPosition: '0px -' + SearchButton.hovertop + 'px'});
		}
		else {
			if (!this.hasFocus) {
				this.searchbtn.select('span').each(function(el) {
	   				el.setStyle({
	   					backgroundPosition: '0px ' + SearchButton.outtop + 'px',
	   					color: '#444444'});
	   			}); 
	   			this.searchinput.setStyle({backgroundPosition: '0px ' + SearchButton.outtop + 'px'});
	   		}		
		}
	},
	
	inputFocus : function(ev, focus) {
		this.hasFocus = focus;
		this.btnOver(ev, focus);
	}	
};

var NewsletterButton = {
	
	newsletterbtn : null,
	newsletterinput : null,
	hasFocus : false,
	
	hovertop : 20,
	outtop : 3,
	
	initialize : function() {
		this.newsletterbtn = $('NewsletterButton');
		this.newsletterinput = $('NewsletterInput');

		if (this.newsletterbtn && this.newsletterinput) {
			this.newsletterbtn.observe('mouseover', this.btnOver.bindAsEventListener(this, true));
			this.newsletterbtn.observe('mouseout', this.btnOver.bindAsEventListener(this, false));
			this.newsletterinput.select('input')[0].observe('focus', this.inputFocus.bindAsEventListener(this, true));
			this.newsletterinput.select('input')[0].observe('blur', this.inputFocus.bindAsEventListener(this, false));
		}
	},
	
	btnOver : function(ev, over) {
		if (over) {
			this.newsletterbtn.select('span').each(function(el) {
   				el.setStyle({
   					backgroundPosition: '0px -' + NewsletterButton.hovertop + 'px',
   					color: '#FFFFFF'
   				});
   			}); 
   			
		    this.newsletterinput.setStyle({backgroundPosition: '0px -' + NewsletterButton.hovertop + 'px'});
		}
		else {
			if (!this.hasFocus) {
				this.newsletterbtn.select('span').each(function(el) {
	   				el.setStyle({
	   					backgroundPosition: '0px ' + NewsletterButton.outtop + 'px',
	   					color: '#444444'});
	   			}); 
   				this.newsletterinput.setStyle({backgroundPosition: '0px ' + NewsletterButton.outtop + 'px'});
   			}		
		}
	},
	
	inputFocus : function(ev, focus) {
		this.hasFocus = focus;
		this.btnOver(ev, focus);
	}	
};

var evilBrowserInformation = {
	isEvil : null,
	evilVersion : null
}

function checkEvilBrowser() {
	var isEvil = /msie\s(\d)/.test(navigator.userAgent.toLowerCase());
	var ieVersion = null;
	if (isEvil) {
		var ieVersion = RegExp.$1;
	}
	evilBrowserInformation.isEvil = isEvil;
	if (isEvil) {
		evilBrowserInformation.evilVersion = ieVersion;
	}
}

checkEvilBrowser();

/* IE6 Hover Fix */
var IE6HoverFix = Class.create({
 
	element: null,
 
	initialize: function(el) {
		if (evilBrowserInformation.isEvil && evilBrowserInformation.evilVersion < 7) {
			if (!el.hoverFixAttached) {
				this.element = el;
				this.element.observe('mouseenter', this.mouseOverHandler);
				this.element.observe('mouseleave', this.mouseOutHandler);
				this.element.hoverFixAttached = true;
			}
		}
	},
 
	mouseOverHandler: function(ev) {
		var element = Event.element(ev);
		element.addClassName('hover');
	},
 
	mouseOutHandler: function(ev) {
		var element = Event.element(ev);
		element.removeClassName('hover');
	}
});

function initIE6HoverFix() {
	if (evilBrowserInformation.isEvil && evilBrowserInformation.evilVersion < 7) {
		$$('.prodMini,a.instructionEl,a.highlProp,a.previous').each(function(el) {
			new IE6HoverFix(el);
		});
	}
}

/** 
 * Calls a function in ie6 only to fix a hover problem for elements which are inserted dynamically per XHR.
 * The function called is included per conditional comment.
 * @params obj 
 */
function imgLoaded(obj) {
	if (typeof IE6Hover !== 'undefined') {
		IE6Hover.fixXHRElement(obj);
	}
}

/*
 * Changes the product image on the search result page.
 * Updates the url of the image and the product link and the name of the product variant.
 * Uses in template 'product-mini'.
 */
function changeVariationImgUrl(element, parentElement, productTitleElement, imageUrl, productUrl, productName, badgeUrl) {
	var imgProd = $(element).up(parentElement).down('img.productImg');
	var prodLink = $(element).up(parentElement).down('a.productLogo');
	
	if (prodLink.href != productUrl) {
		imgProd.writeAttribute('src',imageUrl);
		prodLink.writeAttribute('href',productUrl);
		$(element).up(parentElement).down(productTitleElement).update(productName);
		
		$(element).up(parentElement).select('img.overlay').each(function(e) {
			if (e.hasClassName('selectColorBorder') && e!=$(element).down('img.overlay') ) {
	 			e.toggleClassName('selectColorBorder');
	 		}
	 	});
	
	 	if (!$(element).down('img.overlay').hasClassName('selectColorBorder')) {
	 		$(element).down('img.overlay').toggleClassName('selectColorBorder');
	 	}
	 	
	 	if (null != badgeUrl) {
	 		updatesBadges(element, badgeUrl);
	 	}
	}
}
 
function updatesBadges(source, url) {
	var container = typeof $(source).up("div.productmini") != "undefined" ? $(source).up("div.productmini").down("div.badgeImages") : $(source).up("div.teaser").down("div.badgeImages");
	new Ajax.Updater(container, url,{method:'get'});
}



/*
 * 
 * NaviMenu
 * 
 */

var NaviMenu = {
	menuElement: null,
	menuLayer: null,
	menuWrapper: null,
	topNavEntries: null,
	viewedElement: null,
	hiddenDropDowns: null,

	initialize: function() {
		this.menuElement = $('mainmenu');
		this.menuLayer = $('menu_layer');
		this.menuWrapper = $('menuWrapper');
		
		if (!this.menuElement || !this.menuLayer) {
			return false;
		}
		this.topNavEntries = this.menuElement.select('ul.menuItemList > li > a:first-child');
		this.topNavEntries.each(function(el) {
			var parentEl = el.up();			
			var hiddenMenu = parentEl.select('.hiddenMenu');
			if (hiddenMenu && hiddenMenu.length > 0) {
				el.hiddenMenu = hiddenMenu[0];
			}
			el.observe('mouseover', this.menuOver.bind(this));
			el.observe('mouseout', this.menuOut.bind(this));
		}.bind(this));
		this.menuLayer.observe('mouseover', this.layerOver.bind(this));
		this.menuLayer.observe('mouseout', this.layerOut.bind(this));
	},
	
	calculatePosition: function(el) {
		// TODO: <iframe src="" id="overwrite" style="position:absolute;z-index:-1"></iframe>
		var itemLeft = el.viewportOffset().left;
		var spaceLeft = (document.body.clientWidth - 988) / 2;
		
		var wrap = spaceLeft + 988 - (itemLeft + this.menuLayer.offsetWidth); //988: content width
		if (wrap < 0) {
			itemLeft = itemLeft + wrap;
		}
		itemLeft = itemLeft - 10; // 10: left shift relative to menuitem
		
		if (itemLeft < (spaceLeft + 9)) this.menuLayer.style.left = spaceLeft + 9 + 'px'; // 9: offset position relative to content left
		else this.menuLayer.style.left = itemLeft + 'px';
	    
		var rows = [this.menuWrapper.select('.submenu_box'), this.menuWrapper.select('.submenu_box_1')];
		rows.each(function(submenuBoxes) {
			var maxHeight = 0;
		    submenuBoxes.each(function(el) {
		    	var height = el.getDimensions().height;
		    	if (height > maxHeight) {
		    		maxHeight = height;
		    	}
		    });
		    submenuBoxes.each(function(el) {
		    	el.style.height = maxHeight + 'px';
		    });
		
		});
	    
		/*
		var lastEntries = this.menuWrapper.select('.last');
		if (lastEntries.length > 0) {
			var vertContainer = this.menuWrapper.select('.vertContainer');
			if (vertContainer.length > 0) {
				var vertContainerWidth = vertContainer[0].getDimensions().width;
				lastEntries.each(function(el) {
					if (el.getDimensions().width != vertContainerWidth) {
						el.style.width = vertContainerWidth + 'px';
					}
				});
			}
		}
		*/
		this.hideDropDowns();
	},
	
	show: function(el) {
		el.up().addClassName('hover');
		this.viewedElement = el;
		this.menuLayer.show();
	},
	
	hide: function(el) {
		el.up().removeClassName('hover');
		this.menuLayer.hide();
		if (this.hiddenDropDowns) {
			this.hiddenDropDowns.each(function(el) {
				el.style.visibility = 'visible';
			});
		}
		this.hiddenDropDowns = [];
	},
	
	hideDropDowns: function() {
		this.hiddenDropDowns = [];
		if (evilBrowserInformation.isEvil && evilBrowserInformation.evilVersion < 7) {
			$('main').select('select').each(function(el,i){
				if (el.overlaps(this.menuLayer)) {
					this.hiddenDropDowns.push(el);
					el.style.visibility = 'hidden';
				}
			}.bind(this));
		}
	},
	
	menuOver: function(ev) {
		var el = Event.element(ev);
		var hiddenMenu = el.hiddenMenu;
		if (hiddenMenu) {
			this.menuLayer.style.left = '10px';
			this.menuWrapper.update(hiddenMenu.innerHTML);
			this.show(el);
			this.calculatePosition(el);
			if (evilBrowserInformation.isEvil && evilBrowserInformation.evilVersion == 7) this.ie7ZoomFix();
		}
	},
	
	menuOut: function(ev) {
		this.hide(Event.element(ev));
	},
	
	layerOver: function(ev) {
		this.show(this.viewedElement);
		this.hideDropDowns();
	},
	
	layerOut: function(ev) {
		this.hide(this.viewedElement);
	},
	// fix for menu link salad in ie7 when zoom != 1 (Bug #246)
	ie7ZoomFix: function() {
		var els = this.menuWrapper.select('.listing > li > a');
		var cont;
		for (var i=0; i<els.length; i++) {
			cont = els[i].innerHTML
			els[i].innerHTML = '';
			els[i].innerHTML = cont;
		}
	}
};



/*
 * 
 * Buttons
 * 
 */
function overBtn(btn, hoverTop, outTop){
    $(btn).select('span').each(
    	function(el){
	   		el.setStyle({backgroundPosition: '0px -' + hoverTop + 'px'});
		}
	);
}
function outBtn(btn, hoverTop, outTop){
    $(btn).select('span').each(function(el) {
   		el.setStyle({backgroundPosition: '0px ' + outTop + 'px'});
    });
}

// 20px Buttons (grey border)
var smallhoverTop=20;
var smalloutTop=3;

// 26px Button (black or red background)
var normhoverTop=26;
var normoutTop=3;

// 19px Button (black background)
var smallBlackhoverTop=19;
var smallBlackoutTop=3;

/** IE Hacks **/
if (evilBrowserInformation.evilVersion == 6) {//if ie 6
    smallhoverTop=23;
    smalloutTop=0;
    
    // 26px Button (black or red background)
    var normhoverTop=29;
    var normoutTop=0;

    // 19px Button (black background)
    var smallBlackhoverTop=22;
    var smallBlackoutTop=0;    
}
if (evilBrowserInformation.evilVersion == 7) {
    smallhoverTop=23;
    smalloutTop=0;
    
    // 26px Button (black or red background)
    var normhoverTop=28;
    var normoutTop=1;

    // 19px Button (black background)
    var smallBlackhoverTop=22;
    var smallBlackoutTop=0;   
}

function BtnOver(btn){
    overBtn(btn, smallhoverTop, smalloutTop);
}
function BtnOut(btn){
    outBtn(btn, smallhoverTop, smalloutTop);
}

function normBtnOver(btn){
    overBtn(btn, normhoverTop, normoutTop);
}
function normBtnOut(btn){
    outBtn(btn, normhoverTop, normoutTop);
}

function smallBlackBtnOver(btn){
    overBtn(btn, smallBlackhoverTop, smallBlackoutTop);
}
function smallBlackBtnOut(btn){
    outBtn(btn, smallBlackhoverTop, smallBlackoutTop);
}

function smallBtnOver(btn){
    overBtn(btn, smallhoverTop, smalloutTop);
}
function smallBtnOut(btn){
    outBtn(btn, smallhoverTop, smalloutTop);
}

function formSubmit(domElement, name)
{
	var actEle = findParentForm(domElement);
	actEle.appendChild(getActionAsHiddenInput(name));			
	actEle.submit();
}

function iBoxFormSubmit(domElement, name, callback)
{
	var form = findParentForm(domElement);
	form.appendChild(getActionAsHiddenInput(name));			
	
	var postBody = Form.serialize(form);
	Form.disable(form);
	var ajaxUrl = form.action;
	
	var ajaxData = {
		method: 'post', 
		postBody: postBody, 
		onSuccess: function(transport) {
			iBox.show(transport.responseText);
			if(callback){
				callback();
			}
		}
	};	
	
	new Ajax.Request( ajaxUrl, ajaxData );
}

function statusFormSubmit(formname,name)
{
	var f = $(formname);
	if (f) {
		f.appendChild(getActionAsHiddenInput(name));
		f.submit();
	}
}
function formReset(domElement)
{
	findParentForm(domElement).reset();
}

function getActionAsHiddenInput(name)
{
	var a = document.createElement('input');
	a.setAttribute('type', 'hidden');
	a.setAttribute('name', name);
	a.setAttribute('value', '1');
	return a;
}

function findParentForm(ele)
{
	var actEle = ele;
	while(actEle.nodeName.toUpperCase() != 'FORM')
	{
		actEle = actEle.parentNode;
	}
	return actEle;
}


document.observe('dom:loaded', function() {
	MiniCart.init();
	initIE6HoverFix();
	TopNavSelection.initialize();
	SearchButton.initialize();
	NewsletterButton.initialize();
	NaviMenu.initialize();
});

