/**
* dv - Detailview-Objekt
*
* folgende Attribute und Methoden werden vom dv-Objekt genutzt:
* -dv.availability.fallback_AvailabilityCode;
* -dv.availability.fallback_AdditionalDeliveryCode;
*
* -dv.checkAvailabilityFromMMDB();
* -dv.changeContentOfServiceModule(targetNode);
* -dv.toggleDivSlider(elem);
*
* folgende Methoden globale JavaScript-Methoden werden aufgerufen:
* -prepareSettings();
* -setLandmark(params?);
* -reset_availability();
*/   


var dv = {
	/* angezeigter Text, solange der AJAX-Request der Livehost-Auskunft durchgeführt wird */     
	availabilityWaitText: "<b>Bitte warten ...</b>",
	
	/*GA-Tracking der Lieferbarkeit*/
	availability_ga_status: 'init',
	
	/* angezeigter Text, wenn der AJAX-Request nicht erfolgreich war */       
	availabilityErrorText: "<b>Abfrage der Verf&uuml;gbarkeit z.Zt. nicht m&ouml;glich</b>",
	
	/* Produktreferenz */         
	productRefID: 0,
	
	/* PromoArticleNo, benoetigt fuer Promotionerhalt */
	promoArticleNo: "",
	
	/**
	* Führt die Abfrage der MMDB-Lieferauskunft durch und zeigt sie in dem Objekt
	* dv.availabilityDisplay an (=HTML-Element).         
	*/         
	checkAvailabilityFromMMDB: function() {
		temp_av = availability;

		if (temp_av == null ) {
			temp_av = dv.availability.fallback_AvailabilityCode;
		}
		
		colorCode = av.getColorCodingMMDB(temp_av);
		av.setColorCodingIcon(temp_av);
		dv.availabilityDisplay.html(dv.availCodeToString(temp_av));
		dv.availabilityLink.html("");
		av.setColorCoding(colorCode);	  
	},
	
	/**
	* Führt die Abfrage der Livehost-Lieferauskunft durch und zeigt das Ergebnis
	* in dem Objekt dv.availabilityDisplay an (=HTML-Element).
	* Dabei wird vorbereitend für den AJAX-Request aus SKU die Artikelgröße 
	* geholt und die Artikelanzahl bestimmt. Vor abschicken des AJAX-Requests 
	* wird in dem Objekt dv.availabilityDisplay (=HTML-Element) der 
	* availabilityWaitText angezeigt.   
	*        
	*/  
	checkAvailability: function() {
		sku = $('#hiddenProductRef').val();
		
		if(sku) {
			var skuelems = sku.split("-");
			
			if ( dv.availability.unit == 'stk' ) {
				var quantity = 1;
				var size = skuelems[1];
			} else if ( dv.availability.unit == 'm' ) {
				var quantity = 100;
				var size = skuelems[1];
			} else {
				var quantity = 100;
				var size = 100;
			}
		
//			dv.viewAvailabilityToggle();
			dv.viewAvailabilityShowDisplay();
			dv.availabilityDisplay.html(dv.availabilityWaitText);
			
			$.ajax({
				type: "GET",
				url: dv.availability.url,
				data: {
					articelnr: skuelems[0],
					articelsize: size,
					articelquantity: quantity
				},
				success: function(responseData) {
					dv.availabilityDisplay.html(responseData);
				},
				error: function() {
					dv.availabilityDisplay.html(dv.availabilityErrorText);
				} 
			});
		} else {
			dv.availabilityDisplay.html(dv.availabilityErrorText);
		}
	},
	
	/**
	* Elemente, die zur Verfuegbarkeitsanzeige verwendet werden, werden in Variablen
	* des dv-Objektes gespeichert, um eine einzeige Referenz zu haben und dadurch eine
	* leichte Austauschbarkeit zu gewaehrleisten 
	*/
	init: function() {
		// Container fuer KAL-Verfuegbarkeit definieren
		dv.availabilityDisplay = $('.delivery');
		dv.availabilityLink = $('.deliveryDesc');
		dv.availabilityBackup = $('.deliveryDesc');
		productref = $('#hiddenProductRef').val();
		dv.setProductRefID(productref);
	},
	
	/**
	* Erster Versuch den KAL-Request durchzufuehren
	* bei erfolgreichem AJAX-Request wird die Funktion
	* dv.preCreateKAL ausgefuehrt
	* 
	* @param {Object} xml
	*/
	preLoadKAL: function(xml) {
		$.ajax({
			type: "POST",
			url: window.location.protocol+"//" + window.location.host + av.initial_article_selection.KALServlet,
			processData: false,
			dataType: "xml",
			timeout: 2000,
			contentType: "application/xml; charset=UTF-8",
			data: av.initial_article_selection.kal,
			success: dv.preCreateKAL,
			error: function(responseData) {
				dv.init();
				// Wenn KAL nicht verfuegbar war, MMDB-Lieferbarkeit anzeigen
				dv.checkAvailabilityFromMMDB();
			}
		});
	},
	
	/**
	* AJAX-Response wird ueber die Variable xml in der globalen Variable "kalresponse" gespeichert
	* in av.KALRequestStatus wird gespeichert, ob der KAL-Request erfolgreich war
	* die variable prodref wird mit der ersten lieferbaren product_ref befuellt, 
	* die von der Funktion "checkVariation" zurueck geliefert wird
	* das Variation-IFrame wird befuellt 
	* 
	* @param {Object} xml => enthaelt die AJAX Response
	*/
	preCreateKAL: function(xml) {
		kalResponse = xml;
		av.KALRequestStatus=true;
		var prodref = dv.checkVariation(av.initial_article_selection.product_ref);
		av.loadArticleVariationSuccess();
		
		if(av.initial_article_selection.product_ref != prodref) {
			$('#hiddenProductRef').val(prodref);
			updateProductVariations();
			updateMagicZoomImage();
		} else {
			// Warenkorb-Knopf aktivieren oder deaktivieren, abhaenigig von aktueller Verfuegbarkeit des Artikels
			toggleWkButton();
		}
		
		// Farbfleck initial auswaehlen
		selectColorFlag($('#color :selected').text());
		// Bild initial auswaehlen
		selectMorePicturesSelection($('#color :selected').text());
	},
	
	/**
	* liefert die als parameter reingegebene product_ref zuerueck, wenn diese
	* sofort lieferbar ist
	* sonst wird die naechst lieferbarste variation mit gleicher artikelnummer
	* sonst wird die naechst lieferbarste variation zurueck geliefert
	* 
	* TODO OPT: viel doppelter Code => vereinheitlichen und optimieren
	* 
	* @param {Object} product_ref => initiale product_ref der detailview 
	* (die mit der die Detailview aufgerufen wurde)
	*/	
	checkVariation: function(product_ref) {
		prodref=product_ref.split('-');
		articleno=prodref[0];
		availCode=av.getAvailabilityCode(product_ref);
		if(!availCode) {
			return product_ref;
		}
		avCode=availCode.split(';');
		// ist die initiale variation nicht lieferbar bzw. erst in einem gewissen zeitraum lieferbar, dann wird die naechste lieferbare variation rausgesucht
		// 0 = lieferbar, 1 = nicht lieferbar, 2=lieferbar in einem gewissen zeitraum
		if(avCode[0]=="1" || avCode[0]=="2") {
			var articles = kalResponse.getElementsByTagName( 'Article' );
			try {
				/*
				if(!av.initial_article_selection.selectFirstDeliverableProduct) {
					return product_ref;
				}
				*/

				// Hier wird nur der aktuelle Artikel durchlaufen und in diesem eine passende Auswahl gesucht
				for( i=0; i < articles.length; i++ ) {
					if ((articles[i].getElementsByTagName('ArticleAvailability')[0])) {
						CompleteCatalogItemNo=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('CompleteCatalogItemNo')[0].firstChild.data;              
						SizeAlphaText=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('SizeAlphaText')[0].firstChild.data;              
						DeliveryDesignation=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryDesignation')[0].firstChild.data;              
						DeliveryStatement=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryStatement')[0].firstChild.data;              
						
						// ist die aktuell durchlaufene variation lieferbar und entspricht die artikelnummer, der aus der aufgerufenen product_ref?
						if ((DeliveryDesignation == "0") && (CompleteCatalogItemNo == articleno)) {
							prodref_searchstring = CompleteCatalogItemNo+"-"+SizeAlphaText;
							
							for (articlenotmp in av.prodref_array) {
								if (articlenotmp == prodref_searchstring) {
									dv.ga_prodref = av.prodref_array[articlenotmp]+"@"+dv.articleDomain;
									return av.prodref_array[articlenotmp]+"@"+dv.articleDomain;
								}
							}
							dv.ga_prodref = product_ref;
							return product_ref;
						}
					}
				}
				
				// Hier werden alle Variationen durchsucht und der erste verfuegbare ausgewaehlt
				if(av.initial_article_selection.selectFirstDeliverableProduct) {
					for( i=0; i < articles.length; i++ ) {
						if ((articles[i].getElementsByTagName('ArticleAvailability')[0])) {
							CompleteCatalogItemNo=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('CompleteCatalogItemNo')[0].firstChild.data;              
							SizeAlphaText=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('SizeAlphaText')[0].firstChild.data;              
							DeliveryDesignation=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryDesignation')[0].firstChild.data;              
							DeliveryStatement=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryStatement')[0].firstChild.data;
							
							// ist die aktuell durchlaufene variation lieferbar - hier ist die ausgewaehlte artikelnummer obsolet
							if (DeliveryDesignation == "0") {
								prodref_searchstring = CompleteCatalogItemNo+"-"+SizeAlphaText;
								
								for (articlenotmp in av.prodref_array) {
									if (articlenotmp == prodref_searchstring) {
										dv.ga_prodref = av.prodref_array[articlenotmp]+"@"+dv.articleDomain;
										return av.prodref_array[articlenotmp]+"@"+dv.articleDomain;
									}
								}
								dv.ga_prodref = product_ref;
								return product_ref;
							}
						}
					}
				}
				
				// Default Fall
				dv.ga_prodref = product_ref;
				return product_ref;
			} catch (err) {
				// tritt ein Fehler auf wird die per Parameter in die Funktion gegebene product_ref wieder zurueckgeliefert
				return product_ref;
			}
		}
		
		// availCode = 0, d.h. initiale product_ref ist lieferbar
		dv.ga_prodref = product_ref;
		return product_ref;
	},
	
	/**
	* Fallback-Zustand wiederherstellen, d.h.
	* Fallback-Link fuer die Host-Lieferauskunft (checkAvailability) anzeigen
	* und KAL-Lieferbarkeitsanzeige ausblenden
	*/
	resetAvailability: function() {
		dv.availabilityLink.show();
		dv.availabilityDisplay.hide();
	},
	
	/**
	 * Zeigt Fallbacklink an. (Alias für resetAvailability)
	 */
	viewAvailabilityShowLink: function() {
		resetAvailability();
	},
	
	/**
	 * Zeigt Lieferbarkeit an.
	 */
	viewAvailabilityShowDisplay: function() {
		// dv.availabilityLink.hide();
		dv.availabilityDisplay.show();
	},
	
	/**
	* Notiz Redesign: Sollte nicht mehr verwendet werden! 
	* Besser viewAvailabilityShowDisplay() und viewAvailabilityShowLink() verwenden.
	* 
	* Wechselt zwischen Anzeige der KAL-Lieferbarkeit und 
	* Anzeige des Fallback-Lieferauskunft-Links.
	*/
	viewAvailabilityToggle: function() {
		dv.availabilityLink.toggle();
		dv.availabilityDisplay.toggle();  
	},
	
	/**
	* AvailabilityCode der MMDB zu einer Textauskunft umwandeln
	*/
	availCodeToString: function(availValue) {
		if(availValue) {
			var availCode = availValue.split(";");
			switch(availCode[0]) {
				case "300": return "leider ausverkauft"; break;
				case "310": return "Artikel lieferbar, l&auml;ngere Lieferzeit"; break;
				case "320": return "lieferbar"; break;
				case "330": return "Artikel lieferbar, l&auml;ngere Lieferzeit"; break;
				default: return dv.availabilityErrorText + " (MMDB)";
			}
		}
	},
	
	/**
	* KAL-AvailabilityCode zu einer Textauskunft umwandeln
	*/
	availCodeToStringKAL: function(DeliveryDesignation) {
		if(DeliveryDesignation) {
			switch(DeliveryDesignation) {
				case "0": return "lieferbar"; break;
				case "1": return "leider ausverkauft"; break;
				
				// #18915 KAL - Lieferauskünfte
				// return-Wert von "lieferbar" auf "" geändert
				// "lieferbar" wurde in DeliveryStatement ergänzt
				case "2": return ""; break;
				default: return dv.availabilityErrorText + " (KAL)";
			}
		}
	},
	
	/**
	* Ist der KAL-AvailablityCode = 2 gibt das DeliveryStatement noch eine
	* Zusatzinformation, wann der Artikel lieferbar ist
	* Diese Zusatzinformation besteht aus einer Zahl zwischen 1 und 87 und
	* wird mit dieser Funktion in eine Textauskunft umgewandelt
	* 
	* @param {Object} DeliveryStatement => wird je Artikel mit der KAL-Response mitgeliefert
	*/  
	availStateToStringKAL: function(DeliveryStatement) {
		var kal=new Array();
		kal[1]="lieferbar bis Anfang Januar";
		kal[2]="lieferbar bis Mitte Januar"; 
		kal[3]="lieferbar bis Ende Januar";  
		kal[4]="lieferbar bis Januar";       
		kal[5]="lieferbar im Januar";
		kal[6]="lieferbar bis Anfang Februar";       
		kal[7]="lieferbar bis Mitte Februar";
		kal[8]="lieferbar bis Ende Februar"; 
		kal[9]="lieferbar bis Februar";      
		kal[10]="lieferbar im Februar";       
		kal[11]="lieferbar bis Anfang M&auml;rz";  
		kal[12]="lieferbar bis Mitte M&auml;rz";   
		kal[13]="lieferbar bis Ende M&auml;rz";    
		kal[14]="lieferbar bis M&auml;rz"; 
		kal[15]="lieferbar im M&auml;rz";  
		kal[16]="lieferbar bis Anfang April"; 
		kal[17]="lieferbar bis Mitte April";  
		kal[18]="lieferbar bis Ende April";   
		kal[19]="lieferbar bis April";
		kal[20]="lieferbar im April"; 
		kal[21]="lieferbar bis Anfang Mai";   
		kal[22]="lieferbar bis Mitte Mai";    
		kal[23]="lieferbar bis Ende Mai";     
		kal[24]="lieferbar bis Mai";  
		kal[25]="lieferbar im Mai";   
		kal[26]="lieferbar bis Anfang Juni";  
		kal[27]="lieferbar bis Mitte Juni";   
		kal[28]="lieferbar bis Ende Juni";    
		kal[29]="lieferbar bis Juni"; 
		kal[30]="lieferbar im Juni";  
		kal[31]="lieferbar bis Anfang Juli";  
		kal[32]="lieferbar bis Mitte  Juli";  
		kal[33]="lieferbar bis Ende Juli";    
		kal[34]="lieferbar bis Juli"; 
		kal[35]="lieferbar im Juli";  
		kal[36]="lieferbar bis Anfang August";
		kal[37]="lieferbar bis Mitte August"; 
		kal[38]="lieferbar bis Ende August";  
		kal[39]="lieferbar bis August";       
		kal[40]="lieferbar im August";
		kal[41]="lieferbar bis Anfang September";     
		kal[42]="lieferbar bis Mitte September";      
		kal[43]="lieferbar bis Ende September";       
		kal[44]="lieferbar bis September";    
		kal[45]="lieferbar im September";     
		kal[46]="lieferbar bis Anfang Oktober";       
		kal[47]="lieferbar bis Mitte Oktober";
		kal[48]="lieferbar bis Ende Oktober"; 
		kal[49]="lieferbar bis Oktober";      
		kal[50]="lieferbar im Oktober";       
		kal[51]="lieferbar bis Anfang November";      
		kal[52]="lieferbar bis Mitte November";       
		kal[53]="lieferbar bis Ende  November";       
		kal[54]="lieferbar bis November";     
		kal[55]="lieferbar im November";      
		kal[56]="lieferbar bis Anfang Dezember";      
		kal[57]="lieferbar bis Mitte Dezember";       
		kal[58]="lieferbar bis Ende Dezember";
		kal[59]="lieferbar bis Dezember";     
		kal[60]="lieferbar im Dezember";      
		kal[61]="lieferbar bis Weihnachten";  
		kal[62]="lieferbar bis Ostern";       
		kal[71]="lieferbar innerhalb 1 Woche";   
		kal[72]="lieferbar innerhalb 2 Wochen";   
		kal[73]="lieferbar innerhalb 3 Wochen";   
		kal[74]="lieferbar innerhalb 4 Wochen";   
		kal[75]="lieferbar innerhalb 5 Wochen";  
		kal[76]="lieferbar innerhalb 6 Wochen";  
		kal[77]="lieferbar innerhalb 7 Wochen"; 
		kal[78]="lieferbar innerhalb 8 Wochen";   
		kal[79]="lieferbar innerhalb 9 Wochen";   
		kal[80]="lieferbar innerhalb 10 Wochen";   
		kal[81]="lieferbar innerhalb 11 Wochen";    
		kal[82]="lieferbar innerhalb 12 Wochen";  
		kal[83]="lieferbar innerhalb 13 Wochen";     
		kal[84]="lieferbar innerhalb 14 Wochen";     
		kal[85]="lieferbar innerhalb 15 Wochen";     
		kal[86]="lieferbar innerhalb 16 Wochen";  
		
	    // ohne "lieferbar "?
		kal[87]="zur Nachlieferung vorgesehen";
		
		// #18915 KAL - Lieferauskünfte
		// Neuer Zustand
		kal[103]="zurzeit vergriffen";
		
		return(kal[DeliveryStatement]);	  
	},
	
	/**
	* lokale Speicherung der product_ref im dv-Objekt
	* 
	* @param {Object} product_ref
	*/
	setProductRefID: function(product_ref) {
		dv.productRefID = product_ref;
	},
	
	/**
	* getter-Funktion fuer die lokale gespeicherte product_ref
	*/
	getProductRefID: function() {
		return dv.productRefID;
	}
// dv Objekt wird hier geschlossen
}
	
