﻿/*
 INCLUDES
 **********************************************/
// specify which javascripts to include on the webpage
//js('/files/javascript/SCRIPTNAME.js');
js('/files/javascript/jquery.colorbox-min.js');
js('/files/javascript/jquery.autocomplete.min.js');
js('/files/javascript/jquery.cycle.all.min.js');
js('/files/javascript/jquery.easing.1.3.js');
js('/files/javascript/jquery.scrollTo-1.4.2-min.js');
js('/files/javascript/flowplayer-3.2.4.min.js');
js('/files/javascript/flowplayer.controls-3.0.2.min.js');
js('/files/javascript/jquery.tools.min.js');
/*js('/files/javascript/jquery.ba-bbq.min.js');*/



// groupsmenu ajax funktionality
// version: 1.0 - 2010-05-12
(function($){

	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.groupsmenuAjax = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.groupsmenuAjax.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
		
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $(this).metadata()) : opts;
			
			// add the correct classes based on which submenus are open and closed when the plugin is called
			$(this).find('ul.' + o.closedClass).prev().addClass(o.closedClass);
			$(this).find('ul.' + o.openClass).prev().addClass(o.openClass);
			
			// dynamisk aktivering af klik på elementerne
			$(this).find('.' + o.hasSubmenuClass + ' > a').live('click', function(e){
			
				var $this = $(this);
				
				if ($this.next().size() > 0) {
					// there is already a submenu, so lets just work with that
					
					if ($this.hasClass('closed')) {
						// when the item is closed, open it and close all the other open menus
						$this.removeClass(o.closedClass).addClass(o.openClass).next().slideDown('fast').parent().siblings().find('ul').slideUp().prev().removeClass(o.openClass).addClass(o.closedClass);
					}
					else {
						// when the item is open, close it
						$this.removeClass(o.openClass).addClass(o.closedClass).next().slideUp('fast');
					}
				}
				else {
					// there is not a submenu yet, so fetch the correct submenu with Ajax
					
					// give feedback to the user, that we are working on getting the submenu
					$('<img class="preloader" src="' + o.preloaderImage + '" alt=""/>').insertAfter($this).fadeIn('fast');
					
					// fetch the submenu
					$.ajax({
						url: '/dynamic.aspx?data=groups&template=groupsmenu_ajax&ajaxmode=1',
						data: {
							key: $this.metadata().menuid
						},
						success: function(data){
							// add a "open" class to the link, remove the preloader image and insert the new list of menuitems after the link
							
							$this.addClass(o.openClass).next('img').fadeOut('fast', function(){
								$(this).remove();
							}).end().after(data).next().slideDown('fast');
						}
					});
				}
				
				// remove focus from the clicked link and cancel the normal click event
				$this.blur();
				e.preventDefault();
				//return false;
				
			});
		});
	}
	
	// default values for the options
	$.fn.groupsmenuAjax.defaults = {
		hasSubmenuClass: 'hasSubmenu',
		openClass: 'open',
		closedClass: 'closed',
		preloaderImage: '/images/preload_16x16.gif'
	};
	
})(jQuery);



// horizontal main menu - suckerfish style drop down
// version: 1.0 - 2010-05-14
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.menuFades = function(options){
	
		// activate the script for each instans found in the selector
		return this.each(function(){
		
			$(this).find('li').hoverIntent(function(){
				// on mouseover
				$('ul:first', this).fadeIn('fast');
			}, function(){
				// on mouseout
				$('ul:first', this).fadeOut('fast');
			});
			
		});
	}
	
})(jQuery);



// add and subtract quantity fields.
// version: 1.1 - 2010-07-22
(function($){

	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.quantityAddSubtract = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.quantityAddSubtract.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if ($this.hasClass('quantityButtonsAttached') == false){
				
				$this.addClass('quantityButtonsAttached');
				
				// insert a - (subtract) button
				$('<img/>', {
					'class': o.subtractClass,
					'src': o.subtractImage,
					'alt': '',
					click: function(){
						var floatValue = round_float($this.val(), 2);
						var floatNewVal = floatValue - o.step;
						var floatMinVal = round_float($this.closest('form').find('input[name="min_quantity"]').val(), 2);
						
						if (floatNewVal < floatMinVal) {
							$this.val(floatMinVal);
						}
						else if (floatNewVal < o.step) {
							$this.val(o.step);
						}
						else {
							$this.val(floatNewVal);
						}
					}
				}).insertBefore($this);
				
				// insert a + (add) button
				$('<img/>', {
					'class': o.addClass,
					'src': o.addImage,
					'alt': '',
					click: function(){
						var floatValue = round_float($this.val(), 2);
						var floatNewVal = floatValue + o.step;
						$this.val(floatNewVal);
					}
				}).insertAfter($this);
				
				// when the user removes the focus from the field, check the content
				$this.blur(function(){
					var qtycolli = parseFloat(o.step);
					var quantity = parseFloat($this.val().toString().replace(',', '.'));
					
					// check if colliMessage is defined. If it is, give the user this message, else give the standard danish message 
					var messageText = (typeof colliMessage != 'undefined') ? colliMessage : 'Antallet passer ikke med en hel pakning og er blevet justeret.';
					
					if (isNaN(quantity)) {
						$this.val('');
					}
					else {
						$this.val(quantity);
					}
					
					// show a message to the user
					if (qtycolli > 1 && quantity > 0 && round_float(quantity % qtycolli, 2) > 0) {
						$this.val(round_float(Math.ceil(quantity / qtycolli) * qtycolli, 2));
						$this.after('<div class="' + o.messageClass + '"><div>' + messageText + '</div></div>');
						$this.parent().find('.' + o.messageClass).fadeIn('slow', function(){
							window.setTimeout("$('." + o.messageClass + "').fadeOut('slow',function(){ $(this).remove(); })", 5000);
						});
					}
				});
			
			}
		});
	}
	
	// default values for the options
	$.fn.quantityAddSubtract.defaults = {
		addClass: 'jsQuantityAdd',
		addImage: '/images/btn_plus.gif',
		subtractClass: 'jsQuantitySubtract',
		subtractImage: '/images/btn_minus.gif',
		step: 1,
		messageClass: 'jsMessage'
	};
	
})(jQuery);



// jQuery plugin to replace the text in input fields on focus/blur or replace entire password field
// version: 1.0 - 2010-05-14 
(function($){
	$.fn.toggleInputText = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.toggleInputText.defaults, options);
		
		return ($(this).each(function(){
			var $this = $(this);
			title = $this.attr('title');
			
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if ($this.attr('type') == 'password') {
				// password field specific replacement
				
				var fakePassword = $('<input/>', {
					'class': $this.attr('class') + ' fakePassword',
					'value': $this.attr('title'),
					'type': 'text',
					css: {
						display: 'none'
					},
					focus: function(){
						$(this).hide();
						$this.show().focus();
					}
				});
				
				$this.after(fakePassword).blur(function(){
					if ($this.val() == "") {
						$this.hide().next('.fakePassword').show();
					};
									});
				
				if ($this.val() == "") {
					$this.hide().next('.fakePassword').show();
				};
							}
			else {
				// toggle values
				if ($this.val() == "") {
					$this.val(title);
				};
				$this.focus(function(){
					if ($this.val() == $this.attr('title')) {
						$this.val("");
					};
									}).blur(function(){
					if ($this.val() == "") {
						$this.val($this.attr('title'));
					};
									});
			}
			
			// hide the labels if the option is set to true
			if (o.hideLabels && $this.attr('id') != '') {
				$this.closest('form').find('label[for="' + $this.attr('id') + '"]').hide();
			}
			
		}));
	};
	
	// default values for the options
	$.fn.toggleInputText.defaults = {
		hideLabels: true
	};
	
})(jQuery);



// show the item specified in the href and hide what is specified in the options 
// version: 1.0 - 2010-05-12
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.setActiveBox = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.setActiveBox.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				// show the specified element
				$($this.attr('href')).show();
				
				// if hideSelector is set, hide the elements in the selector
				if (o.hideSelector != null) {
					$(o.hideSelector).hide();
				}

				// stop the click on the link
				return false;
			})
		});
	}
	
	// default values for the options
	$.fn.setActiveBox.defaults = {
		hideSelector: null
	};
	
})(jQuery);



// beskrivelse
// version: 1.0 - 2010-05-12
(function($){
// TODO:
//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.sendAjaxPost = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.sendAjaxPost.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				$.ajax({
					url: '/post.aspx?ajaxmode=1',
					type: 'post',
					data: o.data
				});
				
				if (o.after){
					o.after($this);
				}

				
				return false;
				
			});
		});
	}

	// default values for the options
	$.fn.sendAjaxPost.defaults = {
		data: null,
		after: null
	};

})(jQuery);



// use history.back if the history is present, else fallback to the link.
// version: 1.0 - 2010-05-27
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.historyBack = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.historyBack.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				if (history.length > 1){
					// there is a history in the browser
					history.back();
					return false;
				}
				else {
					// there is not a history in the browser
					// let the link work as a normal link
				}
			});
				
		});
	}
	
	// default values for the options
	$.fn.historyBack.defaults = {
		option: 'value'
	};

})(jQuery);



// check if the specified logininfo actually returns a user
// version: 1.0 - 2010-05-28
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.checkLogin = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.checkLogin.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// check if a user exists with the specified login. If not, throw an error 
			$this.bind('submit.checklogin',function(){
				var strEmail = $('input[name="Email"]',this).val(),
						strPass = $('input[name="Password"]',this).val();
			  
				// create the data object and fill it with data
				var objData = new Object();
				
				if (o.ajaxData){
					// ajaxData contains data, so we fill it into the objData object
					objData = o.ajaxData;
				}
				else {
					// ajaxData is null, so we fill objData with as good data as possible from the visible text/password fields in the form
					$this.find(':text:visible[name],:password:visible[name]').each(function(){
						objData[$(this).attr('name')] = $(this).val();
					});
				}
				
				$.ajax({
					url: '/dynamic.aspx?data=checklogin&ajaxmode=1',
					data: objData,
					success: function(data){
						if (data == '||') {
							// there's no login with those info, so we alert the user and stops the login form
							$this.find('.error').show();
							return false
						}
						else {
							// hide the error, if it's shown and remove the checklogin check (this one) and submit the form normally
							$this.find('.error').hide().end().unbind('submit.checklogin').submit();
						}
					}
				});
				
				// cancel the regular submit function
				return false;
			});
		});
	}
	
	// default values for the options
	$.fn.checkLogin.defaults = {
		ajaxData: null
	};

})(jQuery);


