/** 
 * viega.catalog_usa.js
 * viega Product Catalog
 *
 * @author       ecomplexx, www.ecomplexx.com
 * @version      $Revision: 419 $ 
 * @date         $Date: 2009-07-17 17:08:27 +0200 (Fr, 17 Jul 2009) $
 * 
 * @requires jQuery
 */

/*jslint browser: true */
/*global window: false, jQuery: false, $: false, countryTopLevelDomain: true, cmsProductgroupPages: false, catalog_lang: false, shop: false, webtrekk: false, wt_be: true, wt_be2: true, wt.sendinfo: false */


var catalog = (function()
{
	// Basic configuration 
	var wsBaseUrl           = window.wsBaseUrl || '/axis2/services/LiveCatalogService/';         // Web service base url

	var wsTimeout           = 60;                                        // Web service timeout (milliseconds)

	var error404            = '/error404.html';                          // 404 Error page
	var modelImageUrl       = '/catalog/images/models/';                 // Base url for product images
	var modelThumbUrl       = '/catalog/images/model_thumbnails/';       // Base url for product thumbnails
	var pgImageUrl          = '/catalog/images/productgroups/';          // Base url for product groups color images
	var discountImageUrl    = '/catalog/images/discountgroups/';         // Base url for discount group icons
	
	var currency            = '$';                                       // Currency of article prices
	var breadcrumbBaseLevel = 0;                                         // Base length of breadcrumb (starting at 0)

	
	// Variable initialization
	var productFields  = {};                                             // Data storage for 'getBereiche', also used to render navigation
	var registeredUser = false;                                          // Show shop component only for logged in users
	var lastProductgroup;                                                // Stores last selected product group, so CMS content doesn't get loaded twice
	var lastNode = (window.location.hash === '' ? window.location.href : window.location.href.substring(0, window.location.href.indexOf('#') - 1));
	                                                                     // Stores the last node for back link
	var isProductGroupMetric = false;
	var countryCode = 'us';

	
	// -- Private Functions ---------------------------------------------------
	/**
	 * Fix catalog "buttons" as IE doesn't know display:table-cell
	 * 
	 * @private
	 */
	function fixButtonListIE() {
		if (isIE)
		{
			$('ul.group span').each(function() {
				$(this).css({
					'margin-top': Math.ceil( ( 60 - $(this).height() ) / 2 ),
					'display': 'block'
				});
			});
		}			
	}


	/**
	 * Check if the user is logged in and is allowed to see the shop component
	 * US catalog has no shop, thus returning false
	 * 
	 * @private
	 * @return {Bool}
	 */
	function isRegisteredUser() {
		return false;		
	}
	

	/**
	 * Renders left hand subnavigation for active page
	 * 
	 * @see #getBreadcrumb
	 * @private
	 * @param {String} field           Current product field
	 */
	function renderLeftNavigation(field, level) {
		var subnav = $('#sub-navigation');
		var subnav2ndLevel = $("a:exact('" + field + "')", subnav).parent();
		
		// Exit if field not found (e.g. via $.accordion function)
		if (subnav2ndLevel.length === 0) { return; }

		// Reset navigation highlight		
		$(subnav).find('div').removeClass('selected').addClass('open').end()
			.find('li').removeClass().end()
			.find('ul li ul').hide().end();
		$(subnav2ndLevel).addClass(((level && level >= 3) ? 'open' : 'selected'));

		// Attach subnavigation if not rendered yet
		if ($('li', subnav2ndLevel).length === 0)
		{
			var content = '<ul>';
			var productGroup = productFields[field];
			for (var group=0;group<productGroup.length;group++)
			{
				content += '<li><a href="#scope-' + productGroup[group].id + '">' + productGroup[group].number + ' ' + productGroup[group].name + '</a></li>';
			}
			content += '</ul>';
			subnav2ndLevel.append(content);
			
			if (window.webtrekk)
			{
				// Webtrekk: Subnavigation
				$('a', subnav2ndLevel).click(function(){
					var wtParameter = [wt_be + '.link.sub_navigation.' + $.trim($(this).text()) + '.click', 'link'];
					webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);
				});
			}
		} else {
			$('ul', subnav2ndLevel).show();
		}
	}	


	/**
	 * Renders product fields output
	 * 
	 * @see #getBereiche
	 * @private
	 */
	function renderProductFields() {
		var content = '';

		// Hide other DIVs
		$('#tabs').hide();

		var fieldCount = 0;
		for (var field in productFields)
		{
			if (field == "length") { continue; }           // 'length' is an onject property
			content += '<h3><span class="field' + fieldCount + '">' + field + '</span></h3><ul class="group">';
				
			var productGroup = productFields[field];
			for (var group=0;group<productGroup.length;group++)
			{
				var groupId = productGroup[group].id;
				content +='<li' + ( (group % 2 === 0) ? '' : ' class="even"' ) + '><a href="#scope-' + productGroup[group].id + '"><img src="' + pgImageUrl + productGroup[group].number + '.jpg" width="58" height="58" alt="' + productGroup[group].number + ' ' + productGroup[group].name + '" /><strong>' + productGroup[group].number + '</strong><span> ' + productGroup[group].name + '</span></a>';
			}
			content += '</ul>';
			fieldCount++;
		}
		
		$('#productgroups').html(content).show();
		fixButtonListIE();                // IE needs a special treatment ... as always.
		if (fieldCount > 1)
		{
			$('#productgroups').accordion(); // IMPORTANT: Collapse after IE fix, otherwise spans have zero-height
		} else {
			// Switch navigation on first catalog level	
			catalog.renderLeftNavigation($('#productgroups span:eq(0)').text(), 0);
		}
	}


	/**
	 * Renders model list
	 * 
	 * @see #getModelle
	 * @see #findModelleFullText
	 * @private
	 * @param {DOM} xml                       XML document from web service
	 * @param {Object} produktUntergruppenId  Name of product subgroup for headline (optional),
	 *                                        if empty, the page is considered to be a search result
	 */
	function renderModels(xml, produktUntergruppenId) {
		if ($('return', xml).children().length === 0) { return false; }
		
		// Hide other DIVs
		$('#productgroups').hide();
		$('#tabs').show().find('> div:visible:not(#productmodels, #cmscontent)').hide();

		var modelCount = 0;	
		var content = '<ul class="group">';
		$('return', xml).each(function()
		{
			var modelId             = $(this).children('id').text();
			var modelName           = $("name:exact('Modellbezeichnung')", this).siblings('value').text().replace(/<[^>]*>/g, '').replace(/[^\w\d]$/, '');
			var modelNumber         = $("name:exact('ModellNummer')", this).siblings('value').text();
			var modelNumberComplete = $("name:exact('ModellnummerKomplett')", this).siblings('value').text();
			var modelImage          = $("name:exact('Picture_Color')", this).siblings('value').text().replace(/\.(eps|tif|tiff|gif|pdf)/gi, '.jpg');
			if (modelImage === '') { modelImage = $("name:exact('Abbildung')", this).siblings('value').text().replace(/\.(eps|tif|tiff|pdf)/gi, '.jpg'); }
			var modelImageTable     = $("name:exact('Wertetabelle')", this).siblings('value').text();

			// Distinguish dummy models
			if (parseInt(modelNumber, 10) !== 0 && parseInt(modelNumberComplete, 10) !== 0)
			{
				content += '<li' + ((modelCount % 2 === 0) ? '' : ' class="even"') + '><a href="#modeldetail-' + modelId + '" title="' + catalog_lang.model + ' ' + modelNumberComplete + '"><img src="' + modelThumbUrl + modelImage + '" width="58" height="58" alt="' + modelName.replace(/<br(?: \/)?>/gi, ' ') + '" /><strong style="width:0px"></strong><span>' + modelName + '</span></a>';
				modelCount++;
			} else {
				// Decorative model
				var nodeType = $("name:exact('Knotentyp')", this).siblings('value').text();
				if (nodeType.indexOf('Schmuckmodell') === 0)
				{
					// modelImage
					var decorativeImage = $("name:exact('Picture_Color')", this).siblings('value').text().replace(/\.(eps|tif|tiff|gif|pdf)/gi, '.jpg');
					if (decorativeImage === '') { decorativeImage = $("name:exact('Abbildung')", this).siblings('value').text().replace(/\.(eps|tif|tiff|pdf)/gi, '.jpg'); }
					var decorativeText  = $("name:exact('Schmuckmodelltext')", this).siblings('value').text();
					var decorativeTextShort = '';
					
					if (decorativeText !== '')
					{
						// Extract first text line
						var tempTextShort = decorativeText.match(/([\d\w\s-?üäöÜÄÖ]+)/);
						decorativeText = decorativeText;
						decorativeTextShort = ': ' + ((tempTextShort) ? tempTextShort[0] : decorativeText);
					}
					content += '<li' + ((modelCount % 2 === 0) ? '' : ' class="even"') + '><a class="decorative" title="' + decorativeText.replace(/<br(?: \/)?>/gi, ' ') + '" href="javascript:void(0)" onclick="imagePopup(\'' + modelImageUrl + modelImage + '\', \'' + escape(decorativeText) + '\');">';
					//'<img src="' + modelThumbUrl + modelImage + '" width="58" height="58" alt="' + modelName.replace(/<br(?: \/)?>/gi, ' ') + '" />
					content += '<strong style="width:0px"></strong><span><b>' + catalog_lang.decorative + '</b>' + decorativeTextShort + '</span></a>';
					modelCount++;
				} else {
					// Dummy model
					modelName = $("name:exact('Langtext')", this).siblings('value').text().replace(/[^\w\d]$/, '').replace(/<br(?: \/)?>/gi, ' ');
					if (modelName !== '')
					{
						
						var modelNameShort = modelName;
						if (modelNameShort.length > 100)
						{
							// Limit text to 98 chars (98 + space + ellipsis = 100 chars)
							modelNameShort = modelNameShort.substr(0,98);      

							// Find last word or end of sentence
							var lastSpace = modelNameShort.lastIndexOf(' ');
							var lastPeriod = modelNameShort.lastIndexOf('.');
							modelNameShort = modelNameShort.substr(0, (lastSpace > lastPeriod) ? lastSpace : lastPeriod ) + ' …';
						}
						
						if (modelImage === '' && modelImageTable === '') {
							content += '<li' + ((modelCount % 2 === 0) ? '' : ' class="even"') + '><a class="noclick" title="' + modelName + '">';
							//'<img src="' + modelThumbUrl + modelImage + '" width="58" height="58" alt="' + modelName.replace(/<br(?: \/)?>/gi, ' ') + '" />
							content += '<strong style="width:0px"></strong><span>' + modelNameShort + '</span></a>';
						} else {
							// Yet another special case ... who could have imagined that?
							content += '<li' + ((modelCount % 2 === 0) ? '' : ' class="even"') + '><a class="decorative" title="' + modelName + '" href="javascript:void(0)" onclick="imagePopup(\'' + modelImageUrl + (modelImage !== '' ? modelImage : modelImageTable) + '\', \'\');">';
							content += '<strong style="width:0px"></strong><span>' + modelNameShort + '</span></a>';
						}	
						modelCount++;
					}					
				}
			}	
		});
		content += '</ul>';
		$('#productmodels').html(content).show();
		fixButtonListIE();  // IE needs a special treatment ... as always.
		if (produktUntergruppenId) { getBreadcrumb(produktUntergruppenId); } else { $('#tabs h2').text(catalog_lang.searchResult); }
	}


	/**
	 * Renders model's and dito-model's articles
	 * 
	 * @see #renderModelWithArticles
	 * @param {Object} node  XML node to use for display (may be model or dito-model)
	 * @param {DOM}    xml   XML document from web service
	 */
	function renderArticles(node, xml, modelAbmessungsflag, modelAusfuehrungsflag) {
		var content = '<thead><tr>' + 
			'<th class="article-number right first">' + catalog_lang.article.number + '</th>' + 
			'<th class="article-text">' + catalog_lang.article.text + '</th>' + 
			'<th class="article-unit right">' + catalog_lang.article.unit + '</th>' + 
			'<th class="article-weight right">' + (isProductGroupMetric ? catalog_lang.article.weight_g : catalog_lang.article.weight_lb) + '</th>' + 
			/*
			'<th class="article-price">' + catalog_lang.article.price + '</th>' + 
			'<th class="article-amount">' + catalog_lang.article.amount + '</th>' + 
			*/
			'</tr></thead><tbody>';
		
		var showDiscontinuedFlag = false;
		$(node, xml).each(function(i)
		{
			var text          = '';
			if ( modelAbmessungsflag )   { text += $("name:exact('Abmessung')", this).siblings('value').text(); }
			if ( modelAusfuehrungsflag ) { text += ((text !== '' ) ? ', ' + $("name:exact('Farbschlüssel')", this).siblings('value').text() : $("name:exact('Farbschlüssel')", this).siblings('value').text()); }
			text = $.trim(text);
			
			// Check which units are filled
			var packagingUnit1 = '';
			var packagingUnit2 = '';
			var packagingUnit3 = '';
			var packagingUnitUS = '';
			
			if ( $("name:exact('Verpackungseinheit1JN')", this).siblings('value').text() === 'j' )
			{
				packagingUnit1 = $.trim( $("name:exact('Verpackungseinheit1')", this).siblings('value').text() );
				packagingUnit1 = (packagingUnit1 !== '') ? packagingUnit1 + ' / ' : '';
			}	

			if ( $("name:exact('Verpackungseinheit2JN')", this).siblings('value').text() === 'j' )
			{
				packagingUnit2 = $.trim( $("name:exact('Verpackungseinheit2')", this).siblings('value').text() );
				packagingUnit2 = (packagingUnit2 !== '') ? packagingUnit2 + ' / ' : '';
			}	

			if ( $("name:exact('Verpackungseinheit3JN')", this).siblings('value').text() === 'j' )
			{
				packagingUnit3 = $.trim( $("name:exact('Verpackungseinheit3')", this).siblings('value').text() );
				packagingUnit3 = (packagingUnit3 !== '') ? packagingUnit3 + ' / ' : '';
			}	

			if ( $("name:exact('VerpackungseinheitUSJN')", this).siblings('value').text() === 'j' )
			{
				packagingUnitUS = $.trim( $("name:exact('VerpackungseinheitUS')", this).siblings('value').text() );
				packagingUnitUS = (packagingUnitUS !== '') ? packagingUnitUS + ' / ' : '';
			}	

			var packagingUnit   = (packagingUnit1 + packagingUnit2 + packagingUnit3 + packagingUnitUS).replace(/ \/ $/, '');

			/*
			var unit            = $("name:exact('PreismodellflagArtikel')", this).siblings('value').text();
				unit            = (unit === 'j') ? ' m' : ((unit === '2') ? ' m²' : '');
			*/

			var number          = $("name:exact('Artikelnummer')", this).siblings('value').text();
			var isDiscontinued  = ( $("name:exact('Auslaufartikel')", this).siblings('value').text() === 'j' );
			showDiscontinuedFlag = showDiscontinuedFlag || isDiscontinued;
			
			var price           = $("name:exact('PreisEuro')", this).siblings('value').text();

			// Only articles with valid prices can be purchased (invalid: 0, 'Auf Anfrage', etc.)
			var intPrice        = parseInt(price.replace(/\D/, ''), 10);
			var isNotOrderable  = ( isNaN(intPrice) || intPrice === 0 );
			
			//var discountGroup   = $("name:exact('Rabattgruppe')", this).siblings('value').text();
			
			var weight = $("name:exact('" + (isProductGroupMetric ? 'Weight_g' : 'Weight_lb') + "')", this).siblings('value').text();
			
			var rowClass     = (i % 2 === 0) ? '' : 'even';
			rowClass        += ( $("name:exact('Leerzeile_folgt')", this).siblings('value').text() === 'true' ) ? ' blankline' : '';
			rowClass         = $.trim(rowClass);

			content += '<tr' + ( (rowClass === '') ? '' : ' class="' + rowClass + '"' ) + '>' +
				'<td class="article-number right first">' + number + ((isDiscontinued) ? ' *' : '') + '</td>' +
				'<td class="article-text">' + text + '</td>' +
				'<td class="article-unit right">' + packagingUnit /*+ unit*/ + '</td>' +
				'<td class="article-weight right">' + weight + '</td>';

			// Show oder options only if user is logged in	
/*
			if (registeredUser)
			{
				content += '<td class="article-price">' + price + ' ' + currency + '</td>' +
						   '<td class="article-discountGroup">' + discountGroup + '</td>' +
						   '<td class="article-amount"><input type="text" name="' + number.replace(/\s/g, '') + '" class="amount" size="5" maxlength="6" '+ ((isNotOrderable) ? 'disabled="disabled" ' : '') + '/></td>';
			}
*/			
			content += '</tr></tbody>';
		});
		if (showDiscontinuedFlag) { $('#model').append('<p>* '+ catalog_lang.discontinued + '</p>'); }
		return content;
	}

	
	/**
	 * Renders single model with aricle list
	 * 
	 * @see #getModellWithArtikel
	 * @see #getDeeplink
	 * @private
	 * @param {DOM} xml  XML document from web service
	 */
	function renderModelWithArticles(xml) {
		// Throw 404 error if no nodes exists
		if ($('return', xml).children().length === 0)
		{
			window.location.href = error404;
			return false;
		}
		
		// Hide other DIVs
		$('#productgroups').hide();
		$('#tabs').show().find('> div:visible:not(#model, #cmscontent)').hide();

		var groupId;
		
		var model = $('#model');
		// Remove last three columns if user is not logged in
/*		
		if (!registeredUser) {
			$('#model-articles thead th:gt(2), button', model).remove();
			$('#model-articles thead th:last-child', model).addClass('last');
		}
*/		

		// Render model data
		groupId              = $('return > id', xml).text();
		var modelImage       = $("return > properties > name:exact('Picture_Color')", xml).siblings('value').text().replace(/\.(eps|tif|tiff|gif)/g, '.jpg');
		if (modelImage === '') { modelImage = $("return > properties > name:exact('Abbildung')", xml).siblings('value').text(); }


		// Additional images for popup (data table, measures, design awards)
		var popupTitles = '';
		var popupUrls = '';
		var modelAdditionalImages = '';
		
		var modelImageTable  = $("return > properties > name:exact('Wertetabelle')", xml).siblings('value').text();
		if (modelImageTable !== '')
		{
			popupUrls   += modelImageUrl + modelImageTable + ',';
			popupTitles += catalog_lang.imageTable + ', ';
		}
		
		var modelImageMeasure = $("return > properties > name:exact('Masszeichnung')", xml).siblings('value').text();
		if (modelImageMeasure !== '')
		{
			popupUrls   += modelImageUrl + modelImageMeasure + ',';
			popupTitles += catalog_lang.imageMeasure + ', ';
		}
		
		var modelImageAwards = $("return > properties > name:exact('Awards')", xml).siblings('value').text();
		if (modelImageAwards !== '')
		{
			modelImageAwards = modelImageAwards.replace(/(,|^)[^.]+?(,|$)/g, '');                  // Remove non-filenames
			modelImageAwards = modelImageAwards.replace(/\.(eps|tif|tiff|gif)/g, '.jpg');                         // Replace image file extensions
			modelImageAwards = modelImageAwards.replace(/(^|,)/g, '$1' + modelImageUrl);           // Add path
			popupUrls   += modelImageAwards;
			popupTitles += catalog_lang.imageAwards;
		}

		// Trim last comma
		popupUrls   = popupUrls.replace(/,$/, '');
		popupTitles = popupTitles.replace(/, $/, '');
		
		if (popupUrls.length !== 0) { modelAdditionalImages = '<div><a href="javascript:void(0)" onclick="imagePopup(\'' + popupUrls + '\', \'\');">' + popupTitles + '</a></div>'; }
		
		
		// Get model information
		var modelName        = $("return > properties > name:exact('Modellbezeichnung')", xml).siblings('value').text();
		var modelDescription = $("return > properties > name:exact('Langtext'):not(:contains('Langtextnummer'))", xml).siblings('value').text();
		var modelNumberComplete      = $("return > properties > name:exact('ModellnummerKomplett')", xml).siblings('value').text();

		var discountGroup   = $("return > artikel:eq(0) > properties > name:exact('RabattgruppeUS')", xml).siblings('value').text();
		if (parseInt(discountGroup, 10) > 0 && parseInt(discountGroup, 10) < 10)
		{
			discountGroup = '<p><img src="' + discountImageUrl + 'discount_' + discountGroup + '.gif" width="71" height="21" alt="' + catalog_lang.discountGroup + ' ' + discountGroup + '" /></p>';
		} else {
			discountGroup = '';
		}

		var modelNotice      = $("return > properties > name:exact('Hinweistext1')", xml).siblings('value').text();
		if (modelNotice !== '') { modelNotice = '<p>' + modelNotice + '</p>'; }

		$('#model-image', model).html('<img src="' + modelImageUrl + modelImage + '" alt="' + modelName.replace(/[^\w\d]$/, '').replace(/<br(?: \/)?>/gi, ' ') + '" />' + modelAdditionalImages);
		$('#model-description', model).html('<h5>' + modelName + '</h5><p>' + modelDescription + '</p>' + discountGroup + modelNotice);
			

		// Render model number
		var modelType = $("return > properties > name:exact('Modelltyp')", xml).siblings('value').text();
		if ( modelType === 'Modellfamilienkopf' || modelType === 'Ditomodell' )
		{
			var modelFamily      = $("return > properties > name:exact('Ditotext')", xml).siblings('value').text().replace(/[^\w\d]$/, '');
			if (modelFamily !== '') { modelNumberComplete = modelFamily + '<br />' + catalog_lang.model + ' ' + modelNumberComplete; }
		} else {
			modelNumberComplete = catalog_lang.model + ' ' + modelNumberComplete;
		}
		$('> .model-number', model).html(modelNumberComplete);

		// Get Abmessungsflag and Ausfuehrungsflag for articles
		var modelAbmessungsflag   = ( $("return > properties > name:exact('Abmessungsflag')", xml).siblings('value').text() === 'j' ? true : false); 
		var modelAusfuehrungsflag = ( $("return > properties > name:exact('Ausfuehrungsflag')", xml).siblings('value').text() === 'j' ? true : false); 

		// Populate article table
		var modelTableBody = $('#model-articles', model);
		//modelTableBody.empty();
		
		// Render breadcrumb before articles: We need the isProductGroupMetric flag!
		getBreadcrumb(groupId);
		
		var content = renderArticles('return > artikel', xml, modelAbmessungsflag, modelAusfuehrungsflag);
		$(modelTableBody).html(content);
		

		// Populate dito models
		$('.clone').remove();

		var ditoModels = $('return > ditomodelle', xml);
		if (ditoModels.children().length !== 0)
		{
			var dito = $('div.dito');

/*			
			if (!registeredUser) {
				$('.dito-articles thead th:gt(2)', dito).remove();
				$('.dito-articles thead th:last-child', dito).addClass('last');
			}
*/			
			
			ditoModels.each(function(i) {
				var clone = dito.clone().removeClass('hidden').addClass('clone').insertBefore(dito);
				
				var ditoModelNumberComplete = $("name:exact('ModellnummerKomplett')", this).siblings('value').text();
				var ditoDescription = $("name:exact('Ditotext')", this).siblings('value').text().replace(/[^\w\d]$/, '');
				$('.model-number', clone).html('<br />' + ditoDescription + '<br />' + catalog_lang.model + ' ' + ditoModelNumberComplete);
				
				content = renderArticles('artikel', this, modelAbmessungsflag, modelAusfuehrungsflag);
				$('.dito-articles', clone).html(content);
			});
		}
		
		var modelOrderinfo   = $.trim($("return > properties > name:exact('Bestelldatentext')", xml).siblings('value').text().replace(/<[a-zA-Z\/][^>]*>/g, ' '));
		if (modelOrderinfo !== '') { $('th.article-text').html( catalog_lang.article.text + ' (' + modelOrderinfo + ')' ); }

		
		// if (registeredUser) { $('button span', model).text(catalog_lang.addToCart); }
		model.show();
	}


	/**
	 * Renders breadcrumb
	 * 
	 * @private
	 * @param {Object} nodeId  groupId of the current node (product fields, scopes, models, model with articles)
	 */	
	function getBreadcrumb(nodeId) {
		$.ajax({
			url: wsBaseUrl + 'getBreadcrumb',
			data: 'catalogId=' + countryCode + '&nodeId=' + nodeId,
			timeout: wsTimeout,
			success: function(xml)
			{
				var content = '';
				var wtBreadcrumb = '';

				var currentLevel = $('return', xml).length;
				if (currentLevel === 0) { return false; }
				var historyLevel = currentLevel - 2;       // Index starting at zero

				
				var node;
				var model;
				var productgroup;
					
				$('return', xml).each(function(i)
				{
					var name;
					
					// Hooray for data consitancy!
					switch (i)
					{
						case 0:
							var productField = $("*>name:exact('NameBereich')", this).siblings('value').text().replace(/<br(?: \/)?>/gi, '').replace(/\//, ' / ');
							wtBreadcrumb += '.' + productField;
							renderLeftNavigation(productField, currentLevel);
							break;
						case 1:
							if (node) {	lastNode = (window.location.hash === '' ? window.location.href : window.location.href.substring(0, window.location.href.indexOf('#') - 1)); }
							node = '#scope-' + $(this).children('id').text();
							name = $("name:exact('Produktgruppennummer')", this).siblings('value').text() + ' ' + $("name:exact('UntertitelProduktgruppe')", this).siblings('value').text();
							wtBreadcrumb += '.' + name;
							productgroup = $("name:exact('Produktgruppennummer')", this).siblings('value').text();
							$('#tabs h2').text(name);
							
							//Check for metric/imperial product group
							isProductGroupMetric = $("name:exact('Imperial_measure')", this).siblings('value').text() === 'j' ? false : true;
							
							// Highlight 3rd level navigation
							$('#sub-navigation')
								.find('li.selected').removeClass().end()
								.find("a:exact('" + name + "')").parent().addClass('selected');
							break;
						case 2:
							var scope = $("name:exact('NameVerwendungsbereich')", this).siblings('value').text();
							// Webservice includes scope on third level, although it's not needed. Needs to be removed from tracking.
							if (currentLevel > 3) {
								if (scope === 'nV') { scope = catalog_lang.misc; }
								wtBreadcrumb += '.' + scope;
							}
							break;
						case 3:
							lastNode = node;
							node = '#model-' + $(this).children('id').text();
							
							name = $("name:exact('NameUntergruppe')", this).siblings('value').text().replace(/<br(?: \/)?>/gi, ' ').replace(/,(\S)/g, ', $1').replace(/<[^>]+>/g, '');
							//$(this).children('name').text().replace(/<br(?: \/)?>/gi, ' ').replace(/,(\S)/g, ', $1');
							wtBreadcrumb += '.' + name;
							$('#productmodels').prepend('<h4>' + name + '</h4>');
							break;
						case 4:
							lastNode = node;
							node = '#modeldetail-' + $(this).children('id').text();
							// Remove last char if it's not letter or number, replace <br> with spaces
							name = $("name:exact('Modellbezeichnung')", this).siblings('value').text().replace(/[^\w\d]$/g, '').replace(/<br(?: \/)?>/gi, ' ').replace(/<[^>]+>/g, '');
							model = $("name:exact('ModellnummerKomplett')", this).siblings('value').text();
							wtBreadcrumb += '.modell_' + model;
							$('#model h4').html(name);
							break;
					}
					
					// Add breadcrumb link 
					if (name !== undefined) { content += '<div class="fLeft arrow"><a href="' + node + '">' + name + '</a></div>';}
				});
				
				var $breadcrumb = $('#BreadCrumb');
				$('> div:gt(' + (breadcrumbBaseLevel) + ')', $breadcrumb).remove();
				$($breadcrumb).append( content );
				
				// Set back link
/*
				TODO: Fix back link in IE8
		
				if (lastNode) { $('#backlink').attr('href', lastNode); }
				console.log(lastNode);
*/

				// Load CMS content on all levels >= 1 but don't load same product group twice
				//if (productgroup && lastProductgroup !== productgroup && window.cmsProductgroupPages && window.cmsProductgroupPages[productgroup])
				{
					if(lastProductgroup !== productgroup)
					{
						// IMPORTANT: Only load #Content DIV to avoid all script/css files being loaded as well
						$.ajax({
							dataFilter: function(rawData) { return rawData;	},
							dataType:   'html',
							url:        cmsProductgroupPages[productgroup] + '?mode=catalog',
							success: 	function(data, textStatus, jqXHR) 
							{
								var $cmsContent = $('#cmscontent>*', data);
								var $cmsSidebar = $('#cmssidebar>*', data);
		
								// Hide content tab if no nodes were loaded (e.g. error 404)
								if ($cmsContent.children().length === 0)
								{
									$("#cmstab, #cmscontent").hide();
								} else {
									// Show DIV (may be hidden if page was initally called as search result)
									var $cmsContentNode = $("#cmscontent");
									$cmsContentNode.html($cmsContent).show().prev('h3').show();
									if ( $('h3', $cmsContentNode).length > 1 )
									{
										$cmsContentNode.accordion();
									}
								}
								$("#cmssidebar").html($cmsSidebar);
		
								// Enable Content video module
								var contentFlashIDs = [];
								$('#cmscontent .flashElement a').each(function(){
									contentFlashIDs.push( "#" + $(this).attr('id').match(/videolink(\d+)_(a|b)l/)[0] );
								});
								
								if (contentFlashIDs.length > 0) {
									contentFlashIDs = contentFlashIDs.join(',');
									$( contentFlashIDs ).fancybox({'hideOnContentClick':false, 'frameWidth':480, 'frameHeight':386});
								}	
		
								// Enable Sidebar video module
								var sidebarFlashIDs = [];
								$('#cmssidebar .videolink').each(function() {
									var imageLinkId = $(this).attr('id');
									sidebarFlashIDs.push( imageLinkId );
									sidebarFlashIDs.push( imageLinkId.match(/([\w\d]+?)_img/)[1] );
								});
								if (sidebarFlashIDs.length > 0) {
									sidebarFlashIDs = sidebarFlashIDs.join(',');
									$( sidebarFlashIDs ).fancybox({'hideOnContentClick':false, 'frameWidth':480, 'frameHeight':386});
									if (isIE) { $('#cmssidebar').pngFix(); }
								}	
								
								lastProductgroup = productgroup;
								
								if (window.webtrekk && window.wt.sendinfo)
								{
									// Webtrekk: Sidebar links
									$('#cmssidebar a').click(function(e) {
										var text = $(this).text();
										var wtParameter, wtType;
										if (text === '') {
											if ($('img', this).attr('alt')) {
												wtParameter = [wt_be + '.link.side_bar.image.' + $.trim($(this).attr('alt')) + '.click', 'link'];
											} else {
												wtParameter = 'unknown_image';
											}
										} else {
											wtType = (($(this).attr('target') === '_blank' || $(this).attr('href').indexOf('mailto') !== -1) ? 'click' : 'link');
											wtParameter = [wt_be + '.link.side_bar.' + $.trim(text).replace(/\./g, "_") + '.click', wtType];
										}
										webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);
									});
								}
							}
						});
					}
				}

				
				if (window.webtrekk && window.wt.sendinfo)
				{
					// Webtrekk: Content links
					if (window.webtrekk && window.wt.sendinfo) { trackContentLinks(); }

					// Webtrekk: Breadcrumb
					$('a', $breadcrumb).click(function(){
						var wtParameter = [wt_be + '.link.breadcrumb.' + $.trim($(this).text()) + '.click', 'link'];
						webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);
					});

					// Webtrekk: Page Impression
					if (wt_be1) { wt_be = webtrekk.sanitizeHeadline( wt_be1 + wt_be2 + wtBreadcrumb ); }
					wt.sendinfo();
				}
				
			},
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getVerwendungsbereiche + catalog_lang.error.defaultMessage); }
		});
	}
	

	/**
	 * Web service: 'getBereiche'
	 * Retrives product fields and calls rendering function
	 * 
	 * @see #handleHashNavigation
	 * @private
	 */
	function getBereiche() {
		// Only call web service once
		if (!productFields.length)
		{
			$.ajax({
				url: wsBaseUrl + 'getBereiche',
				data: 'catalogId=' + countryCode,
				timeout: wsTimeout,
				success: function(xml)
				{
					// Populate productFields
					var length = $('return', xml).children().length;
					productFields.length = length;
					if (length === 0) { return false; }
					$('return', xml).each(function()
					{
						var productField = $("*>name:exact('NameBereich')", this).siblings('value').text().replace(/<br(?: \/)?>/gi, '').replace(/\//, ' / ');
						var productGroups = [];
						$('produktgruppen', this).each(function()
						{
							productGroups.push({
								id:     $(this).children('id').text(),
								number: $("name:exact('Produktgruppennummer')", this).siblings('value').text(),
								name:   $("name:exact('UntertitelProduktgruppe')", this).siblings('value').text()
							});
						});
						if (productGroups.length !== 0) { productFields[productField] = productGroups; }
						
					});
				},
				error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getBereiche + catalog_lang.error.defaultMessage); }
			});
		}

		// If not filled by now, an error occured
		if (productFields.length === 0) { return showErrorMessage(catalog_lang.error.getBereiche + catalog_lang.error.defaultMessage); }
	}

	
	/**
	 * Web service: 'getVerwendungsbereiche'
	 * Retrieve product scopes and renders them directly
	 *
	 * @see #handleHashNavigation
	 * @private
	 * @param        {String} produktGruppenId  Id of product group
	 */
	function getVerwendungsbereiche(produktGruppenId) {
		$.ajax({
			url: wsBaseUrl + 'getVerwendungsbereiche',
			data: 'catalogId=' + countryCode + '&parentId=' + produktGruppenId,
			timeout: wsTimeout,
			success: function(xml)
			{
				if ($('return', xml).children().length === 0) { return false; }
				
				// Hide other DIVs
				$('#productgroups').hide();
				$('#tabs').show().find('> div:visible:not(#productscopes, #cmscontent)').hide();
				
				var groupId;
				var scopeCount = 0;
				var content = '';

				$('return', xml).each(function()
				{
					groupId = $(this).children('id').text();
					
					var scope = $("name:exact('NameVerwendungsbereich')", this).siblings('value').text().replace(/<[^>]*>/g, ' ');
					if (scope === 'nV') { scope = catalog_lang.misc; }         // Set title to "Misc" for undefined scopes
					
					content += '<h3><span>' + scope + '</span></h3><ul class="sub">';
					$('untergruppen', this).each(function()
					{
						var subGroupsId   = $(this).children('id').text();
						var subGroupsName = $("name:exact('NameUntergruppe')", this).siblings('value').text().replace(/<[^>]*>/g, ' ');
					
						content += '<li><a href="#model-' + subGroupsId + '">' + subGroupsName + '</a></li>';						
					});
					content += '</ul>';
					scopeCount++;
				});
				
				$('#productscopes').html(content).show();
				
				if (scopeCount > 1)
				{
					// Collapse only if more than one scope
					$('#productscopes').accordion();
				} else {
					// If the only scope present is "Misc", remove scope's header
					var singleScope = $('#productscopes h3:eq(0)');
					if ( $('span', singleScope).text() === catalog_lang.misc ) { singleScope.remove(); }
				} 
				getBreadcrumb(groupId);
			},
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getVerwendungsbereiche + catalog_lang.error.defaultMessage); }
		});
	}

	
	/**
	 * Web service: 'getModelle'
	 * Retrieves product models and calls rendering function
	 *
	 * @see #handleHashNavigation
	 * @private
	 * @param        {String} produktUntergruppenId    Id of product sub group
	 */
	function getModelle(produktUntergruppenId) {
		$.ajax({
			url: wsBaseUrl + 'getModelle',
			data: 'catalogId=' + countryCode + '&parentId=' + produktUntergruppenId,
			timeout: wsTimeout,
			success: function(xml) { renderModels(xml, produktUntergruppenId); },
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getModelle + catalog_lang.error.defaultMessage); }
		});
	}

	
	/**
	 * Web service: 'getModellWithArtikel'
	 * Retrieves all articles for a model and calls rendering function
	 *
	 * @private
	 * @param        {String} produktModellId    Id of model
	 */
	function getModellWithArtikel(produktModellId) {
		$.ajax({
			url: wsBaseUrl + 'getModellWithArtikel',
			data: 'catalogId=' + countryCode + '&modellId=' + produktModellId,
			timeout: wsTimeout,
			success: function(xml) { renderModelWithArticles(xml); },
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getModellWithArtikel + catalog_lang.error.defaultMessage); }
		});
	}

	
	/**
	 * Web service: 'getModellWithArtikelId'
	 * Retrieves model with articles for a certain article number (deeplinking) and calls rendering function
	 *
	 * @see #handleHashNavigation
	 * @private
	 * @param        {String} searchString    Article number
	 */
	function getDeeplink(searchString) {
		$.ajax({
			url: wsBaseUrl + 'getModellByArtikelId',
			data: 'catalogId=' + countryCode + '&artikelId=' + searchString,
			timeout: wsTimeout,
			success: function(xml) { renderModelWithArticles(xml); },
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getModellWithArtikel + catalog_lang.error.defaultMessage);	}
		});
	}

	
	/**
	 * Web service: 'findModelleFullText'
	 * Full text search and calls rendering function
	 *
	 * @see #handleHashNavigation
	 * @private
	 * @param        {String}   searchString    Full text search string
	 * @param        {Integer}  offset          SQL query offset (Default: 0)
	 * @param        {Integer}  limit           SQL query offset (Default: 200)
	 * @param        {Function} callback        Optional callback function (e.g. for search results)
	 */
	function findModelleFullText(searchString, offset, limit, callback) {
		offset = offset || 0;
		limit  = limit || 200;
		$.ajax({
			url: wsBaseUrl + 'findModelleFullText',
			data: 'catalogId=' + countryCode + '&searchString=' + searchString + '&offset=' + offset + '&limit=' + limit,
			timeout: wsTimeout,
			success: function(xml)
			{
				$("#cmstab, #cmscontent, #cmssidebar").hide();

				// Check if search yielded any results
				if (renderModels(xml) === false)
				{
					$('#productmodels').html('<p>' + catalog_lang.error.noResults + '</p>').show();
					$('#tabs').find('h2').text(catalog_lang.searchResult).end().show();
				}
				
				if (typeof callback == 'function') { callback.call(); }
			},
			error: function(request, errorType, errorThrown) { showErrorMessage( (errorType === 'timeout') ? catalog_lang.error.timeout : catalog_lang.error.getModellWithArtikel + catalog_lang.error.defaultMessage); }
		});
	}

	/**
	 * Webtrekk: Content links
	 */
	function trackContentLinks() {
		$('#catalog a')
		//.unbind('click')
		.click(function(e){
			var text = ($(this).attr('title') !== '') ? $(this).attr('title') : $(this).text();
			var wtParameter, wtType;
			
			if (text === '') {
				var imageAltAttribute = $(this).children('img').attr('alt');
				if (imageAltAttribute !== "") {
					wtParameter = [wt_be + '.link.page_content.image.' + $.trim(imageAltAttribute) + '.click', 'link'];
				} else {
					wtParameter = [wt_be + '.link.page_content.unknown.click', 'link'];
				}
			} else {
				wtType = ( $(this).attr('target') === '_blank' || $(this).attr('href').indexOf('mailto') !== -1 ) ? 'click' : 'link';
				wtParameter = [wt_be + '.link.page_content.' + $.trim(text).replace(/\./g, "_") + '.click', wtType];
			}
			webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);          // Customized AJAX call
		});


	}
	// -- Public Functions ----------------------------------------------------
	/**
	 * Catalog navigation according to the URL's hash parameter
	 * 
	 * @param {String} hash
	 */
	function handleHashNavigation(hash)
	{
		// Hide shop module if session expired
/*		
		if (isRegisteredUser())
		{
			if (window.shop && window.shop.sidebar) { shop.sidebar.showBasketItemCount(); }
		} else {
			$('#shop-sidebar').remove();
		}	
*/		

		// getBereiche: no parameter
		var parameter;
		if (hash === '' || hash === undefined)
		{
			getBereiche();             // Load data
			renderProductFields();     // Render HTML output
			
			if (window.wt.sendinfo) {
				//wt.sendinfo();                                 // Track first PI on page load
				if (window.webtrekk) { trackContentLinks(); }  // Add click handler to content links
			}
			return true;
		}

		// Handle highlighting on first catalog level
		// e.g. catalog.html#1 -> highlight first item in left navigation
		parameter = hash.match(/^\d$/);
		if (parameter)
		{
			getBereiche();             // Load data
			renderProductFields();     // Render HTML output
			
			var $productGroups = $('#productgroups > h3');
			var $productGroup = $productGroups.filter(':eq(' + (parameter-1) + ')');
			var productGroup = $.trim($productGroup.text());
			renderLeftNavigation(productGroup, 0);
			
			if ($($productGroups).length > 1)
			{
				$productGroup.toggleClass('slideropen').next('ul').slideToggle('fast');
			}
			if (window.wt.sendinfo)
			{
				// Track sub-navigation click
				wtParameter = [wt_be + '.link.sub_navigation.' + productGroup + '.click', 'link'];
				webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);

				// Track Page Impression
				if (wt_be1) { wt_be = webtrekk.sanitizeHeadline( wt_be1 + wt_be2 + '.' + productGroup ); }
				wt.sendinfo();
				
				// Add click handler to content links
				if (window.webtrekk) { trackContentLinks(); }
			}

			return true;
		}

		// getVerwendungsbereiche: scope or productgroup parameter
		parameter = hash.match(/^scope-(group\d+?)$/);
		if (!parameter)	{ parameter = hash.toUpperCase().match(/^PG=([A-Z]\d{1,2})$/);  }  // Check for direct product group link
		if (parameter && parameter[1])
		{
			if (!productFields.length) { getBereiche(); }       // For subnavigation
			getVerwendungsbereiche(parameter[1]);
			return true;
		}
		
		// getModelle: model parameter
		parameter = hash.match(/^model-(group\d+?)$/);
		if (parameter && parameter[1])
		{
			if (!productFields.length) { getBereiche(); }       // For subnavigation
			getModelle(parameter[1]);
			return true;
		}

		// getModellWithArtikel: model detail parameter
		parameter = hash.match(/^modeldetail-(group\d+?)$/);
		if (parameter && parameter[1])
		{
			if (!productFields.length) { getBereiche(); }       // For subnavigation
			getModellWithArtikel(parameter[1]);
			return true;
		}
		
		// getDeeplink: catalog deeplink parameter (article or model number)
		parameter = hash.match(/^artnr=(.+?)$/);
		if (parameter && parameter[1])
		{
			if (!productFields.length) { getBereiche(); }       // For subnavigation
			getDeeplink(parameter[1]);
			return true;
		}
		
		// findModelleFullText: search
		parameter = hash.match(/^search=(.+?)$/);
		if (parameter && parameter[1])
		{
			findModelleFullText(parameter[1]);
			return true;
		}
		
	}


	/**
	 * Inits the catalog, load language file
	 * This function is called from the catalog or search page itself.
	 * 
	 * @param {Boolean} search    'true' if function is called from the search page
	 */
	function init(search) {
		var isCatalogPage = (search !== true) || false;
		// Load catalog language file dynamically
		$.ajax({
			async:      false,
			dataFilter: function(rawData) { return rawData;	},
			dataType:   'script',
			url:        (window.location.href.indexOf('development') !== -1 ? 'catalog/' : '/static/') + 'viega.catalog.' + countryCode + '.js',
			success: function() {

				// Define global Ajax status dialog
				$("#loading")
					.text(catalog_lang.loading)
					.fadeTo('fast', 0.7)
					.bind("ajaxSend", function() { $(this).vCenter().show(); })
					.bind("ajaxComplete", function() { $(this).hide(); });

				// Define global error dialog	
				$("#error")
					.fadeTo('fast', 0.7)
					.click(function() { $(this).hide(); });
				$("#error").hide();
				
				// Only init hash navigation for catalog, not for search results.
				if ( isCatalogPage ) {
					// Handle hash navigation: On page load
					$.history.init( handleHashNavigation );

					// Handle hash navigation: On click
					$('#top-navigation, #BreadCrumb, #sub-navigation, #catalog').click(function(e)
					{
						var link = ($(e.target).is('a')) ? $(e.target) : $(e.target).parents('a');
						if (link.prop("hash") != undefined) {
							$.history.load(link.prop("href").replace(/^.*#/, ''));
						}
					});
				}
			
			}, 
			error: function() { throw new Error("Catalog language file could not be loaded."); }
		});
	}

	// Reveal functions by assigning public pointers
	return {
		wsBaseUrl: wsBaseUrl,
		countryCode: countryCode,
		init: init,
		/* handleHashNavigation: handleHashNavigation, */
		renderLeftNavigation: renderLeftNavigation,
		findModelleFullText: findModelleFullText
	};
})();