/**
* av - Article-Variation-Object
*
* folgende Attribute und Methoden werden vom dv-Objekt genutzt:
* -dv.availability.fallback_AvailabilityCode;
* -dv.availability.fallback_AdditionalDeliveryCode;
*
* -dv.checkAvailabilityFromMMDB();
* -dv.changeContentOfServiceModule(targetNode);
* -dv.toggleDivSlider(elem);
*
* folgende Methoden globale JavaScript-Methoden werden aufgerufen:
* -prepareSettings();
* -setLandmark(params?);
* -reset_availability();
*/

/**
* Changelog Schwab
* 
* -added method "loadArticleVariationFrame" for loading variations in the 
*  iframe
* -added av-color-properties 
* -added counter-property for different texts if the article is "lieferbar"
* -added method "loadArticleVariationSuccess" to be callable from other
*  methods
* -added method "loadArticleVariationFrame" for loading the article-variations            
*  in an iframe
* -added method "show24hServicePopup" for opening the 24h-service-popup
* 
*    
* -changed method getColorCoding(availStr) for matching the deliverycodes 
*  of dv.availCodeToString     
* -changed method "handleAvailabilityCode"; removed parameter "product_ref";
*  product_ref is now received with the method dv.getProductRefID()
* -changed method "displayDeliveryStatus" to show all KAL-statuses
* -changed method "setColorCoding" to work properly with the iframe
* -changed getColorCoding-methods because of different availabilitycodes in
*  comparison to otto.de
*  
* there are some unused methods which can be important if the iframe will be
* replaced by an ajax-request
* 
* currently unused methods:
* -loadArticleVartion
* -loadArticleVartionKAL
* -show24hServiceReiter
* -resizeSelectBoxes
* -debounceButtons
* -enableButtons
*               
*/   
	