/*
// activate paging on productlistpaging via ajax 
// version: 1.1 - 2010-07-22
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	// global variables for all functions
	var $container;
	
	$.fn.ajaxProductlistpaging = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.ajaxProductlistpaging.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// find out which page we are on
			var strActivePage = '1';
			if (location.href.match(o.curpageRegExMatch)) {
				strActivePage = location.href.match(o.curpageRegExMatch)[1];
			} 
			
			// wrap the "current page" productlist and actions in a container, a track and a page container
			$this.find(o.productlistGroupSelector)
				.wrapAll('<div class="' + o.containerId + '"/>')
				.wrapAll('<div class="' + o.trackId + '"/>')
				.wrapAll('<div class="' + o.pageIdPrefix + strActivePage + ' ' + o.pageClass + '"/>');
			
			$container = $('.' + o.containerId,$this);
			
			// give the container some styles, so the pages can move inside this as on a "track"
			$container.css({
				position: 'relative',
				width: $container.width() + 'px',
				height: $container.height() + 'px',
				overflow: 'hidden'
			});
			
			$('.' + o.pageIdPrefix + strActivePage,$this).css({
				position: 'absolute',
				top: 0,
				left: $container.width() * (parseInt(strActivePage) - 1) + 'px',
				width: $container.width() + 'px',
				height: $container.height() + 'px'
			});
			
			$('.' + o.trackId,$this).css({
				position: 'absolute',
				top: 0,
				left: '-' + $container.width() * (parseInt(strActivePage) - 1) + 'px'
			});
			
			
			// find out if the user requests a page via the location.hash
			if (location.hash.indexOf(o.hashPrefix) > -1) {
				var strHashPage = parseInt(location.hash.replace('#' + o.hashPrefix,''));
				
				if (strHashPage != strActivePage ){
					
					// decide which key/value to use (searchtext or key) and whether or not jQuery BBQ have been used
					var strKeyset;
					if (typeof $.bbq.getState() != 'undefined' && location.href.match(o.searchtextRegExMatch)){
						// find the search parameter in the jQuery BBQ plugin
						strKeyset = 'searchtext=' + $.bbq.getState().site.match(o.searchtextRegExMatch)[1];
					}
					else if (typeof $.bbq.getState() != 'undefined'){
						// find the second key parameter in the jQuery BBQ plugin
						strKeyset = 'key=' + $.bbq.getState().site.match(o.keyRegExMatch)[1];
					}
					else if (location.href.match(o.searchtextRegExMatch)) {
						// find the search parameter in the HREF eg. "test" in /productlistpaging/?searchtext=test&paging=1&curpage=2
						strKeyset = 'searchtext=' + location.href.match(o.searchtextRegExMatch)[1];
					} else {
						// find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
						strKeyset = 'key=' + location.pathname.match(o.keyRegExMatch)[1];
					}
					
					var strHashPageUrl = '/dynamic.aspx?data=products&' + strKeyset + '&paging=1&curpage=' + strHashPage;
					getPage(strHashPageUrl, strHashPage, o, $this);
				}
			}

			
			$this.find(o.pagingLinkSelector).live('click',function(){
				// make a new url
				var strUrl = $(this).attr('href');
				var objCurPage = strUrl.match(o.curpageRegExMatch); // find the current page in the HREF
				
				var strCurpage = '1';
				if (objCurPage){
					strCurpage = objCurPage[1];
				}
				
				// set the hash in the URL for when links are sent by mail or in other ways
				location.hash = o.hashPrefix + strCurpage;
				
				if ($('.' + o.pageIdPrefix + strCurpage,$this).size() > 0){
					// the page already exists
					
					
					$('.'+ o.trackId,$this).animate({
						left: ($('.' + o.pageIdPrefix + strCurpage,$this).position().left * -1) + 'px'
					},'slow');
					
				} else {
					// the page did not exist 
				
					//var objKey = strUrl.match(o.keyRegExMatch); // find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
					
					
					// decide which key/value to use (searchtext or key)
					var strKeyset2;
					if (strUrl.match(o.searchtextRegExMatch)) {
						// find the search parameter in the HREF eg. "test" in /productlistpaging/?searchtext=test&paging=1&curpage=2
						strKeyset2 = 'searchtext=' + strUrl.match(o.searchtextRegExMatch)[1];
					} else {
						// find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
						strKeyset2 = 'key=' + strUrl.match(o.keyRegExMatch)[1];
					}
					
					var strDynamicurl = '/dynamic.aspx?data=products&' + strKeyset2 + '&paging=1&curpage=' + strCurpage;
					
					activatePagePreloader();
					getPage(strDynamicurl, strCurpage, o, $this);
				}
				
				// cancel the normal click event
				return false;
			});
			
		});
	}
	
	function getPage(strUrl,strPageId,o,pageContainer){
				
		$.get(strUrl,function(data){
			// find the body element  
			var startCut = data.indexOf('<body');
			var endCut = data.indexOf('</body>') + 7;
			
			// if the new page has content, insert it and scroll to it
			if ($(data.substring(startCut, endCut)).find(o.productlistGroupSelector).size() > 1) {
				$('.'+ o.trackId, pageContainer).append('<div class="' + o.pageIdPrefix + strPageId + ' ' + o.pageClass + '"/>');
				
				$('.' + o.pageIdPrefix + strPageId, pageContainer).css({
					position: 'absolute',
					left: ($container.width() * (strPageId - 1)) + 'px',
					top: 0,
					width: $container.width() + 'px',
					height: $container.height() + 'px',
					overflow: 'hidden'
				}).html($(data.substring(startCut, endCut)).find(o.productlistGroupSelector));
				
				if (o.beforeAjaxAnimation) {
					o.beforeAjaxAnimation();
				}
				
				// hide the page preloader
				deActivatePagePreloader();
				
				$('.'+ o.trackId, pageContainer).animate({
					left: ($('.' + o.pageIdPrefix + strPageId, pageContainer).position().left * -1) + 'px'
				}, 'slow');
				
				if (o.afterAjaxAnimation) {
					o.afterAjaxAnimation();
				}

			}
		});
	}
	
	// default values for the options
	$.fn.ajaxProductlistpaging.defaults = {
		containerId: 'productlistpaging-ajax-container',
		trackId: 'productlistpaging-ajax-track',
		pageIdPrefix: 'productlistpaging-ajax-page',
		pageClass: 'productlistpaging-ajax-page',
		hashPrefix: 'page',
		productlistGroupSelector: '.productlistActions,.productlist',
		pagingLinkSelector: '.productlistPaging a',
		curpageRegExMatch: /curpage=(\d+)/i,
		keyRegExMatch: /\/[^\/]+\/(.+)\//i,
		searchtextRegExMatch: /searchtext=([^&]+)/i,
		beforeAjaxAnimation: null,
		afterAjaxAnimation: null
	};
})(jQuery);
*/


 // GLS lookup
 // version: 1.0 - 2010-06-09
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.glsLookup = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.glsLookup.defaults, options);
		
		// activate the script for each instance found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// when selecting a GLS shop, update the input values
			$(o.glsContainer + ' :radio').live('click',function(){
				$(o.glsShopName).val($(this).metadata().name);
				$(o.glsShopAddress).val($(this).metadata().address);
			});
			
			// when selecting a shippingtype, toggle the glsData depending on whether useGLS is set or not
			$(o.shippingtypesContainer + ' :radio').click(function(){
				
				if ($(this).metadata().useGLS == true){
					$(o.glsContainer).fadeIn();
				} else {
					$(o.glsContainer).fadeOut();
				}
			});
			
			// set basic values for street postalcode and country
			var strStreet = $(o.street).val();
			var strPostalcode = $(o.postalcode).val();
			var strCountry = $(o.country).val();
			
			// if an alternate delivery address is chosen, replace the previous values with these 
			if ($(o.postalcode2).size() > 0 && $(o.postalcode2).val() != '') {
				strStreet = $(o.street2).val();
				strPostalcode = $(o.postalcode2).val();
				strCountry = $(o.country2).val();
			}
			
			// do an ajax request to the server
			if (strPostalcode != '') {
				$.ajax({
					url: "/dynamic.aspx?data=glsdelivery&ajaxmode=1",
					data: {
						street: strStreet,
						postalcode: strPostalcode,
						country: strCountry
					},
					success: function(data){
						if (data != '') {
							// replace the old GLS data with new
							$(o.glsContainer).html(data);
						}
						else {
							$(o.glsContainer).empty('');
						}
						
						// click the checked radiobutton so it saves data
						$(o.glsContainer).find(':radio:checked').click();
					}
				});
			}
		});
	}

	
	// default values for the options
	$.fn.glsLookup.defaults = {
		glsContainer: '#jsGlsdata',
		postalcode: '#addrPostalcode',
		street: '#addrStreet',
		country: '#addrCountry',
		postalcode2: '#addrPostalcode2',
		street2: '#addrStreet2',
		country2: '#addrCountry2',
		glsShopName: '#glsShopName',
		glsShopAddress: '#glsShopAddress',
		shippingtypesContainer: '#shippingtypes'
	};

})(jQuery);


/*
function singleLookup(){
		var objForm = $(this).closest('form').get(0);
*/	
		/*
		var strStreet = o.street ? o.street.val() : objForm.street.value;
		var strPostalcode = o.postalcode ? o.postalcode.val() : objForm.postalcode.value;
		var strCountry = o.country ? o.country.val() : objForm.country.value;
		*/
		
		/*
		var strStreet = o.street.val();
		var strPostalcode = o.postalcode.val();
		var strCountry = o.country.val();
		*/
		
		/*
		var strStreet = objForm.street.value;
		var strPostalcode = objForm.postalcode.value;
		*/
		
		/*
		if (objForm.postalcode2 || o.postalcode2) {
			if (objForm.postalcode2.value != '' || o.postalcode2) {
				strStreet = o.street2 ? o.street2.val() : objForm.street2.value;
				strPostalcode = o.postalcode2 ? o.postalcode2.val() : objForm.postalcode2.value;
				strCountry = o.country2 ? o.country2.val() : objForm.country2.value;
				
			}
		}
		*/
/*		
		if (strPostalcode != '') {
		
			$.get("dynamic.aspx?data=glsdelivery&ajaxmode=1", {
				street: strStreet,
				postalcode: strPostalcode,
				country: strCountry
			}, function(data){
			
				if (data != '') {
					// replace the old GLS data with new
					$(o.glsContainer).replaceWith(data);
				}
				else {
					$(o.glsContainer).empty('');
				}
				
				$(o.glsContainer).find(':radio:checked').click();
				
			}, 'html');
			
		}
	}
*/


// read out RSS and Atom feeds
// dependent on the jQuery plugin getFeed
// version: 1.0 - 2010-07-28
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.readFeed = function(options){

		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.readFeed.defaults, options);

		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this)
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if (o.feed){
				
				if (o.feed.match('http://') == null){
					o.feed = 'http://' + o.feed;
				}
				o.feed = '/proxy.aspx?datatype=xml&url=' + o.feed;
				
				$.getFeed({
					url: o.feed,
					success: function(feed){
						if (feed.image){
							$this.append('<a href="' + feed.image.link + '"><img src="' + feed.image.url + '" alt="' + feed.image.title + '"/></a>');
						}
						$this.append('<h2><a href="' + feed.link + '">' + feed.title + '</a></h2><h3>' + feed.description + '</h3>');
						var html = '';
						for(var i = 0; i < feed.items.length && i < 5; i++) {
							var item = feed.items[i];
							html += '<h3><a href="' + item.link + '">' + item.title + '</a></h3>';
							html += '<div class="updated">' + item.updated + '</div>';
							html += '<div class="description">' + item.description + '</div>';
						}
						$this.append(html);
					}
				});
				
			}
			
		});
	}

	// default values for the options
	$.fn.readFeed.defaults = {
		feed: false
	};

})(jQuery);


/*
 // Standard jQuery plugin opbygning
 // --------------------------------
 // beskrivelse
 // version: 1.0 - 2010-06-09
 (function($){
 // TODO:
 //		Lav dokumentation til hvordan plugin'et bliver brugt
 
 $.fn.FUNKTIONSNAVN = function(options){
 
 // create the options object with data from the default options and the user specified options
 var opts = $.extend({}, $.fn.FUNKTIONSNAVN.defaults, options);
 
 // activate the script for each instans found in the selector
 return this.each(function(){
 var $this = $(this);
 // build element specific options
 var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
 
 
 });
 }
 
 // default values for the options
 $.fn.FUNKTIONSNAVN.defaults = {
 option: 'value'
 };
 
 })(jQuery);
*/


// round floats up / down
function round_float(x, n){
	if (!parseInt(n)) var n = 0;
	if (!parseFloat(x)) 		
		return false;
	return Math.round(x * Math.pow(10, n)) / Math.pow(10, n);
}