/**
 * Accordion: Custom jQuery function
 *
 * @return       {jQuery}           parent element (for chaining)
 */
jQuery.fn.accordion = function() {
	var $parent = this;
	jQuery('> ul:visible', $parent).hide();  
	jQuery('> h3', $parent).click(function()
	{
		// Hide
		var $visible = $('h3.slideropen', $parent).removeClass('slideropen').next('ul:visible').slideUp('fast').end();
		if (window.webtrekk && window.wt.sendinfo && $visible.length !== 0)
		{
			// Webtrekk: Hide accordion
			wtParameter = [wt_be + '.link.page_content.' + $.trim($visible.text()) + '.hide', 'click'];
			webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);
		}
		
		// Show
		if ($visible.text() !== $(this).text())
		{
			$(this).toggleClass('slideropen').next('ul').slideToggle('fast');

			if (window.webtrekk && window.wt.sendinfo)
			{
				// Webtrekk: Show accordion
				wtParameter = [wt_be + '.link.page_content.' + $.trim($(this).text()) + '.show', 'click'];
				webtrekk.sendinfo(webtrekk.sanitizeHeadline(wtParameter[0]), wtParameter[1]);
			}
		}

		// Switch navigation on first catalog level	
		if ( $($parent).attr('id') === 'productgroups' ) { catalog.renderLeftNavigation($('span', this).text(), 0); }
	});
	return this;
};


/**
 * Displays popup window with image
 * TODO: Replace with FancyBox
 * 
 * @param {String} img   Image filename
 */
function imagePopup(img, additional) {
	var output = window.open('/static/catalogdetail.html?img=' + img + '&additional=' + additional, 'catalogdetail', 'location=0,toolbar=0,menubar=0,status=0,resizable=1,scrollbars=0,height=200,width=200');
	output.focus();
}


function html_entity_decode(str)
{
	return $('<div></div>').html(str).text();
}