var av = {
	// Farbeinstellungen fuer die Lieferbarkeitszustände 
	colorBuyable: "#00AA00", //gruen, lieferbar
	colorBuyableSoon: "#FF9900", //gelb, lieferbar in xx
	colorSold: "#B90000", //rot, ausverkauft

	// Zeitinformation bei Status lieferbar an/aus
	// Bsp.: bei Bestellung in den nächsten xx Std. xx Min. ...    
	counter: true,       

	// dient zur Speicherung der Anzahl der Request-Retries
	KALRetry: 0,

	// speichert, ob der KAL-Request erfolgreich war
	KALRequestStatus: false,
	
	// Hilfsparameter um Warenkorb-Knopf zu deaktivieren, wenn Artikel nicht lieferbar ist
	KALProductUnavailable: false,
	
		
	/**
	* Schickt einen AJAX-Request an eine in diesem Objekt gespeicherte URL und stellt
	* die empfangenen Daten direkt im HTML-Tag mit der id="dvArticleSelection" dar.
	* Die Response beinhaltet, die Artikel-Variationsdropdowns mit dem Event
	* onChange="loadArticleVariation".
	* Dabei werden vor dem Request bestimmte Links(class="toDebounce") auf der Seite
	* deaktiviert und nach erfolgreichem Request wieder aktiviert. Zusätzlich wird die
	* Größe von bestimmten Select-Boxen(class="articleSelect") angepasst und die
	* Preisanzeige aktualisiert.
	* 
	* TODO OPT: Ableich mit Funktion loadArticleVariationKAL und Vereinheitlichung
	* 		   lediglich success-Funktion ist eine andere
	*
	* @param product_ref - Produktreferenz-Nummer 
	*                      (bestehend aus einer Kombination aus Zahlen und 
	*                      Buchstaben)
	*/
	loadArticleVariation: function(product_ref) {
		ajax_url = av.initial_article_selection.url;
		$.ajax({
			type: "GET",
			url: ajax_url,
			data:  "ProductRef=" + product_ref,
			success: function(responseData){
				$("#dvArticleSelection").html(responseData);
				dv.variationFrame.prepareSettings();
		   	}
		});
	},
	
	
	/**
	* Wenn ein HTML-Element mit der id="VariationsPulldown" vorhanden ist (in
	* diesem Fall sollte es ein IFrame sein), wird die product_ref im dv-Objekt
	* und im av.initial_article_selection-Objekt gesetzt.
	* Danach wird das src-Attribut des HTML-Tags mit der id="VariationsPulldown"
	* gesetzt, wodurch die Artikel-Variationen in das IFrame geladen werden.
	* 
	* @param product_ref - Produktreferenz-Nummer 
	*                     (bestehend aus einer Kombination aus Zahlen und 
	*                      Buchstaben) 
	*/
	loadArticleVariationFrame: function(product_ref) {
		loadArticleVariationFrame(product_ref,null);
	},
	
	
	/**
	* TODO OPT: gleichnamige Funktion ueber diesem Kommentar entfernen,
	* da die zuletzt definierte Funktion genutzt wird 
	* 
	* @param {Object} product_ref
	* @param {Object} parameter
	*//*TODO BREAK*/
	loadArticleVariationFrame: function(product_ref, parameter) {
		// TODO: zuverlaessige Abfrage nutzen: $('#VariationsPulldown').size()	
		if($('#VariationsPulldown')) {
			dv.setProductRefID(product_ref);
			
			if (!parameter) {
				parameter="";
			}
			//av.initial_article_selection.product_ref = product_ref;
			//$('#VariationsPulldown').attr('src',av.initial_article_selection.url + product_ref + parameter);
		} 	  
	},
	
	
	/**
	* Schickt einen AJAX-Request an eine in diesem Objekt gespeicherte URL und stellt
	* die empfangenen Daten direkt im HTML-Tag mit der id="dvArticleSelection" dar.
	* Die Response beinhaltet, die Artikel-Variationsdropdowns mit dem Event
	* onChange="loadArticleVariationKAL".
	* Dabei werden vor dem Request bestimmte Links(class="toDebounce") auf der Seite deaktiviert und nach
	* erfolgreichem Request wieder aktiviert. Zusätzlich wird die Größe von bestimmten
	* Select-Boxen(class="articleSelect") angepasst und die Preisanzeige aktualisiert.
	*
	* Nun wird geprüft, ob KAL genutzt werden soll (Variable bei av.initial_article_selection).
	*   Sind bereits 2 KAL-Requests durchgeführt worden wird eine Fallback-Funktion aufgerufen und
	*   die Lieferauskunft auf andere Datenbasis ausgegeben.
	*   Ansonsten wird überprüft, ob der Request-Status (KALRequestStatus) false ist.
	*     Ist dieser false wird der KAL-Request ausgeführt und gezählt (KALRetry + 1)
	*     Ist dieser true wird die Abarbeitung des Lieferbarkeit-Codes begonnen (handleAvailabilityCode)
	* Soll KAL nicht genutzt werden wird auf die MMDB-Lieferauskunft geswitcht (dv.checkAvailabilityFromMMDB)
	*
	* @param product_ref - Produktreferenz-Nummer (bestehend aus einer Kombination aus Zahlen und Buchstaben)
	*
	*
	*/
	loadArticleVariationKAL: function(product_ref) {
		ajax_url = av.initial_article_selection.url;
		$.ajax({
			type: "GET",
			url: ajax_url,
			data:  "ProductRef=" + product_ref,
			success: av.loadArticleVariationSuccess
		});
	},
	
	/**
	* ajax-success-Funktion der Funktion loadArticleVariationKAL
	* wenn der Servlet-Call erfolgreich war wird in dieser Funktion die Antwort ausgewert und weitergehend verarbeitet
	* 
	* @param {Object} responseData XML Servlet response
	*/
	loadArticleVariationSuccess: function(responseData){
		var product_ref = dv.getProductRefID();
		// wird gesetzt in der inc_dv_js.isml (dynamisch (serverseitig) gefuellte JavaScript-Variablen)
		if (av.initial_article_selection.usekal) {
		   // wenn drei KAL-Verarbeitungsversuche fehlgeschlagen sind, zeige Fallback-Link an
		   // TODO OPT: dritter Aufruf der Funktion av.loadKALResponse(ajax-Request) wuerde dennoch in den Fallback-Fall
		   //			laufen, da KALRetry = 3 und Abfrage av.KALRetry > 2 greifen wuerde
			if (av.KALRetry > 2) {
				// Wenn KAL-Verfuegbarkeit nicht vorhanden, dann Backup aus MMDB anzeigen
				av.displayDeliveryStatusFallback();
			} else {
				//wenn der call nicht erfolgreich
				if (!av.KALRequestStatus) {
					av.loadKALResponse();
					av.KALRetry+=1;
				} else {
					av.handleAvailabilityCode();
				}
			}
		} else {
			dv.checkAvailabilityFromMMDB();
		}
	},
	
	/**
	* Führt den eigentlich KAL-AJAX-Request durch. Ist der Request erfolgreich (success),
	* wird die Verarbeitung aufgerufen.
	* Bei einem Fehler wird eine Funktion für die Fehlerbehandlung aufgerufen.
	* 
	* TODO OPT: abgleich mit preLoadKAL-Funktion ggf. Vereinheitlichung
	* 
	*/
	loadKALResponse: function() {
		$.ajax({
			type: "POST",
			url: window.location.protocol+"//" + window.location.host + av.initial_article_selection.KALServlet,
			processData: false,
			dataType: "xml",
			timeout: 2000,
			contentType: "application/xml; charset=UTF-8",
			data: av.initial_article_selection.kal,
			success: av.createKAL,
			error: av.noKALResponse
		});
	},
	
	/**
	* Setzt den Request-Status auf erfolgreich (KALRequestStatus=true) und ruft die Abarbeitung
	* des Lieferbarkeit-Codes auf.
	* 
	* TODO OPT: ggf. Abgleich mit Funktion dv.preCreateKAL
	* 			 
	* @param xml - responseData des AJAX-Requests im XML-Format
	*/
	createKAL: function(xml) {
		kalResponse = xml;
		av.KALRequestStatus=true;
		av.handleAvailabilityCode();
	},
	
	/**
	* Ruft bei nicht gelungenem KAL-Request der Funktion loadKALResponse eine Fallback-Funktion
	* auf.
	* ajax-error-Funktion wenn der KAL-AJAX-Request fehlgeschlagen ist.
	* 
	*/
	noKALResponse: function() {
		av.displayDeliveryStatusFallback();
	},
	
	/**
	* Unterteilt die Produktreferenz-Nummer in Artikel-Nummer und Größe.
	* Danach wird die kalresponse(gefüllt in Funktion createKAL) abgearbeitet und
	* in folgende Inforamationen unterteilt:
	*   CompleteCatalogItemNo
	*   SizeAlphaText
	*   DeliveryDesignation
	*   DeliveryStatement
	*   
	*   Beispiel der KALResponse:
	*   	 
	*   <Articles>
	*     <Article>
	*       <ArticleAvailability>
	*         <ArticleInformation>
	*            <CompleteCatalogItemNo>357457Y</CompleteCatalogItemNo>
	*            <SizeAlphaText>32</SizeAlphaText>
	*            <Std_Promotion>Y</Std_Promotion>
	*            <CustomerCompanyID>0</CustomerCompanyID>
	*         </ArticleInformation>
	*         <Availability>
	*            <DeliveryDesignation>0</DeliveryDesignation>
	*            <DeliveryStatement>0</DeliveryStatement>
	*            <Stock>1</Stock>
	*         </Availability>
	*       </ArticleAvailability>
	*     </Article>
	*     <...>
	*   </Articles>   
	*         
	*	TODO OPT: Funktion checkVariation iteriert auch ueber das Article-Element aus der KAL-Response
				  ggf. Vereinheitlichung der for-Schleife  
	* 
	* @param product_ref - Produktreferenz-Nummer
	*
	* @returns false, wenn die Verarbeitung der kalresponse fehltschlägt
	* @returns DeliveryDesignation + DeliveryStatement wenn, die Verarbeitung der kalresponse korrekt durchläuft
	*/
	getAvailabilityCode: function(product_ref) {
		prodref=product_ref.split('-');
		articleno=prodref[0];
		size=prodref[1];
		var articles = kalResponse.getElementsByTagName( 'Article' );
		
		try {
			for( i=0; i < articles.length; i++ ) {
				if (articles[i].getElementsByTagName('ArticleAvailability')[0]) {
					//<CompleteCatalogItemNo>408515Y</CompleteCatalogItemNo>
					CompleteCatalogItemNo=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('CompleteCatalogItemNo')[0].firstChild.data;
		
					//<SizeAlphaText>32</SizeAlphaText>
					SizeAlphaText=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('ArticleInformation')[0].getElementsByTagName('SizeAlphaText')[0].firstChild.data;
		
					//<DeliveryDesignation>0</DeliveryDesignation>
					DeliveryDesignation=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryDesignation')[0].firstChild.data;
					
					//<DeliveryStatement>0</DeliveryStatement>              	
					DeliveryStatement=articles[i].getElementsByTagName('ArticleAvailability')[0].getElementsByTagName('Availability')[0].getElementsByTagName('DeliveryStatement')[0].firstChild.data;
					if (SizeAlphaText == size && CompleteCatalogItemNo == articleno) {
						return DeliveryDesignation+";"+DeliveryStatement;
					}
				}
			}
		} catch (err) {
			return false;
		}
		
		return false;
	},
	
	/**
	* Prüft, ob die kalresponse korrekt verarbeitet wurde.
	*
	* Ist sie nicht korrekt verarbeitet worden, wird eine Fallback-Funktion zum Anzeigen
	* der Lieferauskunft genutzt.
	*
	* Ist sie korrekt verarbeitet worden, wird Funktion zur Anzeige der KAL-Lieferauskunft
	* aufgerufen.
	*
	* @param product_ref - Produktreferenz-Nummer
	*/
	handleAvailabilityCode: function() {
		var product_ref = dv.getProductRefID();		
		var availabilityCode=av.getAvailabilityCode(product_ref);
		if (!availabilityCode)  {
			av.displayDeliveryStatusFallback();
		} else {
			av.displayDeliveryStatus(availabilityCode,product_ref);
		}
	},
	
	/**
	* Der im Parameter status übergebener Wert wird zuerst in eine Bezeichnung und einen Messagecode
	* unterteilt. Danach wird der Fallback-Liefercode(MMDB) in einer zusätzlichen Variablen gespeichert.
	*
	* Wenn die Bezeichnung den Wert 0 beinhaltet, wird die eine Variable mit der Nachricht "lieferbar"
	* erzeugt. Weiterhin wird unter Prüfung der initialen Artikel-Werte der Eilservice überprüft und ggf.
	* die Funktion zur Vorbereitung der Eilservice-Anzeige aufgerufen.
	* Zusätzlich wird eine Farbe gesetzt, sowie ein Landmark geschrieben.
	*
	* Enthält die Bezeichnung nicht den Wert 0, wird der Fallback-Liefercode überprüft und ggf. eine Variable
	* mit einer anderen Lieferbarkeits-Nachricht gefüllt. Zusätzlich wird auch hier ein Farbcode gesetzt.
	*
	* Ansonsten wird auch der Fallback-Liefercode genutzt, um eine Lieferbarkeits-Nachricht in einer Variablen
	* zu speichern, eine Farbcode sowie ein Landmark gesetzt.
	*
	* Zum Schluss wird der Colorcode dieses Objektes gesetzt.
	*
	* @param status - semikolon-separierter String
	* @param product_ref - Produktreferenz-Nummer
	*/
	displayDeliveryStatus: function(status,product_ref) {
		var stat=status.split(';');
		var ddesignation = stat[0];
		var dstatement = stat[1];
		var hint='';
		var msg='';
		
		// TODO OPT: ist der Artikel lieferbar, haette ddesignation den Wert "0", somit wuerde diese if-Abfrage diesen Fall ausschliessen
		// urspruengliche Intetion war abzufragen, ob ddesignation definiert ist
		if (ddesignation) {
			msg = dv.availCodeToStringKAL(ddesignation);
		  
			// TODO OPT: dieser Fall kann nicht eintreten (doch... kann er und tut er)
			if (av.initial_article_selection.eilservice && ddesignation == 0) {
				hint=av.getHint24h();
			}
		  
			if ((dstatement) && (dstatement != 0)) {
				msg+= dv.availStateToStringKAL(dstatement);
			}
			
			//GA-Tracking der Lieferbarkeit
			if (dv.availability_ga_status == 'init' && dv.ga_prodref == product_ref){
				dv.availability_ga_status = 'user';
				dv.ga_prodref = product_ref;
				try {
					$.gaTracker.trackEvent('DV_Lieferbarkeit', 'init', msg);
				} catch(err) {}
			}else if (dv.availability_ga_status == 'user' && dv.ga_prodref != product_ref){
				dv.ga_prodref = product_ref;
				try {
					$.gaTracker.trackEvent('DV_Lieferbarkeit', 'user', msg);
				} catch(err) {}
			}
			if (msg == 'leider ausverkauft'){
				try {
					$.gaTracker.trackEvent('DV_Lieferbarkeit', 'ausverkaufte Art.', product_ref.substring(0,product_ref.substring(product_ref.indexOf("-")+1,product_ref.length).indexOf("-") + product_ref.indexOf("-")+1));
				} catch(err) {}
			}
			
			colorCode =  av.getColorCoding(ddesignation);
			av.setColorCodingIcon(ddesignation);
	
			// Tracking
			setLandmark("AutoPage", "&pc=availability_kal&lieferstatus=" + msg + "&liefercode="+status+"&productref="+product_ref);
		}
		
		//	dv.viewAvailabilityToggle();
		dv.viewAvailabilityShowDisplay();
		$('.delivery').html(msg);
		$('.deliveryDesc').html(hint);
		// dv.availabilityDisplay.html('<span class="stocktext">'+msg+'</span>'+hint);
		av.setColorCoding(colorCode);
	},
	
	/**
	* Fallback-Funktion, wenn KAL-Request fehlschlägt, Funktion aufrufen,
	* um Lieferbarkeitsanzeigen zurückzusetzen
	*/
	displayDeliveryStatusFallback: function() {
		dv.availabilityLink.html(dv.availabilityBackup.html());
		dv.availabilityLink.addClass('pfeil');
		av.trackKALError();
		dv.checkAvailabilityFromMMDB();
	},
	
	/**
	* Setzt die Schriftfarbe für <b>- und <span>-Tags im HTML-Tag mit id="checkAvailability"
	*
	* @param color - CSS-Farbangabe
	*/
	setColorCoding: function(col) {
		dv.availabilityDisplay.find('b').css({ color: col});
		dv.availabilityDisplay.find('span').css({ color: col});
	},
	
	/**
	* Gibt eine Farbe auf Basis des KAL-Lieferbarkeitsstatuses zurück
	*
	* @param DeliveryDesignation - KAL-Lieferbarkeitsstatus (0,1,2)
	*
	* @returns String, hexadezimale Farbe
	* 
	* @see dv.availCodeToString   	 
	*/
	getColorCoding: function(DeliveryDesignation) {
		var params = DeliveryDesignation.split(";");
		switch(params[0]) {
			case "0": return av.colorBuyable; break;
			case "1": return av.colorSold; break;
			case "2": return av.colorBuyableSoon; break;
			default: return av.colorSold;
		}		
	},
	
	/**
	 * Erweiterung für das Redesign (Redesign beinhaltet zusätzliche Icons).
	 */
	setColorCodingIcon: function(DeliveryDesignation) {
		var params = DeliveryDesignation.split(";");
		switch(params[0]) {
			case "0":
				$('.delivery ').removeClass('orange');
				$('.delivery ').removeClass('red');
				$('.delivery ').addClass('green');	// lieferbar
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			case "1": 
				$('.delivery ').removeClass('green');
				$('.delivery ').removeClass('orange');
				$('.delivery ').addClass('red');	// ausverkauft
				// WK-Button AUSGRAUEN
				av.KALProductUnavailable = true;
				break;
			case "2": 
				$('.delivery ').removeClass('green');
				$('.delivery ').removeClass('red');
				$('.delivery ').addClass('orange');	// demnaechst lieferbar
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			// zusaetzliche Faelle fuer MMDB-Verfuegbarkeit, wenn KAL nicht verfuegbar ist				
			case "300":
				$('.delivery ').removeClass('green');
				$('.delivery ').removeClass('orange');
				$('.delivery ').addClass('red');	// ausverkauft
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			case "310":
				$('.delivery ').removeClass('green');
				$('.delivery ').removeClass('red');
				$('.delivery ').addClass('orange');	// demnaechst lieferbar
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			case "320":
				$('.delivery ').removeClass('orange');
				$('.delivery ').removeClass('red');
				$('.delivery ').addClass('green');	// lieferbar
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			case "330":
				$('.delivery ').removeClass('green');
				$('.delivery ').removeClass('red');
				$('.delivery ').addClass('orange');	// demnaechst lieferbar
				// WK-Button anzeigen
				av.KALProductUnavailable = false;
				break;
			default: break;
		}
	},
	
	/**
	* Gibt eine Farbe auf Basis des MMDB-Lieferbarkeitcodes zurück
	*
	* @param availStr - Lieferbarkeitscode
	*
	* @returns String, hexadezimale Farbe
	*/
	getColorCodingMMDB: function(availStr) {
		var params = availStr.split(";");
		
		switch(params[0]) {
			case "300": return av.colorSold; break;
			case "310": return av.colorBuyableSoon; break;
			case "320": return av.colorBuyable; break;
			case "330": return av.colorBuyableSoon; break;
			default: return av.colorBuyableSoon;
		}		
	},
	
	/**
	* Gibt eine Farbe auf Basis des MMDB-Lieferbarkeitcodes zurück
	*
	* @param availStr - Lieferbarkeitscode
	* 
	* TODO OPT: Diese Funktion kann entfernt werden, Pruefung steht aus
	*
	* @returns String, hexadezimale Farbe
	*/
	show24hServiceReiter: function(elem) {
		var targetNode = $(elem.hash);
		if (targetNode.is("*")) {
			window.scrollTo( 0, targetNode.realOffsetTop())
			targetNode.click();
			targetNode.id = targetNode[0].id
			dv.changeContentOfServiceModule(targetNode);
			elem = $("#service24h");
			if ( elem.size() > 0 ) {
				elem = elem.parent();
				if ( !elem.hasClass("sliderOpen") ) {
					dv.toggleDivSlider(elem);
				}
			}
		}
		return false;
	},
	
	/**
	* Ermittelt clientseitig das aktuelle Datum und verrechnet es mit der Serverzeit.
	* Danach wird eine gewisse Zeit addiert und überprüft, in welchem Tag wir uns nun
	* befinden. Sind wir in einem Samstag oder Sonntag angelangt wird weitere Zeit addiert.
	* Danach wird der Wochentag als Zahl in einen String umgewandelt.
	* ...
	* 
	* serverTime => definiert inc_dv_js.isml per module, dass Serverzeit zurueckgibt,
	* 	
	* TODO: richtige Serverzeit sollte verwendet werden
	*
	*
	* @returns String mit der Eilservice Nachricht
	*/
	getHint24h: function() {
		var d = new Date();
		var ld = new Date();
		var highnoon = new Date();
		var ordertime = new Date();
	
		/**
		*  TODO OPT: Zeitberechnung der "actTime" ist sinnlos
		*  serverTime = clientTime => inc_dv_js.isml
		*/
		actTime = serverTime+(d.getTime()-clientTime);
		d.setTime(actTime);
		highnoon.setTime(actTime);
		ld.setTime(actTime+129720000);
		
		// aktuellen Tag in lday speichern
		lday = ld.getDay();
		weekend=false;
		
		if (lday==0) {
			// Sonntag
			ld.setTime(actTime+302520000);
			weekend=true;
		} else if (lday==1) {
			// Montag
			ld.setTime(actTime+216120000);
			weekend=true;
		}
		ldayString = av.getWochentag(ld.getDay());
	
		highnoon.setHours(12);
		highnoon.setMinutes(0);
		highnoon.setSeconds(0);
		timediff = (highnoon.getTime()-120000)-actTime;
		if (timediff < 0) {
			timediff = timediff+24*3600000;
		}
		
		ordertime.setTime(timediff-3600000);
		
		if (ordertime.getMinutes() < 10 ) {
			minutes = "0"+ordertime.getMinutes();
		} else {
			minutes = ordertime.getMinutes();
		}
		
		if(av.counter) {
			if (weekend) {
				return '<strong>Unser '+dv.availability.popupLink+'</strong><br />Bei Bestellung mit 24-Stunden-Service erfolgt die Lieferung am '+ldayString+'.';
			} else {
				return '<strong>Unser '+dv.availability.popupLink+'</strong><br />Bei Bestellung in den n&auml;chsten '+ordertime.getHours()+' Std. '+minutes+' Min. mit 24-Stunden-Service erfolgt die Lieferung am '+ldayString+'.';
			}
		} else {
			return '<br /><strong>Unser '+dv.availability.popupLink+'</strong><br />Bei Bestellung im 24-Stunden-Service erhalten Sie Ihre Ware noch schneller.';            
		}
	},
	
	/**
	* TODO OPT: URL dynamisch in inc_dv_js generieren lassen per Intershop-Action
	*/  
	show24hServicePopup: function() {
		layer_trigger('layer_24hService');
	},
	
	/**
	* Wandelt einen Wochentag als Zahl in den Namen des Wochentags um
	*
	* @param day - Wochentag als Zahl (Date-Objekt)
	*
	* @returns String Wochentag als Name
	*/
	getWochentag: function(day) {
		if (day == 2) {
			return 'Dienstag';
		} else if (day == 3) {
			return 'Mittwoch';
		} else if (day == 4) {
			return 'Donnerstag';
		} else if (day == 5) {
			return 'Freitag';
		} else if (day == 6) {
			return 'Samstag';
		}
	},
	
	/**
	* Vergrößert die HTML-Elemente mit der CSS-Klasse (class="articleSelect")
	* je nach größe des Attributes "offsetwidth" der Select-Box
	* 
	* TODO OPT: klaeren, ob Funktion benoetigt wird
	*
	*/
	resizeSelectBoxes: function() {
		sboxes = $(".articleSelect");
		for ( i=0; i < sboxes.length; i++ ) {
			if ( sboxes[i].offsetWidth < 175 ) {
				sboxes[i].style.width = "175px";
			} else if ( sboxes[i].offsetWidth > 275 ) {
				sboxes[i].style.width = "275px";
			}
		}
	},
	
	/**
	* Setzt für alle HTML-Elemente mit der CSS-Klasse (class="toDebounce") das
	* "Backup"-Attribut "js" mit dem Wert des Attributes "href" und entfernt
	* schließlich das "href"-Attribut.
	* 
	* TODO OPT: klaeren, ob Funktion benoetigt wird
	* 
	*/
	debounceButtons: function() {
		$(".toDebounce").each(function(i) {
			$(this).attr("js", $(this).attr("href"));
			$(this).removeAttr("href");
		});
	},
	
	/**
	* Setzt für alle HTML-Elemente mit der CSS-Klasse (class="toDebounce") das
	* "href"-Attribut mit dem Wert des "Backup"-Attributes "js" und entfernt
	* schließlich das "js"-Attribut.
	* 
	* TODO OPT: klaeren, ob Funktion benoetigt wird
	* 
	*/
	enableButtons: function() {
		$(".toDebounce").each(function(i) {
			$(this).attr("href", $(this).attr("js"));
			$(this).removeAttr("js");
		});
	},
	
	/**
	* Erstellt ein <textarea>-HTML-Element und in seinem Inhalt alle
	*   "<" => "&lt;"
	*   ">" => "&gt;"
	*
	* @returns String mit ersetzten Entitaeten
	* 
	* TODO OPT: klaeren, ob Funktion benoetigt wird
	* 
	*/
	html_entity_decode: function(str) {
		var ta = document.createElement("textarea");
		ta.innerHTML = str.replace(/</g,"&lt;").replace(/>/g,"&gt;");
		toReturn = ta.value;
		ta = null;
		return toReturn;
	},
	
	/**
	* Tritt ein ungewöhnlicher Fehler bei KAL auf, so dass die eine Fallback-
	* Methode aufgerufen werden muss, werden Produktreferenz, Lieferstatus und
	* Lieferzeit an ein Trackingpixel übergeben.
	*/
	trackKALError: function() {
		var product_ref = dv.getProductRefID();
		var params = 'ProductRef=' + product_ref;
		var url = 'http://web.schwab.de/track/kal_schwab.php?';
		var tracking = url + params;
		
		$('#kalTracker').attr('src',tracking);
	}
}