// NY activate ajax shopping - skal kopieres over i korrekt javascript fil, når den er færdig og gennemtestet.
function activateAjaxShopping_NEW(objArg){

	/* 
	 * ajaxMode (default = false)             : defines whether or not ajaxMode is being used in the querystring
	 * target (default = '.basketpreview')    : selector string to the element which should be replaced with the content
	 * find (default = '.basketpreview')      : selector string to find a specific element inside the collected data
	 *
	 * if no arguments are passed, default values are set
	 */
	objArg = (typeof objArg == 'undefined') ? new Object : objArg;
	objArg.ajaxMode = (typeof objArg.ajaxMode == 'undefined') ? false : objArg.ajaxMode;
	objArg.target = (typeof objArg.target == 'undefined') ? '.basketpreview' : objArg.target;
	objArg.find = (typeof objArg.find == 'undefined') ? '.basketpreview' : objArg.find;
	
	var strAjaxMode = '';
	if (objArg.ajaxMode) {
		strAjaxMode = '&ajaxmode=1'; // call the page with ajaxmode = 1 
	}

	// remove products from basket and update basket preview
	$('.basketpreview .removeFromBasket').live('click', function(e){
		
		e.preventDefault();
		$(this).closest('form').submit(function(){
			$.post('/post.aspx', {
				_Function: this._Function.value,
				_ReturnTo: '/dynamic.aspx?data=basket&template=basketpreview&mode=removed' + strAjaxMode,
				productid: this.productid.value,
				quantity: this.quantity.value,
				pkid: this.pkid.value
			}, function(data){
			
				var $content = '';
				
				if (objArg.ajaxMode) {
					$content = $(data).filter('.basketpreviewBox').find('.basketpreview');
				}
				else {
				
					// find the body element  
					var startCut = data.indexOf('<body');
					var endCut = data.indexOf('</body>') + 7;
					
					$content = $(data.substring(startCut, endCut));
					
				}
				
				// replace the target with the new content
				$(objArg.target).replaceWith($content);
				$('#siteBasketpreview').find('.basketlink').removeClass('active').click();
				
			}, 'html');
			
			// cancel the normal form submit
			return false;
		}).submit();
	});
	

	// add products to basket and update basketpreview
	$('form.jsUpdateBasket').live('submit',function(){
		var strAlert;
		
		// cancel the Ajax call, if some values are missing
		if (this.productid.value == '' || this.quantity.value == '') {
		
			strAlert = (typeof strErrorFieldRequired == 'undefined') ? 'Udfyld alle n\u00F8dvendige felter' : strErrorFieldRequired;
			
			modalAlert(strAlert);
			return false;
		}
		
		// cancel the Ajax call, if the quantity is less than minimum quantity
		if (parseInt(this.min_quantity.value) > parseInt(this.quantity.value)) {
		
			strAlert = (typeof strErrorOrderMinimum == 'undefined') ? 'Du skal bestille minimum' : strErrorOrderMinimum;
			var strAlertPcs = (typeof strErrorOrderMinimumPcs == 'undefined') ? 'stk.' : strErrorOrderMinimumPcs;
			
			modalAlert(strAlert + ' ' + this.min_quantity.value + ' ' + strAlertPcs);
			return false;
		}
		
		
		$.post("/post.aspx", {
			_Function: this._Function.value,
			_ReturnTo: '/dynamic.aspx?data=basket&template=basketpreview&mode=added' + strAjaxMode,
			productid: this.productid.value,
			quantity: this.quantity.value
		}, function(data){
		
			var $content = '';
			
			if (objArg.ajaxMode) {
				$content = $(data).filter('.basketpreviewBox').find('.basketpreview');
			}
			else {
			
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;
				
				$content = $(data.substring(startCut, endCut));
				
			}
			
			// replace the target with the new content
			$(objArg.target).replaceWith($content);
			
			// click on the "show basket preview"-button
			$('#siteBasketpreview').find('.basketlink').removeClass('active').click();
			
		}, 'html');
		
		
		// this is used to show that the form have been sent to the server and the basket have been updated  
		$('.added', this).fadeIn(100, function(a){
			setTimeout(function(){
				$('.added').fadeOut('slow');
			}, 2000)
		});
		
		// cancel the normal form submit
		return false;
	});

	// hack to make Internet Explorer respect the live event on the forms (it could otherwise just use the browser default action)
	$('form.jsUpdateBasket :submit, form.jsUpdateBasket :image').live('click',function(){
		$(this).closest('form').submit();
		return false;
	});
}

// GiftWrapping
function GiftWrapping()
{
	$('.inpWrapping').live('click', function() {
			var that = $(this);
			var pkid = $(this).attr('name').substring(8);
			activatePagePreloader();
			
			if ($(this).is(':checked'))
			{
				var params = {};
				params[encodeURI('pkid')] = pkid;
				params[encodeURI('productid')] = $('#update' + pkid).find('input[name=productid]').val();
				params[encodeURI('quantity')] = $('input[name=quantity' + pkid + ']').val();
				params[encodeURI('@wrapping')] = 1;
				params[encodeURI('_Function')] = 'UpdateBasket';
				params[encodeURI('_ReturnTo')] = '/dynamic.aspx?data=basket';
				
				$.post("/post.aspx", params,
				function(data){
					//alert('CHECKED: ' + pkid);
					$('#siteMain').html(data);
				}, 'html');
			}
			else
			{
				var params = {};
				params[encodeURI('pkid')] = pkid;
				params[encodeURI('productid')] = $('#update' + pkid).find('input[name=productid]').val();
				params[encodeURI('quantity')] = $('input[name=quantity' + pkid + ']').val();
				params[encodeURI('@wrapping')] = 0;
				params[encodeURI('_Function')] = 'UpdateBasket';
				params[encodeURI('_ReturnTo')] = '/dynamic.aspx?data=basket';
				
				$.post("/post.aspx", params,
				function(data){
					//alert('UNCHECKED: ' + pkid);
					$('#siteMain').html(data);
				}, 'html');
			}
			
			deActivatePagePreloader();
		});
	//});
}

/*
 ON LOAD
 *********************************************/
// jQuery 'onReady' script - runs when the document have been loaded, but before images
$(function () {
	//validateForms();

	activateAjaxShopping_NEW({
		ajaxMode: true
	});

	$('form').formvalidation();

	autocompletePostalCode3('#tDelivery #addrPostalcode', '#tDelivery #addrCity', '#tDelivery #addrCountry');
	autocompletePostalCode3('#tDelivery #addrPostalcode2', '#tDelivery #addrCity2', '#tDelivery #addrCountry2');
	autocompletePostalCode3('#tCreatecustomer #customerPostalcode', '#tCreatecustomer #customerCity', '#tCreatecustomer #customerCountry');

	productlistImage();
	postPolls();
	quizWizzard();
	tracktrace();
	changeProductImage();
	flashLoad();
	openPopups();
	GiftWrapping();
	//showInlineHelp();
	//variantSelection();
	HandleImagesets();

	// when changing sort method on productlistpaging, submit the sorting form
	$('#siteMain').delegate('.productlistSorting select', 'change', function () {
		$(this).closest('form').submit();
	});

	/*
	$('.tProducts').ajaxProductlistpaging({
	beforeAjaxAnimation: function(){
	$('.jsQuantity').quantityAddSubtract();
	}
	});
	*/

	$('#mainMenu').menuFades();
	$('#areaMenu').groupsmenuAjax();
	$('.jsQuantity').quantityAddSubtract();
	$('.jsInput').toggleInputText();
	$('.jsShowForgotPwd, .jsShowLogin').setActiveBox();
	$('.jsGoBack').historyBack();
	$('#menuLoginForm form, #siteLoginForm form').checkLogin();
	$('#tPayment').glsLookup();
	$('.rssFeed').readFeed();


	// toggle optional delivery address
	$('#addrOptionalDelivery').click(function () {
		if (this.checked) {
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').removeAttr('disabled');
			$('#tDelivery').find('.secondaryAddress').show();
		} else {
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').attr('disabled', 'disabled');
			$('#tDelivery').find('.secondaryAddress').hide();
		}
	});
	$('#tDelivery').find('.secondaryAddress:hidden .secondaryAddresinput').attr('disabled', 'disabled');


	// tests if the terms are accepted on the orderstatus page before going on
	$('#tOrderstatus').find('form').submit(function () {
		if ($('#TermsAccepted').is(':checked') == false) {
			var strAlert = typeof strAcceptTermsError == 'undefined' ? 'Du skal acceptere handelsbetingelserne' : strAcceptTermsError;
			alert(strAlert);
			return false;
		}
	});

	// when user wants to unsubscribe the newsletter, fill out the correct form and submit it
	/*
	$('#tNewssignup').find('.cancelSubscription').click(function(){
	var objForm = $('#newsletterCancelSubscription');
	objForm.get(0).email.value = $('#newslettersubscribeEmail').val();
	objForm.submit();
	});
	*/

	// show/hide the menuLogin container, based on the class
	$('#menuLogin>a').click(function () {
		$(this).blur().parent().toggleClass('itemLoginActive');
		return false;
	});

	// add/remove product to/from wishlist
	$('.productLinkwishlist').not('.productLinkwishlistRemove').sendAjaxPost({
		after: function () { $('.productLinkwishlist').toggle(); }
	});
	$('.productLinkwishlistRemove').sendAjaxPost({
		after: function () { $('.productLinkwishlist').toggle(); }
	});

	// add/remove product to/from favorites
	$('.productLinkfavorites').not('.productLinkfavoritesRemove').sendAjaxPost({
		after: function () { $('.productLinkfavorites').toggle(); }
	});
	$('.productLinkfavoritesRemove').sendAjaxPost({
		after: function () { $('.productLinkfavorites').toggle(); }
	});

	// add lightbox/colorbox functionality to shoppinglist links
	$('.productLinkshoppinglist').colorbox({
		onComplete: function () {
			$('#tUpdateshoppinglist .jsQuantity').quantityAddSubtract();
			$('#tUpdateshoppinglist .jsInput').toggleInputText();
			$('#tUpdateshoppinglist').find('form').ajaxForm({
				success: function (data) {
					$(document).one('cbox_closed', function () {
						$.fn.colorbox({
							html: data
						});
					});
					$.fn.colorbox.close();
				}
			})
		}
	});

	// add lightbox/colorbox functionality to tip a friend links
	$('.productLinktipafriend').colorbox({
		onComplete: function () {
			$('#tTipafriend .jsInput').toggleInputText();
			$.fn.colorbox.resize();
			$('#tTipafriend').find('form').formvalidation().ajaxForm({
				beforeSubmit: function (formData, jqForm, options) {
					if (jqForm.data('allOk') == 0) {
						return false;
					}
				},
				success: function (data) {
					$(document).one('cbox_closed', function () {
						$.fn.colorbox({
							html: data
						});
					});
					$.fn.colorbox.close();
				}
			})
		}
	});

	// add lightbox/colorbox functionality to print links
	$('.productLinkprint').colorbox({
		iframe: true,
		width: 700,
		height: '80%'
	});




	// standard lightbox feature for productinfo page - building the container
	updateProductImagesLightbox();

	// standard lightbox feature for productinfo page - activating the overlay
	$('#productImages a').colorbox({
		inline: true,
		href: '#productImagesLightbox',
		opacity: 0.65,
		onOpen: function () {
			$('#productImagesLightbox').find('.imageContainer img[src$="' + escape($(this).attr('href')) + '"]:first').show().siblings('img').hide();
			$('#productImagesLightbox').find('.productImageActions').html($('#productAdditions').children().clone(true));
		},
		onComplete: function () {
			$('#productImagesLightbox').find('.imageContainer').css({
				height: $('#productImagesLightbox').find('.imageContainer').height()
			});

			if ($('#productImagesLightbox').find('.imageContainer img').size() > 1) {
				updateLightboxButtons();

				$('#productImagesLightbox').find('.imageContainer .lightboxNavigation').click(function () {
					$this = $(this);
					$img = $this.siblings('img:visible');

					if ($img.siblings('img').size() > 0) {
						if ($img.next('img').size() > 0 && $this.hasClass('next')) {
							$img.fadeOut('fast', function () {
								$img.next('img').fadeIn('slow');
								updateLightboxButtons();
							});
						}
						else if ($img.prev('img').size() > 0 && $this.hasClass('prev')) {
							$img.fadeOut('fast', function () {
								$img.prev('img').fadeIn('slow');
								updateLightboxButtons();
							});
						}
					}
				});
			}
			else {
				$('#productImagesLightbox').find('.imageContainer .lightboxNavigation').hide();
			}
		}
	});



	// delete from basket
	$('#tBasket').find('.jsDelete').live('click', function () {
		$($(this).attr('href')).ajaxSubmit({
			beforeSubmit: activatePagePreloader,
			success: function (data) {
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;

				var $content = $(data.substring(startCut, endCut));
				$('#tBasket').replaceWith($content);

			}
		});
		return false;
	});

	// update quantity in basket
	$('#tBasket').find('.quantity input').live('change', function () {
		var strPkid = $(this).attr('name').replace('quantity', ''),
				intValue = $(this).val();

		$('#update' + strPkid).get(0).quantity.value = intValue;

		$('#update' + strPkid).ajaxSubmit({
			beforeSubmit: activatePagePreloader,
			success: function (data) {
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;

				var $content = $(data.substring(startCut, endCut));
				$('#tBasket').replaceWith($content);

			}
		});
		return false;
	});

	$('#tBasket').find('#basketWrapping').live('click', function () {
		$(this).closest('form').ajaxSubmit();
	});

	// toggle the visibility of the optional delivery form
	$('.jsOptionalDelivery').click(function () {
		var $this = $(this);

		if ($this.attr('checked')) {
			$('.secondaryAddress').show();
		} else {
			$('.secondaryAddress').hide();
		}
	});


	/*
	// empty city and postalcode input fields, when changing country 
	$('#tDelivery').find(':input[name=country]').change(function(){
	$('#tDelivery').find(':input[name=city], :input[name=postalcode]').val('');
	$('#addrPostalcode').flushCache();
	})
	.end().find(':input[name=country],:input[name=country2]').change(function(){
	$('#tDelivery').find(':input[name=city2], :input[name=postalcode2]').val('');
	$('#addrPostalcode2').flushCache();
	});
	*/



	/*
	// ajax submitting the subscribe newsletter form
	$('#newsletterSubscription').ajaxForm({
	beforeSubmit: function(formData, jqForm, options){
	if (jqForm.data('allOk') == 0){
	return false;
	}
	$('#newsletterSubscription').find('.preloader').fadeIn('fast');
	},
	success: function(){
	$('#newsletterSubscription').find('.preloader').hide();
	$('#newsletterSignupSuccess').fadeIn('fast', function(){
	setTimeout("$('#newsletterSignupSuccess').fadeOut('fast')",5000);
	});
			
	}
	});
	
	// ajax submitting the unsubscribe newsletter form
	$('#newsletterCancelSubscription').ajaxForm({
	beforeSubmit: function(formData, jqForm, options){
	if (jqForm.data('allOk') == 0){
	return false;
	}
	$('#newsletterSubscription').find('.preloader').fadeIn('fast');
	},
	success: function(){
	$('#newsletterSubscription').find('.preloader').hide();
	$('#newsletterUnsubscribeSuccess').fadeIn('fast', function(){
	setTimeout("$('#newsletterUnsubscribeSuccess').fadeOut('fast')", 5000);
	});
	}
	});
	*/


	// promotion articles rotation
	if ($('#promotion .promotionImages img').size() > 1) {
		$('#promotion .promotionImages').cycle({
			speed: 'fast',
			timeout: 4000,
			pager: '#promotion .promotionNav',
			pagerAnchorBuilder: function (idx, slide) {
				// return selector string for existing anchor 
				return '#promotion .promotionNav li:eq(' + idx + ') a';
			},
			pagerEvent: 'mouseover',
			pauseOnPagerHover: true
		});

		// force a click event on the carousel navigation links, to counteract the cycle plugin event unbinder.
		$('#promotion .promotionNav a').click(function () {
			location.href = this;
		});
	}

	// toggle visibility of input fields on the customerinfo page, when clicking on the edit profile button
	$('#tCustomerinfo').find('.inpEditProfile').click(function () {
		$('#tCustomerinfo .updatecustomerForm').find('span.value,:text, select, textarea,:submit,:button').toggle();
		return false;
	});

	// on submitting forms on the shoppinglist page, ask if the user wants to save the list for later. 
	$('#tShoppinglist').find('.jsTransferShoppinglistToBasket').submit(function () {
		var preserveText = (typeof preserveListText != 'undefined') ? preserveListText : 'Vil du bevare listen?';
		var agree = confirm(preserveText);
		if (agree) {
			this.preserve.value = '1';
		}
	});


	// galleries on pages should have lightbox/colorbox functionality and an icon at mouseover
	$('#pageGallery').find('a[rel="imageGallery"]').append('<img class="zoom" src="/images/icon_zoom.png" alt="">').colorbox({
		current: ''
	});

	// images on normal pages should have lightbox/colorbox functionality
	$('a[rel="pageImages"]').colorbox({
		current: ''
	});

	// activate search suggests - type-ahead search
	$('.searchform input[name="searchtext"]').searchSuggest({
		afterAjax: function () {
			$('.jsQuantity').quantityAddSubtract();
		}
	});

	$('.getEmailLink').click(function () {
		var $this = $(this);
		$.ajax({
			url: '/dynamic.aspx?ajaxmode=1&data=article&template=getemail',
			data: {
				key: $this.attr('href').substring(1)
			},
			success: function (data) {
				$this.replaceWith(data);
			}
		});
		return false;
	});




	//initializeBBQ();

	// toggle the streamer view between products and bundles
	$('#siteStreamer').find('a.changegroup').click(function (e) {
		// cancel if an animation is already ongoing
		if ($('#siteStreamer').data('animating')) {
			return false;
		};

		// mark the animation as ongoing
		$('#siteStreamer').data('animating', true);

		var $this = $(this);
		e.preventDefault();

		// find the target
		var strId = $this.attr('href').substr($(this).attr('href').indexOf('#'));

		// toggle the buttons
		$this.fadeOut().siblings('.changegroup').fadeIn();

		// hide the currently showing list
		$(strId).siblings().animate({
			left: -2000
		}, 600, function () {
			// show the next list
			$(strId).animate({
				left: 0
			}, 600, function () {
				// mark the animation as done
				$('#siteStreamer').data('animating', false);
			});
		});

	});

	// activate scroll functionality on the basketpreview if needed
	$('.basketScrollUp, .basketScrollDown').live('click', function () {
		// stop an eventual timeout, if the user clicks to scroll up or down
		//clearTimeout(window.basketpreview);

		var currentBasketItemIndex = $('.scrollContainer').data('scrollItem');

		if (!currentBasketItemIndex) {
			currentBasketItemIndex = 0;
		}

		var nextBasketItem;
		if ($(this).hasClass('basketScrollUp')) {

			if (currentBasketItemIndex < 1) {
				currentBasketItemIndex = 1;
			}

			nextBasketItem = $('.scrollContainer table').get(currentBasketItemIndex - 1);
			$('.scrollContainer').data('scrollItem', currentBasketItemIndex - 1);

		} else {
			if (currentBasketItemIndex > $('.scrollContainer table').size() - 2) {
				currentBasketItemIndex = $('.scrollContainer table').size() - 2;
			}

			nextBasketItem = $('.scrollContainer table').get(currentBasketItemIndex + 1);
			$('.scrollContainer').data('scrollItem', currentBasketItemIndex + 1);

		}

		$('.scrollContainer').scrollTo(nextBasketItem, 800, { easing: 'easeInOutQuart' });
	});


	// show the basketpreview when clicking on the shopping bag link
	$('#siteBasketpreview').find('.basketlink').click(function (e) {
		e.preventDefault();

		var $this = $(this);
		var $basket = $('.basketpreview');
		var boxHeight = $basket.outerHeight();


		// only start the toggling, if the basket is not empty
		if (!$basket.is(':empty')) {
			$this.toggleClass('active').blur();

			// show or hide the basket with all animations
			$basket.animate({
				top: boxHeight * -1
			}, 600, function () {
				$(this).css('top', '-9000px').find('.shortBox, .longBox').toggle();
				resizeBasketPreview();
				boxHeight = $(this).outerHeight();
				$(this).css('top', boxHeight * -1).animate({
					top: 28
				}, 600);
			});

			// if the basketpreview is shown, make it possible to hide it by pressing Esc on the keyboard
			if ($this.hasClass('active')) {
				$(document).keyup(function (e) {
					if (e.which == 27) { // 27 == ESC key
						$('#siteBasketpreview').find('.basketlink').click();
						$(this).unbind('keyup');
					}
				});
			}
		}
	});

	$('#siteBasketpreview .continueshopping').live('click', function (e) {
		e.preventDefault();
		$('#siteBasketpreview').find('.basketlink').click();
	});

	/*
	// set the language data and submit the form
	$('#countrySelection').find('ul a').click(function(e){
	e.preventDefault();
		
	var strLangid = $(this).attr('href').substr($(this).attr('href').indexOf('#')+1);
	var strUrl = location.href;
		
	$('#countryselectLangid').val(strLangid);
	$('#countryselectUrl').val(strUrl);
		
	$('#countrySelection').find('form').submit();
	});
	*/

	$('#discountcodeQuestion').bind('mouseenter mouseleave', function () {
		$('#discountcodeExplanation').toggle();
	});

	$('#siteBasketpreview').find('.countrylink').colorbox({
		inline: true,
		opacity: 0.65
	});

	$('.shopflowForm, .shopflow').find('.accordianHeader').click(function () {
		$(this).toggleClass('open').next('div').slideToggle('fast');
	}).next('div').hide();

	// toggle optional delivery address
	$('#tDelivery :radio[name="optionaldelivery"]').live('click', function () {
		if (this.value == 1) {
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').removeAttr('disabled');
			$('#tDelivery').find('.secondaryAddress').show();
		} else {
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').attr('disabled', 'disabled');
			$('#tDelivery').find('.secondaryAddress').hide();
		}
	});
	$('#tDelivery').find('.secondaryAddress:hidden .secondaryAddresinput').attr('disabled', 'disabled');

	$('#productlinks a.jsPopup').colorbox({
		iframe: true,
		width: 710,
		height: 510,
		opacity: 0.65
	});

	// set the baseLeft data on basketpreview and make sure that it is moved as needed
	if ($('#siteBasketpreview').size() > 0) {
		$('#siteBasketpreview').data('baseLeft', $('#siteBasketpreview').position().left);
		repositionBasketpreview();
	}
	$(window).resize(repositionBasketpreview);

	// activate variant system with custom updateLayout function
	$('#productVariantsNew').variantSystem({
		updateLayout: updateProductLayoutCustom,
		onCreate: function () {
			var flavour = querySt("flavour");

			if (flavour) {
				setTimeout(function () {
					var flavourValue = '';
					var flavourQs = flavour.replace(/\+/g, ' ').replace(/-/g, '/');
					//alert(flavourQs);
					$('#variantFlavour').children().each(function () {
						if ($(this).text() == flavourQs) {
							flavourValue = $(this).val();
							return false;
						}
					});

					$('#variantFlavour').val(flavourValue);
					$('#variantFlavour').change();

				}, 100);


			}
		}
	});


	$('#tDelivery #addrCountry, #tDelivery #addrCountry2').live('change', function () {
		var $this = $(this);
		var objForm = $this.closest('form');
		var strCountryID = $this.val();

		if ($this.is('#addrCountry2') || ($this.is('#addrCountry') && objForm.find(':input[name="optionaldelivery"]:checked').val() == '0')) {
			// update the webpage if we are changing country for the delivery address or for the invoice address, while there are no delivery address specified.

			// RUN UPDATE function WITH value from strCountryID.
			fetchDeliveryPageUpdate();
		} else {
			//console.log('no need for updating - we are not changing the delivery address.');
		}
	});

	// expand/collapse the productdescription if it is available on the page
	$('#expandProductdescription span').live('click', function () {
		var $box = $('#productDescription');

		if ($box.data('animating') != true) {
			var intNewHeight = $box.data('originalHeight');

			if ($box.height() == intNewHeight) {
				intNewHeight = $box.data('childrenHeightSum');
			}

			$box.data('animating', true).animate({
				height: intNewHeight
			}, function () {
				$(this).data('animating', false);
			});
			$('#expandProductdescription span').toggle();
		}

	});
	activateProductdescriptionReadMore();



});              // jQuery ready end

// read a querystring value from the key
function querySt(ji) {
	hu = window.location.search.substring(1);
	gy = hu.split("&");
	for (i=0;i<gy.length;i++) {
			ft = gy[i].split("=");
			if (ft[0] == ji) {
			return ft[1];
		}
	}
}

// fetch new delivery page and insert the new delivery information on the page
function fetchDeliveryPageUpdate(){
	var objDeliveryPage = $('#tDelivery');
	var objForm = $('#formDelivery');
	
	var strNewReturnTo = '/dynamic.aspx?data=delivery';
	objForm.find('input[name="_ReturnTo"]').val(strNewReturnTo);
	objForm.find('input[name="IgnoreErrorMessage"]').val('1');
	
	objForm.ajaxSubmit({
		success: function(responseText, statusText, xhr, $form){
			var startCut = responseText.indexOf('<body');
			var endCut = responseText.indexOf('</body>') + 7;
			
			var newDeliveryPage = $(responseText.substring(startCut, endCut));
			objDeliveryPage.replaceWith(newDeliveryPage);

			$('#formDelivery').formvalidation();
			autocompletePostalCode3('#tDelivery #addrPostalcode', '#tDelivery #addrCity', '#tDelivery #addrCountry');
			autocompletePostalCode3('#tDelivery #addrPostalcode2', '#tDelivery #addrCity2', '#tDelivery #addrCountry2');
			$('#tDelivery').find('.secondaryAddress:hidden .secondaryAddresinput').attr('disabled','disabled');
			
			$('.shopflowForm, .shopflow').find('.accordianHeader').click(function(){
				$(this).toggleClass('open').next('div').slideToggle('fast');
			}).next('div').hide();
		}
	});
}



function activateProductdescriptionReadMore(){
	var intChildrenHeightSum = 0;

	// collect the height from all productdescription children
	$('#productDescription').children(':visible').each(function(){
		intChildrenHeightSum += $(this).outerHeight(true);
	});
	
	$('#productDescription').css('height','').data('originalHeight', $('#productDescription').height()).data('childrenHeightSum',intChildrenHeightSum);
	
	// if the sum of all the childrens heights is higher than the container
	if (intChildrenHeightSum > $('#productDescription').outerHeight()){
		// show the read more / collapse button and give it the default state, regardless of what it was before.
		
		$('#expandProductdescription').show()
		.find('span:first').show()
		.next().hide();
		
	} else {
		// hide the read more / collapse button
		
		$('#expandProductdescription span').hide();
	}
	
}

function updateProductLayoutCustom($container,$box,o){
	
	// find the variant object
	var objVariant = $box.find('option').eq($box.get(0).selectedIndex).data(o.optionVariantObjectName);
	
	// if there is no objVariant, then cancel the entire function
	if (typeof(objVariant) == 'undefined') {
		return false;
	}
	
	
	// insert the header of the variant into the page
	if (objVariant.header != '') {
		$('#productDescription').find('h2 span').html(objVariant.header).parent().removeClass('hidden');
	}
	
	// insert either the new description or show the original product description
	var objOriginalText = $('#productDescription').find('.textoriginal');
	if (objVariant.description != '') {
		if (objOriginalText.size() < 1) {
			$('<div class="textoriginal" style="display: none;"/>').html($('#productDescription').find('.text').html()).appendTo('#productDescription');
		}
		$('#productDescription').find('.text').html(objVariant.description);
	}
	else {
		if (objOriginalText.size() > 0) {
			$('#productDescription').find('.text').html(objOriginalText.html());
		}
	}
	
	activateProductdescriptionReadMore();
	
	
	// place a background image on the productpage
	if (objVariant.largeimagefilename != ''){
		 setTimeout(function () {
		 	$('body').css('background-image', 'url(/images/' + objVariant.largeimagefilename + ')');
		}, 10)
		
		
	};
	
	if (typeof(objVariant.variantarticles) != 'undefined'){
		
		//empty the current list
		$('#productlinks').find('ul li:not(.persistant)').remove();
		
		// fill out the list with new links
		for(var i=0, varArtLen = objVariant.variantarticles.length; i<varArtLen; i++){
			$('#productlinks').find('ul').append(
				$('<li><a class="jsPopup" href="' + objVariant.variantarticles[i].url + '">' + objVariant.variantarticles[i].header1 + '</a></li>')
			);
		}
		
		// add colorbox functionality on the link
		$('#productlinks a.jsPopup').colorbox({
			iframe: true,
			width: 710,
			height: 510,
			opacity: 0.65
		});
	};
}

// if popups are used on the page, show it
// have to be in the load event, since "ready state" is to early
$(window).load(function(){
	// set default id on the popup
	var strCurrentPKID = '0';
	
	// if the strPagePKID variable is set, replace the old id 
	if (typeof strPagePKID != 'undefined'){ strCurrentPKID = strPagePKID; }
	
	// if a popup should be shown and the cookie is not set to 1
	if ($('#pagePopup').size() > 0 && readCookie('pagePopup'+ strCurrentPKID) != '1'){
		$.colorbox({
			href: $('#pagePopup').attr('href'),
			iframe: true,
			width: '700',
			height: '80%',
			title: '<a href="#" onclick="closeAndHidePopup('+ strCurrentPKID +'); return false;">Luk og vis ikke igen</a>',
			onOpen: function(){
				$('#colorbox').addClass('pagePopup');
			},
			onClosed: function(){
				$('#colorbox').removeClass('pagePopup');
			}
		});
	}
});

// close and hide the pagePopup
function closeAndHidePopup(strPKID){
	createCookie('pagePopup' + strPKID,'1',1);
	$.colorbox.close();
}

// standard lightbox feature for productinfo page - building the container
function updateProductImagesLightbox(){
	
	$('#productImagesLightbox .imageContainer').find('img').remove()
		.end().prepend($('#productImages img').clone().removeAttr('id')).find('.zoom').remove()
		.end().find('img').each(function(){
	
			var strSrc = $(this).attr('src').replace('/thumbnail/','/productzoom/').replace('/productmain/','/productzoom/');
			$(this).attr('src',strSrc);
		
		}).hide();
	
} // updateProductImagesLightbox end


function autocompletePostalCode3(pcodeField, cityField, countryField) {
	if ($.isFunction($(this).autocomplete)) {//kontroller om autocomplete-funktionen er importeret
		$(pcodeField)
			.autocomplete('/dynamic.aspx?data=citynames&ajaxmode=1', {
				formatItem: function(row, i, max) {
					return row[0].replace('_',' ');
				},
				max: 9,
				extraParams: {
					countryid: function() { return $(countryField).val(); }
				},
				width: '200px'
			})
			.result(function(event, data, formatted){
				
				if (data) {
					var result = data[0].split('_');
					$(pcodeField).val(result[0]);
					if ($(pcodeField).val() != '') {
						$(cityField).val(result[1]);
					}
					else {
						$(cityField).val('');
					}
				}
				
				/*
				else {
					$(cityField).val('');
				}
				*/
				
			})
			.blur(function(){
				$this = $(this);
				if ($this.val() != ""){
					$.ajax({
						url: "/dynamic.aspx?data=citynames&ajaxmode=1",
						data: {
							q: $this.val(),
							countryid: $(countryField).val()
						},
						success: function(data){

							if(data != ""){
								var strFirstResult = data.match(/(.+)\n/i)[1].split('_');
								$(pcodeField).val(strFirstResult[0]);
								$(cityField).val(strFirstResult[1]);	
							}
							
						}
					});
				}
			});
		
		//$(cityField).attr('readonly', true).addClass('disabled');
	}
}


function activatePagePreloader(){
	$('#pagePreloader').fadeTo('fast',0.5);
}
function deActivatePagePreloader(){
	$('#pagePreloader').fadeOut('fast');
}

// productImagesLightbox buttons update
function updateLightboxButtons(){
	
	var $imageContainer = $('#productImagesLightbox').find('.imageContainer');
	var $prev = $imageContainer.find('.prev'),
			$next = $imageContainer.find('.next'),
			$img = $imageContainer.find('img:visible');
	
	// enable/disable the next-button as needed
	if ($img.nextAll('img').size() < 1){ $next.addClass('disabled'); }
	else { $next.removeClass('disabled'); }
	
	// enable/disable the prev-button as needed
	if ($img.prevAll('img').size() < 1){ $prev.addClass('disabled'); }
	else { $prev.removeClass('disabled'); }

} // updateLightboxButtons end



// beskrivelse
// version: 1.0 - 2010-06-08
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.formvalidation = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.formvalidation.defaults, options);
	
	
		// activate the script for each instans found in the selector
		return this.each(function(){
			var objForm = this;
			var $this = $(objForm);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			
			// if the 'allOk' is already set as a string on the form, validation is already active and does not need to be set again.
			if (typeof ($this.data('allOk')) == 'string'){
				return false;
			}
			
			$this.data('allOk', '1');
			
			// select all fields that require a certain mask validation
			$this.find('.jsValidate').bind('keyup blur', validateField);
			
			$this.submit($.fn.formvalidation.validate);
		});
	}
	
	$.fn.formvalidation.validate = function(){
		var $this = $(this), bitSendform = true;
		
		// Run a validation on all required fields
		$this.find(':input[name*=_Required], :input[name*=_required]').each(function(){
			var relatedInput = $this.find(':input[name=' + $(this).attr('name').replace(/_Required$/i, '').replace(/^_/, '') + ']');
			relatedInput.each(validateField);
		});
		
		// test if any active fields are not valid
		$this.find(':input').not('[disabled]').each(function(){
			var $input = $(this);
			
			if ($input.data('validatedOk') == false) {
				bitSendform = false;
			}
		});
		
		if (!bitSendform) {
			$this.data('allOk', '0');
			
			var strAlert = 'You have to fill out all required fields.';
			alert(strAlert);
			return false;
		} else {
			$this.data('allOk', '1');
		}
	}
	
	// single field validation
	function validateField(evt){
		var $this = $(this), objForm = $this.closest('form'), strActivateKeyup = 'jsTextfieldactivatekeyup', bitOk = true, re;
		
		if (evt.type != "keyup" || $this.hasClass(strActivateKeyup)) {
			// if the input doesn't allow keyup events, activate it (this happens at first blur event)
			if (!$this.hasClass(strActivateKeyup)) {
				$this.addClass(strActivateKeyup);
			}
			
			// validate field
			
			/*
			 * Valideringen skal understoette foelgende data, krav og afgraensninger:
			 *
			 * Fornavn og efternavn skal indeholde tekst.
			 * Gade skal indeholde minimum et ord efterfulgt af et mellemum og et tal.
			 * postnummer skal vaere 4 tegn i Danmark.
			 * By bliver automatisk indsat efter postnummer.
			 * Telefon skal indeholde 8 tegn for dansk tlf.nummer.
			 * E-mail skal indeholde min. 1 tegn efterfulgt af et @ (snabel a) efterfulgt af min. 1 tegn efterfulgt af et . (punktum) efterfulgt af 2-4 karakterer.
			 *
			 *
			 * For at identificere de forskellige felttyper, skal hvert felt have en css klasse der fort�ller hvordan feltet skal valideres.
			 * Forslag til css klasser, der kan benyttes til validering samt beskrivelse af hvad de skal validere:
			 *
			 * jsValidate: bruges kun til at identificere hvilke felter der skal valideres.
			 * jsValidatetext: validerer om feltet ikke er tomt - dette skal vaere basis form for validering, alle andre valideringstyper goer automatisk dette
			 * jsValidatefullname: kontrollerer om der er minimum 2 ord i feltet
			 * jsValidatepostalcode: tester om postnummeret er korrekt i forhold til det enkelte lands krav
			 * jsValidatephone: Ser om telefonnummeret er indtastet korrekt i forhold til landets krav
			 * jsValidatemail: E-mail skal indeholde de paakraevede dele specificeret ovenfor
			 * jsValidateaddress: Korrekt indtastet adresse - efter ovenstaaende specifikation
			 * jsValidaterepeat: Tester om teksten i feltet er det samme som i feltet med det tilknyttede ID (i css klassen "jsValidaterepeatfromIDPAAFELT"
			 *
			 *
			 */
			// test if there is a required field for this input field
			var strCurrentName = $this.attr('name');
			var objRequiredField = $('input[name="_' + strCurrentName + '_required"], input[name="_' + strCurrentName + '_Required"]', objForm);
			var bitRequired = (objRequiredField.size() > 0);
			
			if ($this.hasClass('jsValidatetext')) {
				re = /.+/;
			}
			else 
				if ($this.hasClass('jsValidatefullname')) {
					re = /[^ ]+ [^ ]+/;
				}
				else 
					if ($this.hasClass('jsValidatepostalcode')) {
						// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 4 cifre
						//re = /^\d{4}$/;
						re = /^\d+$/;
					}
					else 
						if ($this.hasClass('jsValidatephone')) {
							// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 8 cifre
							re = /^\d{8}$/;
						}
						else 
							if ($this.hasClass('jsValidatemail')) {
								re = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i;
							}
							else 
								if ($this.hasClass('jsValidateaddress')) {
									re = /^(.)+\s[1-9]/;
								}
								else {
									// hvis der ikke er nogen specifik validering, skal der alligevel valideres paa om der er indhold i feltet.
									re = /.+/;
								}
			
			bitOk = re.test($this.val());
			
			// hvis feltet er et repeat felt, f.eks. gentag password eller e-mail,
			// skal valideringen i stedet gaa paa om feltets indhold er det samme som det tilknyttede
			if ($this.hasClass('jsValidaterepeat')) {
				var strAllclasses = $this.attr('class').split(' '), strOriginalInputId;
				
				$.each(strAllclasses, function(i, val){
					if (val.indexOf('jsValidaterepeatfrom') > -1) {
						strOriginalInputId = val.replace('jsValidaterepeatfrom', '');
						
						return false;
					}
				});
				
				bitOk = ($this.val() == $('#' + strOriginalInputId).val() && $this.val != '');
			}
			
			// hvis et postalcode felt ikke indeholder tal mellem 1000 og 9999, skal der vises en fejl
			/*
			if ($this.hasClass('jsValidatepostalcode') && bitOk) {
				var intPostal = parseInt($this.val());
				if (intPostal < 1000 || intPostal > 9999){
					bitOk = false;
				}
			}
			*/
			
			if ((bitRequired && bitOk) || (!bitRequired && $this.val() != '' && bitOk)) {
				// hvis feltet er korrekt udfyldt
				$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
				$this.addClass('textfield_valid').siblings('.validationMessage').addClass('validationMessageValid');
				
				$this.data('validatedOk', true);
			}
			else 
				if ((bitRequired && !bitOk) || (!bitRequired && $this.val() != '' && !bitOk) || (bitRequired && $this.val() == '')) {
					// hvis feltet ikke er udfyldt korrekt.
					$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
					$this.addClass('textfield_error').siblings('.validationMessage').addClass('validationMessageError');
					
					$this.data('validatedOk', false);
				}
				else
					if ($this.val() == '' && !bitRequired) {
						// hvis feltet ikke er udfyldt og det ikke er paakraevet
						$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
						$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
						
						$this.data('validatedOk', true);
					}
					else {
					}
		}
	} // validateField end
	
	
	
	// default values for the options
	$.fn.formvalidation.defaults = {
		option: 'value'
	};

})(jQuery);


// searchSuggest - type ahead
// version: 1.0 - 2010-07-23
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt.
	//		Udvid funktionalitet, så man kan kalde/aktivere søgningen direkte fra javascript ved at kalde det på ca. denne måde: $(selector).searchSuggest.search().
	//		Lav callback funktioner.
	//		Burde man kunne navigere ned igennem listen af resultater med keyboardet? Hvis man skal, skal det være en option og hvordan skulle det gøres med et fleksibelt system - der skal være en form for selector-option tilknyttet så?
	
	
	$.fn.searchSuggest = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.searchSuggest.defaults, options);

		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// remove the autocomplete from the input
			$this.attr('autocomplete','off').keyup(function(e){
				var intKey = e.keyCode;
				// only allow certain keystrokes
				if ((intKey > 47 && intKey < 58) || (intKey > 36 && intKey < 41) || (intKey > 64 && intKey < 91) ||
						(intKey > 96 && intKey < 112) || (intKey > 185 && intKey < 223) ||
						intKey == 32 || intKey == 226 ||
						intKey == 46 || intKey == 8){
			
					// if the timeout is still counting down, cancel it to stop the client from hammering the server with search requests
					if (typeof($.fn.searchSuggest.searchSuggestTimeout) != 'undefined') {
						clearTimeout($.fn.searchSuggest.searchSuggestTimeout);
					}
					
					// set the timeout to when the search should be made after last keystroke
					$.fn.searchSuggest.searchSuggestTimeout = window.setTimeout(function(){
						searchSuggestAjax($this,o);
					}, o.timeout);
				}
			});
		});
	}
	
	
	// timeout container for the searchsuggestion container
	$.fn.searchSuggest.searchSuggestTimeout;
	
	
	// search suggest ajax request
	// strSort: optional method of sorting
	function searchSuggestAjax($this,o,strSort){
		
		// if no sorting method has been chosen, use the default
		if (!strSort){
			strSort = o.defaultSort
		};
		
		if ($this.val().length >= o.minLength) {
			var strQuery = '/dynamic.aspx?ajaxmode=1&data=' + o.ajaxDataFormat + '&template=' + o.ajaxTemplate + '&sort=' + strSort + '&searchtext=' + $this.val();
			
			$.ajax({
				url: strQuery,
				type: 'get',
				success: function(data){
					
					// collect the position and dimensions of the searchfield
					var inputX = $this.offset().left,
							inputY = $this.offset().top,
							inputHeight = $this.outerHeight(),
							inputWidth = $this.outerWidth();
					
					// position the search container below the searchfield aligned to the left.
					var containerX = inputX + o.offsetX,
							containerY = inputY + inputHeight + o.offsetY;
					
					// If horisontalAlign is set to right, position the search container to be aligned to the right
					if (o.horisontalAlign == 'right'){
						containerX = inputX - (o.containerCss.width - inputWidth);
					}
					
					// set the default container CSS and let the user extend it as needed
					var containerCssObject = $.extend({
						position: 'absolute',
						top: containerY,
						left: containerX,
						zIndex: o.zIndex
					}, o.containerCss);
					
					//if the container do not already exist, create it and append it to the body
					if ($('#' + o.containerId).size() == 0){
						var ajaxSearchBox = $('<div/>',{
							'id': o.containerId,
							css: containerCssObject,
							html: data
						}).css('opacity',0).appendTo('body').fadeTo(200,1);
					} else {
						// if the container already exists, just replace the content with new data
						$('#' + o.containerId).html(data);
					}
					
					// unbind previous events and append new ones.
					// if the user press Esc on the keyboard or click outside the search container, close the search container and unbind the events
					$(document).unbind('.searchSuggest').bind('keyup.searchSuggest click.searchSuggest',function(e){
						if (e.which == 27 || (e.type == 'click' && !$(e.target).closest('#'+o.containerId).size() > 0)) {
							$('#'+o.containerId).remove();
							$(document).unbind('.searchSuggest');
						}
					});
					
					if (o.afterAjax) {
						o.afterAjax();
					}
				}
			});
		} else {
			$('#'+o.containerId).remove();
		}
	}
	
	
	// default values for the options
	$.fn.searchSuggest.defaults = {
		ajaxDataFormat: 'products',
		ajaxTemplate: 'ajaxsearch',
		containerCss: {
			background: '#fff', // IE6-7 bugfix, so elements can't be clicked through the searchcontainer. It can be replaced with a (transparent) background-image instead.
			width: 300
		},
		containerId: 'ajaxSearchSuggestContainer',
		defaultSort: 'pop',
		horisontalAlign: 'right',
		minLength: 2,
		offsetX: 0,
		offsetY: 5,
		timeout: 200,
		zIndex: 1000,
		afterAjax: null
	};

})(jQuery);


function initializeBBQ(){
	
	// to prevent any empty page reloads, test if $ exists
	if (typeof $ == 'undefined') {
		return false;
	}
	
	// cancel the BBQ integration if the confirmation page is loaded
	if ($('#tConfirmation').size() > 0 || $('.shopflowForm, .shopflow').size() > 0) {
  	return false;
  }
	
	// insert the needed classes and default content
	$('#site').addClass('jsBbq');
	$('#siteMain').addClass('jsBbq-content').wrapInner('<div class="jsBbq-default"/>');
	
	// For each .bbq widget, keep a data object containing a mapping of
	// url-to-container for caching purposes.
	$('.jsBbq').each(function(){
		$(this).data('bbq', {
			cache: {
				// If url is '' (no fragment), display this div's content.
				'': $(this).find('.jsBbq-default'),
				'/': $(this).find('.jsBbq-default')
			}
		});
	});
	
	// For all links inside a .jsBbq widget, push the appropriate state onto the
	// history when clicked.
	$('#areaMenu a[href^="/groups/"], #siteBreadcrumb a[href^="/groups/"]').live('click', function(e){
		var state = {},  // Get the id of this .jsBbq widget.
		id = $(this).closest('.jsBbq').attr('id'),  // Get the url from the link's href attribute, stripping any leading #.
		url = $(this).attr('href');
		
		// Set the state!
		state[id] = url;
		$.bbq.pushState(state);
		
		// save the request for the latest clicked url, so the callback knows which to show, even if the return order is not the same as the requested order
		$(this).closest('.jsBbq').data('currentLinkUrl',url);

		// And finally, prevent the default link click behavior by returning false.
		e.preventDefault();
		//return false;

	});
	
	// Bind an event to window.onhashchange that, when the history state changes,
	// iterates over all .bbq widgets, getting their appropriate url from the
	// current state. If that .bbq widget's url has changed, display either our
	// cached content or fetch new content to be displayed.
	$(window).bind('hashchange', function(e){
	
		// Iterate over all .bbq widgets.
		$('.jsBbq').each(function(){
			var that = $(this),   // Get the stored data for this .bbq widget.
			data = that.data('bbq'),   // Get the url for this .bbq widget from the hash, based on the
			// appropriate id property. In jQuery 1.4, you should use e.getState()
			// instead of $.bbq.getState().
			url = $.bbq.getState(that.attr('id')) || '';
			
			// If the url hasn't changed, do nothing and skip to the next .bbq widget.
			if (data.url === url || url == '') {
				return;
			}
			
			// Store the url for the next time around.
			data.url = url;
			
			// Remove .bbq-current class from any previously "current" link(s).
			that.find('a.selected').removeClass('selected');
			
			// Hide any visible ajax content.
			that.find('.jsBbq-content').children(':visible').hide();
			
			// Add .bbq-current class to "current" nav link(s), only if url isn't empty.
			url && that.find('#areaMenu a[href="' + url + '"]').addClass('selected');
			
			// create a url to the dynamic page, to get a faster and smaller page
			// the url could be built up of a dataformat, key and template
			var arrLinkUrl = url.substr(1).split('/');
			var strLinkUrl = '/dynamic.aspx?ajaxmode=1';
			var strBreadcrumbUrl = '/dynamic.aspx?ajaxmode=1&data=breadcrumb';
			
			if (arrLinkUrl[0] && arrLinkUrl[0] != '') {
				strLinkUrl = strLinkUrl + '&data=' + arrLinkUrl[0];
				strBreadcrumbUrl = strBreadcrumbUrl + '&maindata=' + arrLinkUrl[0];
			}
			if (arrLinkUrl[1] && arrLinkUrl[1] != '') {
				strLinkUrl = strLinkUrl + '&key=' + arrLinkUrl[1];
				strBreadcrumbUrl = strBreadcrumbUrl + '&mainkey=' + arrLinkUrl[1];
			}
			if (arrLinkUrl[2] && arrLinkUrl[2] != '') {
				strLinkUrl = strLinkUrl + '&template=' + arrLinkUrl[2];
				strBreadcrumbUrl = strBreadcrumbUrl + '&maintemplate=' + arrLinkUrl[2];
			}
			
			// update the breadcrumb if the URL contains something
			if (url) {
				$('#siteBreadcrumb').load(strBreadcrumbUrl + ' >div');
			}
			
			if (data.cache[url]) {
				// Since the widget is already in the cache, it doesn't need to be
				// created, so instead of creating it again, let's just show it!
				data.cache[url].show();
				
			}
			else {
				// Show "loading" content while AJAX content loads.
				that.find('.jsBbq-loading').show();
				
				// Create container for this url's content and store a reference to it in
				// the cache.
				
				
				//data.cache[url] = $('<div class="jsBbq-item"/>')				// Append the content container to the parent container.
				//.appendTo(that.find('.jsBbq-content'));
				
				$.ajax({
					url: strLinkUrl,
					success: function(strData){
						
						// find the body element  
						var startCut = strData.indexOf('<body');
						var endCut = strData.indexOf('</body>') + 7;
						
						// Create container for this url's content and store a reference to it in
						// the cache.
					
						var strStyle = '';
						if( that.data('currentLinkUrl') != url && typeof that.data('currentLinkUrl') != 'undefined') {
							strStyle = ' style="display: none;"';
						}
					
						// if the new page has content, insert it and scroll to it
						data.cache[url] = $('<div class="jsBbq-item"' + strStyle + '/>')				// Append the content container to the parent container.
						.appendTo(that.find('.jsBbq-content'))
						.html($(strData.substring(startCut, endCut)));
						
						// reactivate the add and subtract features on productlists 
						$('.jsQuantity').quantityAddSubtract();
						
						/*
						$('.tProducts').ajaxProductlistpaging({
							beforeAjaxAnimation: function(){
								$('.jsQuantity').quantityAddSubtract();
							}
						});
						*/
						
						// Content loaded, hide "loading" content.
						that.find('.jsBbq-loading').hide();
					}
				});
				
			/*
			 // Load external content via AJAX.
			 .load( strLinkUrl + ' >div', function(){
			 // reactivate the add and subtract features on productlists
			 $('.jsQuantity').quantityAddSubtract();
			 
			 $('.tProducts').ajaxProductlistpaging({
			 beforeAjaxAnimation: function(){
			 $('.jsQuantity').quantityAddSubtract();
			 }
			 });
			 
			 // Content loaded, hide "loading" content.
			 that.find( '.jsBbq-loading' ).hide();
			 });
			 */
			}
		});
	});
	
	// Since the event is only triggered when the hash changes, we need to trigger
	// the event now, to handle the hash the page may have loaded with.
	$(window).trigger('hashchange');
}


/*
// if productvariants are available, find the input fields and activate Ajax implementation on them 
function variantSelection(){
	if ($('#productVariants').size() > 0){
		productVariantAjax();
		$('#productVariants').find(':input').change(productVariantAjax);
	}
}
*/

// common functionality for the variantSelection function - specific for NUPO 
function productVariantAjax(){
	var $this, noElement;
	
	if (this.name){
  	$this = $(this);
		noElement = false;
	} else {
		$this = '';
		noElement = true;
	}
	
	// clear the productid everytime we mess around with the variants
	$('#productVariants').closest('form').find('input[name="productid"]').val('');
	
	if ($(this).val() != '' || $this == '') {
  	
		var objBox, intIndex;
		if (noElement) { // if there is not an element in $this
			intIndex = 0;
			objBox = $('#productVariants').find(':input').eq(0); // return the first box
		}
		else {
			intIndex = $('#productVariants').find(':input').index(this); // the index of the current item in the object
			if ($('#productVariants').find(':input').eq(intIndex + 1).size() > 0) {
				objBox = $('#productVariants').find(':input').eq(intIndex + 1); // the next box
			}
			else {
				objBox = null;
			}
		}
		
		if ($this != ''){
			
				if ($this.data('variants') != ''){
					
					var arrData = $this.data('variants').split('|'),
							strNewImage = '',
							strNetPrice = '',
							strNetPrice2 = '';
					
					$.each(arrData,function(i){
						arrVariant = arrData[i].split(';');
						
						
						var strVariantValue = $this.val();
						
						if ($this.val().indexOf('$') != -1){
							strVariantValue = $this.val().split('$')[1];
						}
						
						var intIndexArray = $.inArray(strVariantValue,arrVariant);
						if (intIndexArray != -1){
						
							strNewImage = arrVariant[1];
							strNetPrice = arrVariant[2];
							strNetPrice2 = arrVariant[3];
							return false;
						
						}
					
					});
					
					// change images based on variants, if there is an image specified and there is an actual productimage on the page.
					if ($('#productImages').size() > 0){
					
						var objFirstimage = $('#productImages').find('img:first');
						var objFirstimageLink = objFirstimage.parent('a');
						if (objFirstimage.size() > 0 && strNewImage != '' && strNewImage != 'undefined'){
				
							var intIndexOfSlash = objFirstimage.attr('src').lastIndexOf('/')+1;
							objFirstimage.attr('src',objFirstimage.attr('src').substring(0,intIndexOfSlash) + strNewImage);
							
							if (objFirstimageLink.size() > 0) {
								var intIndexOfSlash2 = objFirstimageLink.attr('href').lastIndexOf('/')+1;
								objFirstimageLink.attr('href',objFirstimageLink.attr('href').substring(0,intIndexOfSlash2) + strNewImage);
							}
						}
						
						// if we have a lightbox container that should be updated, execute this function, if it exists
						if (typeof updateProductImagesLightbox == 'function'){
							updateProductImagesLightbox();
						}
					}
					
					
					// change netprice of the product, if it exists on the page and there is something in the variable
					if ($('#jsProductnetprice').size() > 0 && strNetPrice != '' && strNetPrice != '0,00' && strNetPrice != '0.00'){
						$('#jsProductnetprice').text(strNetPrice);
					}
					
					// change netprice2 of the product, if it exists on the page and there is something in the variable
					if ($('#jsProductnetprice2').size() > 0 && strNetPrice2 != '' && strNetPrice2 != '0,00' && strNetPrice2 != '0.00'){
						$('#jsProductnetprice2').text(strNetPrice2);
					}
					
				}
			
		}
		
		// when changing the last box, it must insert the value into the productid
		if (!objBox){
			if ($this.val() != ''){
				$('#productVariants').closest('form').find('input[name="productid"]').val($this.val());
			}
		} else {
			$('#productVariants').closest('form').find('input[name="productid"]').val('');
			objBox.attr('disabled', 'disabled'); // disable the object, that will be updated
		
			var bolLast = false;
			if ($('#productVariants').find(':input').index(objBox) == $('#productVariants').find(':input:not(:last)').size()){ // define whether this is the last object
				bolLast = true;
			}
			
			// if we are not working with an element, strVars should not be set
			var strVars;
			if (noElement){
				strVars = '';
			} else {
				
				
				var collectedVars = '';
				var intStopAtIndex = $('#productVariants').find(':input').index($this);
				
				// run through all variants and collect the previous variantinformation
				$('#productVariants').find(':input').each(function(i){
					
					if (i <= intStopAtIndex) {
					
						if ($(this).val()!= ''){
							if (i != 0){
								collectedVars += '|';
							} 
							collectedVars += $(this).val();	
						}
						
					}
					else {
						$(this).find('option[value !=""]').remove();
					}
					
					// stop when we reach the current element in the loop
					//if (i == intStopAtIndex){
					//	return false;
					//}
					
				});
				
				strVars = collectedVars;
			}
			

			// make an Ajax call to retrieve data for the next box

			$.ajax({
				url: '/dynamic.aspx',
				data: {
					ajaxmode: '1',
					data: 'utilizevariants',
					key: $('#productVariants').closest('form').find('input[name=original_productid]').val(),
					type: objBox.attr('id').replace('variant',''),
					vars: strVars,
					last: bolLast
				},
				dataType: 'text',
				success: function(data){
					var data2 = eval("(" + data + ")");
					var objVars = data2.variants.variant,
							strHtml = '<option value="">' + objBox.find('option').eq(0).text() + '</option>',
							strVariant = '';
						
					for(var i = 0; i<objVars.length;i++){
						if (objVars[i].productid != ''){
					
							strHtml += '<option value="' + objVars[i].productid + '">' + objVars[i].propertytext + '</option>';
							strVariant += '|' + objVars[i].productid;
					
						} else {
							strHtml += '<option value="' + objBox.attr('id').replace('variant','') + '$' + objVars[i].property + '">' + objVars[i].propertytext + '</option>';
							strVariant += '|' + objVars[i].property;
					
						}
					
						strVariant += ';' + objVars[i].imagefilename + ';' + objVars[i].netprice + ';' + objVars[i].netprice2;
					
					}
				
					objBox.html(strHtml); // insert the options into the box
					objBox.get(0).disabled = false; // enable the object again
					objBox.data('variants',strVariant.substring(1)); // insert the strImages without the first pipe

				},
				error: function(data,status,error){
//					log_debug(data);
//					log_debug(status);
//					log_debug(error);
				}

			});
			
		}
	}
}



// test if the basketpreivew should be resized, so that it needs scrolling functionality
function resizeBasketPreview(){
	var basketpreview = $('.basketpreview');
	var scrollContainer = $('.scrollContainer');
	var intWindowHeight = $(window).height();
	var intNewHeight;
	
	// hardcoded position, shadows and extra space
	var extraMargin = 50;
	
	// reset the height and remove the scroll buttons
	scrollContainer.height('auto');
	$('.basketScrollUp, .basketScrollDown').addClass('inactive');
	
	if ((basketpreview.outerHeight() + extraMargin) > intWindowHeight){
		// set the scrollbuttons to be active
		$('.basketScrollUp, .basketScrollDown').removeClass('inactive');
		
		// calculate the new height
		//intNewHeight = scrollContainer.height() - ((basketpreview.outerHeight() + extraMargin) - intWindowHeight);
		intNewHeight = 300;
		
		// set the new height to the scrollcontainer
		scrollContainer.height(intNewHeight);
	}
}

// make sure the basketpreview can be seen on small as well as large screens
function repositionBasketpreview(){
	var $window = $(this);
	var $bp = $('#siteBasketpreview');
	
	// find out what the mainmenu width is, so we don't overlay the menu
	var intMenuWidth = 0;
	$('#mainMenu').find('li').each(function(){
		intMenuWidth += $(this).outerWidth(true);
	});
	
	if (($bp.width() + $bp.data('baseLeft')) > $window.width()){
		// if the basketpreview right edge is higher than the window width
		
		if (($window.width() - $bp.width()) > intMenuWidth){
			// if the new position is higher than the intMenuWidth, reposition the basketpreview
			
			$bp.css('left',$window.width() - $bp.width());
		} else {
			// if the new position is equal or lower than the intMenuWidth, make sure the basketpreview
			// does not move infront of the menu by setting it to the width of the menu
			
			var intLeft = $window.width() - $bp.width();
			$bp.css('left',intMenuWidth);
		}
	} else {
		// otherwise the basketpreview right edge can be positioned at the base position correctly
		
		$bp.css('left','');
	}
}





// Variant system
// --------------------------------
// beskrivelse
// version: 1.0 - 2011-02-02
(function($){
// TODO:
//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.variantSystem = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.variantSystem.defaults, options);
		
		// activate the script for each instance found in the selector
		return this.each(function(){
			var $this = $(this);
			
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// We need the variantDataObject to continue - if this does not exist, we cannot continue
			if (o.variantDataObject != null){

				// start by clearing the productid inputfield, as it now needs to be a variant
				$this.closest('form').find('input[name="' + o.productidName + '"]').val('');
					
				// run a anonymous change function on every selectbox used for the variantsystem
				$this.find('select').change(function(){
					
					// run optional onBeforeChange callback function
					if (o.onBeforeChange) {
						o.onBeforeChange($this, $(this), o);
					}

					// everytime a selectbox is changed, we need to clear the productid in the form
					$this.closest('form').find('input[name="' + o.productidName + '"]').val('');
					
					// continue if an option with a value have been selected
					if ($(this).val() != '') {
			  		var objVariantcollection = $(this).find('option').eq(this.selectedIndex).data(o.optionDataObjectName)[0];
			  	
				  	// find out if we are on the last selectbox
						if (typeof(objVariantcollection) != 'undefined') {
							// there is a variantcollection and another selectbox
							
							var intNextBoxIndex = $this.find('select').index(this) + 1;
							
							// fill out the next variant selectbox
							fillVariantBox(o, $this, intNextBoxIndex, objVariantcollection);
						}
						else {
							// this is the final selectbox in the variant selection and we need to get the productid
							
							// get the productid
							var strProductid = $(this).val();
							
							// insert the prooductid in the correct inputfield in the form
							$this.closest('form').find('input[name="' + o.productidName + '"]').val(strProductid);
						}
						
						// if the updateBaseLayout is allowed to run, run it
						if (!o.disableUpdateBaseLayout){
							updateBaseLayout($this, $(this), o);
						}
						
						// run optional onUpdateLayout function to update the layout of the page (images, text, links etc.)
						if (o.updateLayout) {
							o.updateLayout($this, $(this), o);
						}
						
					}
					
					// run optional onBeforeChange callback function
					if (o.onAfterChange) {
						o.onAfterChange($this, $(this), o);
					}
					
				});
				
				// fill out the first variantbox
				fillVariantBox(o, $this);
				
				// run optional onCreate callback function
				if (o.onCreate) {
					o.onCreate($this, o);
				}
			} else {
				log_debug('ERROR in jQuery variantSystem plugin: the option "variantDataObject" is not set in the template - it is needed to activate the variantSystem plugin');
			}
		});
	}
	
	
	
	/**
	 * Fill variant box with data from the objVariantCollection, if it is supplied
	 * @param {Object} o	The options object for the plugin
	 * @param {jQueryObject} $productVariantContainer	The jQuery object for the containing element
	 * @param {number} intIndex	Index of the affected selectbox. Optional (if not specified, first selectbox will be chosen)
	 * @param {Object} objVariantCollection	The variantcollection object from the previously chosen option. Optional (if not specified, it will get the first variantcollection from objVariants)
	 */
	function fillVariantBox(o, $productVariantContainer, intIndex, objVariantcollection){
		var $variantBox, arrVariantValues;
		var intBoxIndex = 0;
		
		// if intIndex exists, use its value in intBoxIndex
		if (typeof(intIndex) != 'undefined') {
			intBoxIndex = intIndex;
		}
		
		// get the selectbox to insert new data into
		$variantBox = $productVariantContainer.find('select').eq(intBoxIndex);
		
		if ($variantBox.size() == 0){
			return false;
		}
		
		// set the array of values to insert into the selectbox
		if (typeof(objVariantcollection) != 'undefined'){
			// if the objVariantcollection parameter have been passed to us, use it
			
			arrVariantValues = objVariantcollection.values;
		} else {
			// otherwise use the first variantcollection in the data object
			
			arrVariantValues = o.variantDataObject.variantcollection[0].values;
		}
		
		// retrieve the first option (choose [varianttype])
		var $firstOption = $variantBox.find('option').eq(0);
		
		// empty the current options and append the previous first option (choose [varianttype])
		$variantBox.empty().append($firstOption);
		
		for(var i = 0, arrLength = arrVariantValues.length; i<arrLength;i++){
			// append new variant options and insert the variantcollection as a data object on the option
			
			// find the variant object for the current productid, so it can be stored as well
			var variantObject;
			for(var j=0, objVarsLength = o.variantDataObject.variants.length; j<objVarsLength; j++){
				if (o.variantDataObject.variants[j].productid == arrVariantValues[i].productid){
					variantObject = o.variantDataObject.variants[j];
					break;
				}
			}
			
			// setup and append the option to the selectbox along with some dataobjects
			$variantBox.append($('<option/>',{
				text: arrVariantValues[i].value,
				value: arrVariantValues[i].productid
			}).data(o.optionDataObjectName,arrVariantValues[i].variantcollection).data(o.optionVariantObjectName,variantObject));
		}
	}
	
	
	
	/**
	 * Update the base layout of the page with the new information, based on the given productid of the selectbox
	 * @param {jQueryObject} $productVariantContainer	The jQuery object for the containing element
	 * @param {jQueryObject} $box	The jQuery object for the selectbox which have been changed
	 * @param {Object} $box	The options object for the plugin
	 */
	function updateBaseLayout($productVariantContainer, $box, o){
		
		/*
		//TODO: make context work properly, so the updateBaseLayout function also is able to handle productlists
		
		var $productContext = $productVariantContainer.closest(o.outerLimitProduct);
		var $productListItemContext = $productVariantContainer.closest(o.outerLimitProductListItem);
		
		// if there is no context, we cannot figure out where to limit ourselves to and therefore we must stop here
		if ($productContext.size() == 0 && $productListItemContext.size() == 0){
			return false;
		}
		*/

		var objVariant = $box.find('option').eq($box.get(0).selectedIndex).data(o.optionVariantObjectName);
		
		// if there is no objVariant, then cancel the entire function
		if (typeof(objVariant) == 'undefined') {
			return false;
		}
		
		var strNewImage = '';
		var strNetPrice = '';
		var strNetPrice2 = '';
		var intInstock;
		
		
		if (typeof(objVariant.imagefilename) != 'undefined') {
			strNewImage = objVariant.imagefilename;
		}
		if (typeof(objVariant.netprice) != 'undefined') {
			strNetPrice = objVariant.netprice;
		}
		if (typeof(objVariant.netprice2) != 'undefined') {
			strNetPrice2 = objVariant.netprice2;
		}
		if (typeof(objVariant.instock) != 'undefined') {
			intInstock = objVariant.instock;
		}
		
		
		
		
		// change productimage based on variants, if there is an image specified and there is an actual productimage on the page.
		if ($('#productImages').size() > 0){
			
			var objFirstimage = $('#productImages').find('img:first');
			var objFirstimageLink = objFirstimage.parent('a');
			if (objFirstimage.size() > 0 && strNewImage != '' && strNewImage != 'undefined'){
	
				var intIndexOfSlash = objFirstimage.attr('src').lastIndexOf('/')+1;
				objFirstimage.attr('src',objFirstimage.attr('src').substring(0,intIndexOfSlash) + strNewImage);
				
				if (objFirstimageLink.size() > 0) {
					var intIndexOfSlash2 = objFirstimageLink.attr('href').lastIndexOf('/')+1;
					objFirstimageLink.attr('href',objFirstimageLink.attr('href').substring(0,intIndexOfSlash2) + strNewImage);
				}
			}
			
			// if we have a lightbox container that should be updated, execute this function, if it exists
			if (typeof updateProductImagesLightbox == 'function'){
				updateProductImagesLightbox();
			}
		}
		
		
		// change netprice of the product, if it exists on the page and there is something in the variable (not 0,00 and 0.00)
		if ($('#jsProductnetprice').size() > 0 && strNetPrice != '' && strNetPrice != '0,00' && strNetPrice != '0.00'){
			$('#jsProductnetprice').text(strNetPrice);
		}
		
		// change netprice2 of the product, if it exists on the page and there is something in the variable (not 0,00 and 0.00)
		if ($('#jsProductnetprice2').size() > 0 && strNetPrice2 != '' && strNetPrice2 != '0,00' && strNetPrice2 != '0.00'){
			$('#jsProductnetprice2').text(strNetPrice2);
		}
		
		
		// change instock status to the chosen variant
		if (!isNaN(intInstock) && $('#productBasicProperties').size() > 0){
			if (intInstock < 1){
				$('#productBasicProperties').find('.instock').hide();
				$('#productBasicProperties').find('.notinstock').show();
			} else {
				$('#productBasicProperties').find('.instock').show();
				$('#productBasicProperties').find('.notinstock').hide();
			}
		}
		
	}
	
	// default values for the options
	$.fn.variantSystem.defaults = {
		productidName: 'productid',
		variantDataObject: null,
		optionDataObjectName: 'variantcollection',
		optionVariantObjectName: 'variant',
		onCreate: null,
		onBeforeChange: null,
		onAfterChange: null,
		updateLayout: null,
		disableUpdateBaseLayout: false,
		outerLimitProduct: '#tProductinfo',
		outerLimitProductListItem: '.productlistVerbose li'
	};
})(jQuery);

// Imagesets handler
function HandleImagesets()
{
	/*$("#productImages .scrollable").scrollable();*/
	/*$('#ImageListCarouselWindow').cycle({ 
		fx:     'scrollRight', 
		speed:  'fast', 
		timeout: 0, 
		next:   '#prevNext', 
		prev:   '#prevBack' 
	});*/
	/*$('.prevBack').click(function(e) {
		e.preventDefault();
	});*/
}

