// >> i18n
	$.lang('moreText', {
			'de': 'mehr',
			'en': 'more',
			'fr': 'plus',
			'es': 'más',
			'it': 'di più',
			'hu': 'még',
			'nl': 'meer',
			'zh': '更多'
	});
	$.lang('fewerText', {
			'de': 'weniger',
			'en': 'fewer',
			'fr': 'moins',
			'es': 'menos',
			'it': 'meno',
			'hu': 'kisebb',
			'nl': 'minder',
			'zh': 'fewer'
	});
// <<


// >> Special scripts registration for the frontend editor
	$(function(){
		if (typeof FrontendEditor === 'object'){
			FrontendEditor.CustomerLayoutPreparer.add('bannercorrection', function(){
				$('.headerImg .hImg img').css({
					top: 237
				});
			});
			FrontendEditor.CustomerLayoutPreparer.run();
		}
	});
// <<


// >> Input Button Hover/Focus Effect (Background switcher for image and submit/reset buttons)
	InputButtonHoverEffect = $.extend(
		$.clone(LLObject),
		{
			create: function (inputs) {
				var o = LLObject.create.call(this);
				o.inputs = inputs;
				o.handleType();
				return o;
			},
			handleType: function(){
				var self = this;
				this.inputs.each(
					function (i) {
						if ($(this).attr('type') === "image"){
							self.addEffect($(this), 'button');
						}
						else if ($(this).attr('type') === "submit") {
							self.addEffect($(this), 'subButton');
						}
						else if ($(this).attr('type') === "reset") {
							self.addEffect($(this), 'resButton');
						}
					}
				);
			},
			addEffect: function (elm, className) {
				elm.hover(
					function(){elm.addClass(className + 'Hover').removeClass(className + 'Focus');},
					function(){elm.removeClass(className + 'Hover').removeClass(className + 'Focus');}
				).focus(
					function() {elm.removeClass(className + 'Hover').addClass(className + 'Focus');}
				);
			}
		}
	);
// <<


// >> Simple Flyout Handler
	//triggerEl = element that activates the flyout by hover
	//flyoutEl = element which flies out
	//used by: standalone, QuickLoginLogoutHandler
	
	SimpleFlyout = $.extend(
		$.clone(LLObject),
		{
			create: function (triggerEl, flyoutEl) {
				var o = LLObject.create.call(this);
				o.handleFlyout(triggerEl, flyoutEl);
				return o;
			},
			handleFlyout: function (triggerEl, flyoutEl) {
				triggerEl.each(
					function (i) {
						var flyout = $(this).find(flyoutEl);
						$(this).hover(
							function () {
								flyout.show();
							},
							function () {
								flyout.hide();
							}
						);
					}
				);
			}
		}
	);
//<<


// >>  Flyoutnavi (for first level nav to work with IE)
	FlyoutNavi = $.extend(
		$.clone(LLObject),
		{
			create: function () {
				var o = LLObject.create.call(this);
				o.handleHover();
				return o;
			},
			handleHover: function () {
				var self = this;
				$('div.flOuterShell_slide div.flNavEl_1_normal')
				.add('div.flOuterShell_slide div.flNavEl_1_inPath')
				.add('div.flOuterShell_slide div.flNavEl_1_here').each(
					function (i) {
						var shell = $(this).find('div.flNavNS_2');
						$(this).hover(
							function () {
								shell.show();
							},
							function () {
								shell.hide();
							}
						);
					}
				)
				
				$('div.flOuterShell_slide div.flNavEl_2_normal')
				.add('div.flOuterShell_slide div.flNavEl_2_inPath')
				.add('div.flOuterShell_slide div.flNavEl_2_here').each(
					function (i) {
						var shell = $(this).find('div.flNavNS_3');
						$(this).hover(
							function () {
								shell.show();
							},
							function () {
								shell.hide();
							}
						);
					}
				);
			}
		}
	);
// <<


// >>  Selectbox to FlyoutList
	//el = element which contains the selectbox and is used for flyout handler
	
	SelectboxSpecLayout = $.extend(
		$.clone(LLObject),
		{
			create: function (el, title) {
				var o = LLObject.create.call(this);
				o.selectBoxOuter = $(el);
				o.itemsMax = 11;
				o.itemsAll = null;
				o.currScrollItem = 0;
				o.title = title || null;
				o.editSelectboxLayout();
				return o;
			},
			editSelectboxLayout: function () {
				if (this.selectBoxOuter.find('select').length > 0) {
					this.setLayout();
					this.getSelectboxItemsAndTitle();
					this.setPager();
					this.selectBoxOuter.hover(
						function() {$(this).find('div.selectBoxList').addClass('selectBoxList_hover');},
						function() {$(this).find('div.selectBoxList').removeClass('selectBoxList_hover');}
					);
				}
			},
			layoutOuter: function () {
				var sty = '';
				if (this.title) {
					sty = " selectBoxHeaderWithText"
				}
				
				var layOuter = $(
					'<div class="selectBoxHeader' + sty + '">' +
						'<div class="sbhDes1"></div>' +
					'</div>' +
					'<div class="selectBoxList">' +
						'<div class="sblDes1">' +
							'<div class="scroller scrollerTop"><img alt="up" src="/xist4c/px/spc.gif" width="1" height="1" /></div>' +
							'<div class="inner"></div>' +
							'<div class="scroller scrollerBottom"><img alt="down" src="/xist4c/px/spc.gif" width="1" height="1" /></div>' +
						'</div>' +
					'</div>'
				);
				return layOuter;
			},
			layoutItem: function (mode, prompt, url) {
				var inner, layItem;
				
				if (mode === "here") {
					inner = '<div class="noLink"><span>' + prompt + '</span></div>';
				} else {
					inner = '<a href="' + url + '" target="_self"><span>' + prompt + '</span></a>';
				}
				
				layItem = $('<div class="item">' + inner + '</div>');
				return layItem;
			},
			getSelectboxItemsAndTitle: function () {
				var url, prompt, mode, options, self=this, title;
				title = this.title;
				options = this.selectBoxOuter.find('select option');
				
				this.itemsAll = options.length;
				
				options.each(function (i) {
					url = $(this).val();
					prompt = $(this).text();
					if ($(this).attr('selected') === true) {
						mode = "here"
						title = $(this).text();
					} else {
						mode = "standard"
					}
					self.selectBoxOuter.find('div.selectBoxList div.inner').append(self.layoutItem(mode, prompt, url));
				});
				if (title) {
					this.selectBoxOuter.find('div.selectBoxHeader div.sbhDes1').text(title);
				}
			},
			setLayout: function () {
				this.selectBoxOuter.wrap('<div class="selectBoxOuterShell"></div>');
				this.selectBoxOuter.append(this.layoutOuter());
			},
			setPager: function () {
				if (this.itemsAll > this.itemsMax) {
					var itemHeight, scrollContHeight, self=this;
					this.selectBoxOuter.find('div.scroller img').addClass('scrollArrow');
					itemHeight = this.selectBoxOuter.find('div.selectBoxList div.item').outerHeight();
					scrollContHeight = itemHeight * this.itemsMax;
					this.selectBoxOuter.find('div.selectBoxList div.inner').eq(0).css({'height': scrollContHeight + 'px', 'overflow': 'hidden'});
					this.selectBoxOuter.find('div.scroller').bind('click', function (e) {self.scrollItems(this);}).css({'cursor': 'pointer'});
				}
			},
			scrollItems: function (el) {
				var direction, itemList;
				direction = String($(el).attr('class').split(/\s+/)[1]); // scrollerTop/scrollerBottom
				itemList = this.selectBoxOuter.find('div.selectBoxList div.item');
				
				if (direction === "scrollerTop") {
					if (this.currScrollItem - this.itemsMax >= 0) {
						this.currScrollItem = this.currScrollItem - this.itemsMax;
					} else {
						this.currScrollItem = 0;
					}
					this.selectBoxOuter.find('div.selectBoxList div.inner').eq(0).scrollTo(itemList[this.currScrollItem], 600, {'axis': 'vertical', 'offset': {'left': -35, 'top': 0}})
				} else {
					if (this.currScrollItem + this.itemsMax < itemList.length) {
						this.currScrollItem = this.currScrollItem + this.itemsMax;
					} else {
						this.currScrollItem = itemList.length-1;
					}
					this.selectBoxOuter.find('div.selectBoxList div.inner').eq(0).scrollTo(itemList[this.currScrollItem], 600, {'axis': 'vertical', 'offset': {'left': -35, 'top': 0}})
				}
			}
		}
	);
// <<


//>> Quicksearch Flyout
	//overwrites the standard handleFieldPrompt to work with specials input backgrounds
	function handleFieldPrompt(fieldList){
		$(function(){
			for (var i = 0; i < fieldList.length; ++i){
				function x(f){
					var elm = $('#' + f);
					if (f !== 'c_qSearch') {
						if (elm.length === 0) {
							elm = $(f);
						}
						elm.focus(
							function(e){hidePrompt($(this), e)}
						).blur(
							function(e){
								if ($(this).val() == ''){
									showPrompt($(this), e)
								}
							}
						)
						if (elm.val() != '') hidePrompt(elm);
					}
				}
				x(fieldList[i]);
			}
		});
	}
	
	//add special class for focused input fields to work with IE
	function handleInputFocus(el) {
		var searchPhrase = $('input:text, input:password');
		var searchPhraseTextarea = $('textarea');
		if (el) {
			searchPhrase = el.find('input:text, input:password');
			searchPhraseTextarea = el.find('textarea');
		}
		
		searchPhrase.wrap('<div class="specialInputField"><div class="sif_des1"><div class="sif_des2"></div></div></div>'
		).focus(
			function(e){$(this).parents('div.specialInputField').addClass('specialInputField_focus');}
		).blur(
			function(e){$(this).parents('div.specialInputField').removeClass('specialInputField_focus');}
			).parents('div.specialInputField').parent().find('img').css({'display': 'block'});
		
		searchPhraseTextarea.wrap('<div class="specialTextareaField"><div class="sif_des1"><div class="sif_des2"></div></div></div>'
		).focus(
			function(e){$(this).parents('div.specialTextareaField').addClass('specialTextareaField_focus');}
		).blur(
			function(e){$(this).parents('div.specialTextareaField').removeClass('specialTextareaField_focus');}
		).parents('div.specialInputField').parent().find('img').css({'display': 'block'});
	}
	
	//move quicksearch element to flNav flyout
	//When there's already a subnav (e.g. english sites), replace it by the special flyout elements.
	QuicksearchFlyoutHandler = $.extend(
		$.clone(LLObject),
		{
			create: function (url, extAppID) {
				var o = LLObject.create.call(this);
				if ($('div.flOuterShell_slide div.co_specSearch').length){
					o.navItem = $('div.flOuterShell_slide div.co_specSearch div.outer').eq(0);
				}else{
					o.navItem = $('div.flOuterShell_slide div.co_search div.outer').eq(0);
				}
				o.searchUrl = url || null;
				o.extAppID = extAppID || null;
				o.quickSearchCont = null;
				o.createSpecialSearchShell();
				return o;
			},
			createSpecialSearchShell: function () {
				this.quickSearchCont = $('<div class="qSearchCont staticQuickSearch">' +
					'<form action="/' + this.searchUrl + '.htm' + Utils.getUrlSession(';jsessionid=') +'" target="_top" method="post">' +
						'<input type="hidden" value="true" name="com.livinglogic.cms.apps.search.model.SearchState.search_submit"/>' +
						'<input type="hidden" value="510-' + this.extAppID + '" name="app"/>' +
						'<table width="100%" cellspacing="0" summary="Search element" class="qSearch" cellpadding="0" border="0">' +
							'<tr>' +
								'<td width="100%" align="left">' +
									'<input name="searchDescription" value="" class="text" type="text" id="c_qSearch" size="14" />' +
									'<script type="text/javascript" language="javascript">handleFieldPrompt(["c_qSearch"]);</script>' +
								'</td>' +
								'<td class="qsSpacer" width="3"><img width="3" alt="" height="1" src="/xist4c/px/spc.gif" /></td>' +
								'<td align="left" abbr="A search field for the quick search">' +
									'<input class="button" type="image" src="/xist4c/px/spc.gif" />' +
								'</td>' +
							'</tr>' +
						'</table>' +
					'</form>' +
				'</div>');
				this.makeFlyout();
			},
			makeFlyout: function () {
				if (this.quickSearchCont.find('input').length > 0){
					this.setNewLayout();
				} else if (this.navItem.find('div.flNavCHS_2').length > 0) {
					this.navItem.find('div.flNavCHS_2').remove();
					this.navItem.append('<div class="floatTerm"></div>');
				} else {
					this.navItem.append('<div class="floatTerm"></div>');
				}
			},
			flyoutLayout: function () {
				var layout = '<div class="flNavCHS_2">'+
					'<div class="flNavNS_2">'+
						'<div class="nav">'+
							'<div class="navItem">' +
								'<div id="qSearchFlyoutNavItem"></div>'+
							'</div>' +
						'</div>'+
					'</div>'+
					'<div class="floatTerm"></div>' +
				'</div>';
				return layout;
			},
			setNewLayout: function () {
				if (this.navItem.find('div.flNavCHS_2').length == 0) {
					this.navItem.append(this.flyoutLayout);
				} else {
					this.navItem.find('div.flNavCHS_2').eq(0).replaceWith(this.flyoutLayout);
				}
				$('#qSearchFlyoutNavItem').append(this.quickSearchCont);
			}
		}
	);
//<<


//>> Print link for footer nav
	//Adds the standard print link to the footer navigation
	//When there's no print link on the page (e.g. contact page) no link will be constructed for the footer nav, too
	FooterPrintLinkHandler = $.extend(
		$.clone(LLObject),
		{
			create: function () {
				var o = LLObject.create.call(this);
				o.topAddControlShell = $('td.contentMainColumn div.topAddContrContainer');
				o.footerNaviPrintItem = $('#footerPrint');
				o.handlePrintInfo();
				return o;
			},
			handlePrintInfo: function () {
				if (this.topAddControlShell.find('td.printButton a').length > 0) {
					var printLink, printURL, height, frm = null;
					printLink = this.topAddControlShell.find('td.printButton a');
					printLink.removeAttr('onclick');
					printURL = printLink.attr('href');
					height = $(window).height()-120;
					printLink.bind('click', function(e){
						e.preventDefault();
						e.stopPropagation();
						if (RcpOvHnl.recipeObjs.length){
							Utils.busyWait(
								function(intervalObj){
									var i;
									for (i = 0; i < window.frames.length; i+=1){
										frm = window.frames[i];
										if (frm.location.href.search(/print/) > -1 && (frm.$ && frm.$.find('.moreText').length)){
											return true;
										}
									}
									return false;
								},
								200,
								100,
								function(intervalObj){
									var moreElms = frm.$.find('.moreText'), recipeItems = RcpOvHnl.recipeObjs, item, cnt = 0;
									for (i = 0; i < recipeItems.length; i+=1){
										item = recipeItems[i];
										if (item.hasMore && item.showData){
											frm.$(moreElms[cnt]).trigger('click');
											cnt++;
										}else if (item.hasMore){
											cnt++;
										}
									}
								}
							);
						}
					});
					LL_XPopup.registerPopup(
						printLink,
						'click',
						'WEBPAGE',
						'p_c',
						'c',
						0,
						0,
						{
							'fixedPosition': 'true',
							'height': height,
							'width': '857',
							'background':{
								'r': 0,
								'g': 0,
								'b': 0,
								'opacity': 0.5
							},
							'url': printURL
						}
					);
					this.footerNaviPrintItem.append(printLink);
				} else {
					this.footerNaviPrintItem.remove();
				}
			}
		}
	);
	
	//Adaptes the print view control links to work with xpopup
	PrintViewHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (textTeaser, textImages, textPrint) {
				var o = LLObject.create.call(this);
				o.printAddControlShell = $('div.printButtonShell');
				o.textTeaser = textTeaser || null;
				o.textImages = textImages || null;
				o.textPrint = textPrint || null;
				o.adaptPrintView();
				return o;
			},
			adaptPrintView: function () {
				this.printAddControlShell.remove();
				$('td.msCont').prepend(this.printAddControlShell);
				this.printAddControlShell.find('td:last').remove();
				this.printAddControlShell.find('a').attr('target', '_self');
				var textPrompts = this.printAddControlShell.find('td span');
				if (this.textTeaser) {
					textPrompts.eq(0).text(this.textTeaser);
				}
				if (this.textImages) {
					textPrompts.eq(1).text(this.textImages);
				}
				if (this.textPrint) {
					textPrompts.eq(2).text(this.textPrint);
				}
				this.reorderImgText();
				this.printAddControlShell.css('display', 'block');
			},
			reorderImgText: function () {
				var links = this.printAddControlShell.find('table td a');
				links.each(
					function (i) {
						var text = $(this).find('span');
						text.remove();
						$(this).prepend(text);
					}
				);
			}
		}
	);
//<<


//>> AJAX Login Handler (get login page elements by ajax and add it to the actually page)
	//el = outer element for appending login content
	//options = optional setting for request
	//callback = for request storage
	//test = "test" for static test mode
	//used for: RecipesOverviewHandler, QuickLoginLogoutHandler
	AjaxLoginHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (el, options, callback, test) {
				var o = LLObject.create.call(this);
				o.ajaxOuterShellClass = 'div.twoCol_login' //outer shell of the requested elements
				o.testMode = test || null; //activates test mode for static sites (special static login url and handling)
				o.ajaxLoginCont = null; //storage for the ajax request result shell
				o.initComplete = callback || null; //for storage the requested shell in the specific handler
				o.defaults = {
					requestURL: "/login.htm",
					target: null
					//requestProps: {'linkItem': 'ClickedRecipeLinkItem', 'ajaxCont': 'AlreadyGotLoginContent'}
				};
				if (options) $.extend(o.defaults, options);
				for (var k in o.defaults) o[k] = o.defaults[k];
				o.handleLoginRequest(el);
				return o;
			},
			handleLoginRequest: function (outerShell) {
				var requestURL, self=this, linkItemPrompt=null;
				requestURL = this.defaults.requestURL;
				if (this.testMode) {
					requestURL = "ireks_de_login.html";
				}
				
				if (this.defaults.requestProps.linkItem) {
					linkItemPrompt = this.defaults.requestProps.linkItem.find('span').text();
				}
				
				if (this.defaults.requestProps.ajaxCont) {
					this.ajaxLoginCont = this.defaults.requestProps.ajaxLoginCont;
					self.placeLoginContent(outerShell, this.defaults.requestProps.ajaxCont, linkItemPrompt);
				} else {
					$.ajax({
						url: requestURL,
						dataType: "html",
						success: function (data, msg) {
							self.placeLoginContent(outerShell, $(data).find(self.ajaxOuterShellClass).eq(0), linkItemPrompt);
							if (typeof self.initComplete === "function") {
								self.initComplete.call(self);
							}
						},
						error: function (req, status, error) {}
					});
				}
			},
			placeLoginContent: function (el, loginCont, linkItemPrompt) {
				//places the login shell content
				//For Recipes: adapted headline in that content: set item prompt at the start of the headline
				var loginInfoTitle, target = this.defaults.target;
				$(this.ajaxOuterShellClass).remove();
				if (target){
					target.empty().append(loginCont.clone());
				}else{
					el.append(loginCont.clone());
				}
				
				if (!this.ajaxLoginCont) {
					this.ajaxLoginCont = loginCont;
				}
				handleInputFocus($(this.ajaxOuterShellClass));
				InputButtonHoverEffect.create($(this.ajaxOuterShellClass).find('input'));
				
				if (linkItemPrompt) {
					loginInfoTitle = $(this.ajaxOuterShellClass).find('td.l h3').eq(0);
					loginInfoTitle.text(linkItemPrompt + ' / ' + loginInfoTitle.text());
				}
			}
		}
	);
//<<


//>> Recipes ov handler (handles mass date recipe items)
	RecipesOverviewHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (test) {
				var o = LLObject.create.call(this);
				o.recipeItems = $('td.massDataItem div.recipeItem');
				o.recipeObjs = [];
				o.ajaxLoginContent = null; //storage for the ajax request result shell
				o.testMode = test || null; //activates test mode for static sites (special static login url and handling)
				o.adaptItems();
				return o;
			},
			adaptItems: function () {
				var self = this;
				//set highlight
				this.recipeItems.hover(
					function () {$(this).addClass("recipeItem_highlight");},
					function () {$(this).removeClass("recipeItem_highlight");}
				);
				this.recipeItems.each(function(i){
					//clip text
					var img = null;
					if ($(this).find('td.image').length > 0) {
						img = $(this).find('td.image').eq(0);
					}
					// Record recipe overview data items and prepare item.
					self.recipeObjs.push(RecipeOverviewItem.create($(this), self, i));
					self.recipeObjs[i].prepareItemDomel();
					self.handleTextWidth($(this).find('div.desc1').eq(0), img, self.recipeObjs[i]);
					//handle link list items (when user isn't logged in)
					if (!(XIST4C_GLOBALS && XIST4C_GLOBALS.login && XIST4C_GLOBALS.login.userID) || self.testMode) {
						self.handleLinkListItems($(this), self.recipeObjs[i]);
					}
				});
			},
			handleTextWidth: function (el,img, RecipeItemObj) {
				//clips long descriptions (and additional infos).
				//Cropped text is set to "display: none" to allow the user to fade the offcut in.
				var moreText, fewerText, maxTextLength, maxTextLengthWithImage, elmText, textLength, shortText,
				addOnText, decorator, addInfo;
				moreText = $.lang("moreText");
				fewerText = $.lang("fewerText");
				maxTextLength = 304 - 7 - moreText.length; //"-7" = "... >> ";
				maxTextLengthWithImage = 220 - 7 - moreText.length; //"-7" = "... >> ";
				elmText = el.text();
				textLength = elmText.length;
				decorator='<span class="decorator">' +
					'<span class="pre">... </span>' +
					'<span class="more moreText">&gt;&gt;&nbsp;' + moreText + '</span>' +
					'<span class="addOn" style="display: none;"></span>' +
					'<span class="decorator fewerDecorator" style="display: none;">' +
						'<span class="more fewerText">&nbsp;&lt;&lt;&nbsp;' + fewerText + '</span>' +
					'</span>' +
				'</span>';
				addInfo = el.siblings('div.desc3');
				
				if (img !== null) {
					maxTextLength = maxTextLengthWithImage;
				}
				
				if ((elmText.length > maxTextLength) || (addInfo.text().length > 0)) {
					shortText = elmText.substring(0, maxTextLength);
					addOnText = elmText.substring(maxTextLength, textLength);
					RecipeItemObj.hasMore = true;
					el.text(shortText);
					el.append(decorator);
					el.find('span.addOn').eq(0).html(addOnText);
					el.find('span.moreText, span.fewerText').click(function(e){
						el.find('span.pre, span.moreText, .addOn, .fewerDecorator').add(addInfo).toggle(0, function(){
							if ($(this).hasClass('fewerDecorator')){
								if ($(this).css('display') !== 'none'){
									RecipeItemObj.showData = 1;
									$(this).css({
										display: 'inline'
									});
								}else{
									RecipeItemObj.showData = 0;
								}
							}else if ($(this).css('display') !== 'none'){
								$(this).css({
									display: 'inline'
								});
							}
						});
					});
				}
			},
			handleLinkListItems: function (el, RecipeItemObj) {
				//adaptes link list items: set/remove style class and start request
				var self = this, items;
				items = el.find('div.recipeLinkShell td.item');
				el.find('div.recipeLinkShell td.item').each(function(i){
					if ($(this).find('a').length == 0) {
						$(this).click(function(e){
							e.preventDefault();
							if (RecipeItemObj.showLogin){
								RecipeItemObj.handleSlider(0);
								items.removeClass('item_here');
							}else{
								items.removeClass('item_here');
								$(this).addClass('item_here');
								if (self.ajaxLoginContent) {
									AjaxLoginHandler.init(
										el.parents('div.des1').eq(0),
										{
											requestProps:{
												linkItem: $(this),
												ajaxCont: self.ajaxLoginContent
											},
											target: RecipeItemObj.sliderDomel
										},
										null,
										self.testMode
									);
									RecipeItemObj.handleSlider(1);
									RecipeItemObj.correctLoginLeftColumn();
								} else {
									AjaxLoginHandler.init(
										el.parents('div.des1').eq(0),
										{
											requestProps:{
												linkItem: $(this),
												ajaxCont: null
											},
											target: RecipeItemObj.sliderDomel
										},
										function(){
											self.ajaxLoginContent = this.ajaxLoginCont;
											RecipeItemObj.handleSlider(1);
											RecipeItemObj.correctLoginLeftColumn();
										},
										self.testMode
									);
								}
							}
						});
					}
				});
			}
		}
	);
//<<


// >> Recipes overview items
	RecipeOverviewItem = $.extend(
		$.clone(LLObject),
		{
			create: function(domel, parent, id){
				var o = LLObject.create.call(this);
				o.domel = domel || null;
				o.sliderDomel = null;
				o.showLogin = 0;
				o.showData = 0;
				o.hasMore = false;
				o.id = 'recipeItemSliderContainer_' + (id || '0');
				o.parent = parent || null;
				return o;
			},
			prepareItemDomel: function(){
				var lay = $('<div id="' + this.id + '" class="recipeItemSliderContainer"></div>').hide();
				this.sliderDomel = lay;
				this.domel.parents('.des1').append(lay);
			},
			handleSlider: function(opt){
				if (opt){
					this.showLogin = 1;
				}else{
					this.showLogin = 0;
				}
				this.sliderDomel.slideToggle();
			},
			correctLoginLeftColumn: function(){
				this.domel.parents('.des2').next().find('.l').css({
					paddingLeft: 20
				});
			}
		}
	);
// <<


//>> Recipes detail handling
	LLcmsRecipeCalculator = $.extend(
		$.clone(LLObject),
		{
			create: function(opts){
				var o = LLObject.create.call(this);
				o.targetClass = '.recipeDetailOuterShell';
				return o;
			},
			round: function(f){
				var newF;
				newF = Math.round(f * 1000) / 1000;
				return newF.toFixed(3) + '';
			},
			calculateIngrediansTable: function(factor){
				var ingrediansTable = $('.ingredients'), superOv_amR = 0 , ov_amR = 0, ov_amB = 0, self = this;
				ingrediansTable.find('tr').each(function(i){
					var colVal, colValFac, screenColVal, screenColValFac;
					if (!$(this).hasClass('asHeadline')){
						$(this).find('td').each(function(i){
							var col = $(this);
							if (col.hasClass('amR')){
								if (col.text() != ''){
									colVal = col.text();
								}else{
									colVal = superOv_amR + '';
									col.parent().find('.suff, .bSuff').text('kg');
								}
								colVal = parseFloat(colVal.replace(/,/, '.'), 10);
								if (!isNaN(colVal)){
									ov_amR += colVal;
									screenColVal = self.round(colVal);
									col.text(screenColVal.replace(/\./, ','));
								}
							}
							if (!isNaN(colVal)){
								if (col.hasClass('amB') && factor){
									col.addClass('amB-withValue');
									colValFac = colVal * factor;
									ov_amB += colValFac;
									screenColValFac = self.round(colValFac);
									col.text(screenColValFac.replace(/\./, ','));
								}else if (col.hasClass('amB')){
									col.html('&ndash;')
								}
							}
							if (col.hasClass('overall') || col.hasClass('busiOverall')){
								var colClass = '.resSuff', colData = ov_amR;
								if (col.hasClass('busiOverall')){
									colClass = '.resBSuff';
									colData = ov_amB;
								}
								col.text(self.round(colData).replace(/\./, ','));
								col.parent().find(colClass).text('kg');
								superOv_amR += ov_amR;
								ov_amR = 0;
								if (col.hasClass('busiOverall')){
									ov_amB = 0;
								}
							}
						});
					}
				});
			},
			prepareComponents: function(){
				var tc = this.targetClass, calcForm = $('.recipeRecalcForm', tc), self = this;
				calcForm.bind('submit.recipeCalculator', function(e){
					var xVal = $('#xmenge').val(), kgVal = $('#gesgew').val().replace(/,/, '.'), ovVal, factor;
					e.preventDefault();
					e.stopPropagation();
					xVal = !isNaN(parseInt(xVal, 10)) ? parseInt(xVal, 10) : null;
					kgVal = !isNaN(parseFloat(kgVal), 10) ? parseFloat(kgVal.replace(/,/, '.'), 10) : null;
					if (xVal || kgVal){
						if (xVal){
							self.calculateIngrediansTable(xVal);
						}else{
							ovVal = $('.ingredients tr:last-child').find('.overall').text();
							ovVal = parseFloat(ovVal.replace(/,/, '.'), 10) || 1;
							factor = kgVal / ovVal;
							self.calculateIngrediansTable(factor);
						}
					}
				});
			},
			make: function(){
				this.calculateIngrediansTable(1);
				this.prepareComponents();
			}
		}
	);
	$(function(){
		LLcmsRecipeCalculator.create().make();
	})
//<<


//>> Quicklogin/Logout Handler
	//Adds a mouseover bubble with info text for login/logout
	//Login: Disabled login-button-link and activates a lightbox with the login element within (ajax Request)
	//textLogin: text of the login mouseover bubble
	//textLogout: text of the logout mouseover bubble
	//test: set "test" for the static sites
	QuickLoginLogoutHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (textLogin, textLogout, test) {
				var o = LLObject.create.call(this);
				o.outerShell = $('div.quickLogKontainer');
				o.textLogin = textLogin || 'Rezepte einloggen';
				o.textLogout = textLogout || 'Rezepte ausloggen';
				o.ajaxLoginContent = null; //storage for the ajax request result shell
				o.testMode = test || null; //activates test mode for static sites (special static login url and handling)
				o.getMode();
				return o;
			},
			getMode: function () {
				if (this.outerShell.find('form').length > 0) {
					this.handleLoginMode();
				} else {
					this.handleLogoutMode();
				}
			},
			handleLoginMode: function () {
				var loginURL, loginButton, self=this;
				this.setMouseOver(this.textLogin);
				loginURL = this.outerShell.find('form.quicklogin').eq(0).attr('action');
				loginButton = this.outerShell.find('td.qlButton input');
				self.setXpopup(loginButton);
				loginButton.bind('click', function (e) {
					e.preventDefault();
					if (self.ajaxLoginContent) {
						AjaxLoginHandler.init(
							$('#loginXpopupTarget'),
							{
								'requestURL': loginURL,
								'requestProps': {'ajaxCont': self.ajaxLoginContent}
							},
							null,
							self.testMode
						);
					} else {
						AjaxLoginHandler.init(
							$('#loginXpopupTarget'),
							{
								'requestURL': loginURL,
								'requestProps': {'ajaxCont': null}
							},
							function(){
								self.ajaxLoginContent = this.ajaxLoginCont;
							},
							self.testMode
						);
					}
				});
			},
			handleLogoutMode: function () {
				this.setMouseOver(this.textLogout);
			},
			setMouseOver: function (text) {
				var layout;
				layout = '<div class="flyout">' +
					'<div class="inner">' + text + '</div>' +
				'</div>';
				
				this.outerShell.prepend(layout);
				SimpleFlyout.create(this.outerShell, 'div.flyout');
			},
			setXpopup: function (el, cont) {
				LL_XPopup.registerPopup(el, 'click','HTMLSRC','p_c','c',0,0,{'fixedPosition':'true','height':'230','width':'717','background':{'r': 0, 'g': 0, 'b': 0, 'opacity': 0.5}, 'cont':'<div id="loginXpopupTarget"></div>'});
			}
		}
	);
	
	FooterLoginLogoutHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (logoutText, test) {
				var o = LLObject.create.call(this);
				o.ajaxLoginContent = null; //storage for the ajax request result shell
				o.testMode = test || null; //activates test mode for static sites (special static login url and handling)
				o.outerShell = $('div.quickLogKontainer');
				o.footerItem = $('#footerLogin');
				o.logoutText = logoutText || 'Logout';
				o.getMode();
				return o;
			},
			getMode: function () {
				if (this.outerShell.find('form').length > 0) {
					this.handleLoginMode();
				} else {
					this.handleLogoutMode();
				}
			},
			handleLoginMode: function () {
				var loginURL, loginButton, self=this;
				loginURL = this.outerShell.find('form.quicklogin').eq(0).attr('action');
				loginLinkItem = this.footerItem.find('a');
				self.setXpopup(loginLinkItem);
				loginLinkItem.bind('click', function (e) {
					e.preventDefault();
					if (self.ajaxLoginContent) {
						AjaxLoginHandler.init(
							$('#loginXpopupTarget'),
							{
								'requestURL': loginURL,
								'requestProps': {'ajaxCont': self.ajaxLoginContent}
							},
							null,
							self.testMode
						);
					} else {
						AjaxLoginHandler.init(
							$('#loginXpopupTarget'),
							{
								'requestURL': loginURL,
								'requestProps': {'ajaxCont': null}
							},
							function(){
								self.ajaxLoginContent = this.ajaxLoginCont;
							},
							self.testMode
						);
					}
				});
			},
			handleLogoutMode: function () {
				var logoutLink = this.outerShell.find('table td a').attr('href');
				this.footerItem.find('a').attr('href',logoutLink).text(this.logoutText);
			},
			setXpopup: function (el, cont) {
				LL_XPopup.registerPopup(el, 'click','HTMLSRC','p_c','c',0,0,{'fixedPosition':'true','height':'230','width':'717','background':{'r': 0, 'g': 0, 'b': 0, 'opacity': 0.5}, 'cont':'<div id="loginXpopupTarget"></div>'});
			}
		}
	);
//<<


//>> Slideshow (Images and text fade in)
	//To handle the loop every last but two element is set to "hide"
	//Standard Text-Banner for head image is set to "hide"
	SlideshowHandler = $.extend(
		$.clone(LLObject),
		{
			init: function () {
				var o = LLObject.create.call(this);
				o.outerShell = $('div.slideshow ul');
				o.items = null;
				o.startSlider();
				return o;
			},
			startSlider: function () {
				$('div.headImgText').hide();
				this.items = this.outerShell.find('li');
				$(this.items[0]).show();
				this.run();
			},
			run: function(){
				var self = this, maxItems, currItem;
				maxItems = this.items.length -1;
				currItem = 0;
				index = 100;
				Utils.busyWait(
					function(){
						if (currItem == maxItems) {
							currItem = 0;
						} else {
							currItem++
						}
						index++;
						$(self.items[currItem]).fadeIn(2000).css("z-index", index);
						// Negative number combined with "mod" results negative number.
						// Workaround: Handle the special items yourself...
						if ((currItem - 2) >= 0 ) {
							$(self.items[currItem - 2]).hide();
						} else {
							$(self.items[self.items.length + currItem - 2]).hide();
						}
						return false;
					},
					4000,
					100,
					function(){
					}
				);
			}
		}
	);
//<<


//>> Photogallery Hover effect
	PhotogalleryHoverEffect = $.extend(
		$.clone(LLObject),
		{
			init: function () {
				var o = LLObject.create.call(this);
				o.setHover();
				return o;
			},
			setHover: function () {
				$('div.mds_detailItems div.des1').each(
					function (i) {
						if ($(this).find('img.dummySpacer').length == 0) {
							$(this).mouseover(function(){$(this).addClass('des1JsHover')});
							$(this).mouseout(function(){$(this).removeClass('des1JsHover')});
						}
					}
				);
			}
		}
	);
	$(function() {PhotogalleryHoverEffect.init();});
//<<


//>> Faked upload fields (creates styled upload inputs)
	// Pre-Condition: all upload fields needs a corresponding text input field (faked field name = upload field name + '_fake').
	// The script wraps the faked field in special shells which are adapted/designed by the css.
	// By css the faked field is placed under the upload field and the upload field's
	// opacity is set to zero. That effects by clicking in the visible field (faked field)
	// the user actually clicks in the hidden upload field and so the upload works as normal.
	// By setting the addFields variable, these addFields shows more upload fields after
	// filling one by one of the stored upload field. These fields have to placed in the
	// form's html code and set to 'display: none' to work with the database form's restore mode!
	// When there is a file for an upload selected a remove icon is faded in and
	// allows the user to remove the uploaded file of the form.
	
	FakedUploadFields = $.extend(
		$.clone(LLObject),
		{
			init: function (el, addFields) {
				var o = LLObject.create.call(this);
				o.inputs = $('input.fileInput:file');
				o.addFields = addFields || null;
				o.handleElms(el);
				return o;
			},
			handleElms: function (el) {
				var self = this;
				this.handleContentNavItems();//handles content navigation to work with forms
				this.disableBewerbungAls();//handles job overview requests
				if (el) {
					el.find('input.fileInput:file').each(function (i) {
						self.fakeUploads($(this));
					});
				} else {
					this.inputs.each(function (i) {
						self.fakeUploads($(this));
					});
				}
				this.handleAddFields();
			},
			handleContentNavItems: function () {
				var contentNavItems = $('div.contNavShell_jobApplication td.contNavItem');
				var form = $('td.contentColumn form');
				var pageInput = $('td.contentColumn input[name="seite"]');
				var hereIndex = -1;
				contentNavItems.each(function (i) {
					if ($(this).hasClass('cni_normal') && (hereIndex !== -1)) {
						$(this).find('a').bind('click', function (e) {
							e.preventDefault();
						});
						$(this).find('a').addClass('specialHandling');
					} else if ($(this).hasClass('cni_normal')) {
						$(this).find('a').bind('click', function (e) {
							e.preventDefault();
							pageInput.val(i+1);
							form.submit();
						});
					} else {
						hereIndex = i;
					}
				});
			},
			disableBewerbungAls: function () {
				var ovId = $('input[name=sta_id]');
				if (ovId.val()) {
					$('input[name=bewerbungals]').attr('readonly', 'readonly');
				}
			},
			fakeUploads: function (upload) {
				var inputName = upload.attr('name');
				var fakedInput = $('input[name=' + inputName + '_fake]');
				this.createLayout(upload, inputName);
				this.handleFakedInput(upload, fakedInput);
				//handleInputFocus(upload.parent('div.uploadDes1'));
				this.handleDeleteButton(upload, fakedInput);
				InputButtonHoverEffect.create(upload.parent('div.uploadDes1').find('td.button input'));
			},
			createLayout: function (upload, inputName) {
				var visible = 1;
				if (upload.css('display') === 'none') {
					visible = 0;
				}
				upload.wrap(this.setOuterLayout(inputName, visible));
				upload.parent('div.uploadDes1').append(this.setInnerLayout(inputName));
				upload.parent('div.uploadDes1').find('td.field').append($('input[name=' + inputName + '_fake]:text').parents('div.specialInputField')[0]);
			},
			setInnerLayout: function (inputName) {
				var layout = '<table width="100%" cellspacing="0" cellpadding="0" border="0" class="fakedFieldTable">' +
					'<tr>' +
						'<td class="field">' +
							'<img width="1" height="1" src="/xist4c/px/spc.gif" class="normal" alt="">' +
						'</td>' +
						'<td class="button">' +
							'<input type="image" src="/xist4c/px/spc.gif" value="Durchsuchen" alt="Durchsuchen" />' +
						'</td>' +
					'</tr>' +
				'</table>';
				return layout;
			},
			setOuterLayout: function (inputName, visible) {
				var sty = null;
				if (!visible) {
					sty = ' style="display: none;"';
				}
				var layout = '<div class="uploadOuter uploadOuter_' + inputName + ' viewport"' + sty + '><div class="uploadDes1"></div></div>';
				return layout;
			},
			handleFakedInput: function (upload, fakedInput) {
				var self = this;
				var bindings = 'mouseenter mouseleave';
				if (window.navigator.platform === "Win32" && $.browser.mozilla) {
					upload.attr('size', '57');
				}
				upload.bind(bindings, function (e) {
					fakedInput.trigger(e.type);
					upload.parent('div.uploadDes1').find('td.button input').trigger(e.type);
				});
				//fakedInput.val(upload.val());
				upload.bind('change', function (e) {
					fakedInput.val($(this).val());
					self.handleDeleteButton($(this), fakedInput);
					self.handleAddFields();
				});
			},
			handleDeleteButton: function (upload, fakedInput) {
				var img = upload.parent('div.uploadDes1').find('td.field img').eq(0);
				var self = this;
				if (fakedInput.val() !== '') {
					img.unbind('click.deleteButtonHandler');
					img.bind('click.deleteButtonHandler', function () {
						var newUpload = upload.clone().val('');
						upload.replaceWith(newUpload);
						self.handleFakedInput(newUpload, fakedInput);
						fakedInput.val('');
						$(this).removeClass('delete');
					});
					img.addClass('delete');
				}
			},
			handleAddFields: function () {
				if (this.addFields) {
					for (var i = 0; i < this.addFields.length; ++i) {
						for (var j = 0; j < this.addFields[i].length; ++j) {
							var upload = $('input.fileInput[name=' + this.addFields[i][j] + ']:file');
							var fakedInput = $('input[name=' + this.addFields[i][j] + '_fake]')
							if ((upload.length > 0 && upload.val() !== '') || (fakedInput.length > 0 && fakedInput.val() !== '')) {
								upload.show();
								upload.parents('div.uploadOuter').show();
								if (j+1 < this.addFields[i].length) {
									var nextEl = $('input.fileInput[name=' + this.addFields[i][j+1] + ']:file');
									nextEl.show();
									nextEl.parents('div.uploadOuter').show();
								}
							}
						}
					}
				}
			}
		}
	);
//<<


//>> Handle standard error shell for forms
	// Handle the combination of standard error list and errorblocks in the form content.
	// Compares the error messages and remove duplicates in the standard list.
	// When a target container is set the error list shell will be appended to that container.
	// If there are no standard error items left the whole element will be removed.
	// errorList = standard error list (on top of the content)
	// errorBlocks = error messages in the form content
	FormErrorShellHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (targetCont) {
				var o = LLObject.create.call(this);
				o.targetCont = targetCont || null;
				o.handleErrors();
				return o;
			},
			handleErrors: function () {
				var errorList = $('td.contentColumn').find('form').eq(0).prev('td.contentColumn ul').addClass('defaultErrorList');
				var errorBlocks = $('td.contentColumn form div.formError span');
				$('td.contentColumn form input:text').eq(0).focus();//to fix an IE bug (missplaced required arrows)
				if ((errorList.length > 0) && (errorBlocks.length > 0)) {
					errorList.hide();
					this.removeDuplicates(errorList, errorBlocks);
					if (errorList.children().length > 0) {
						if (this.targetCont && (this.targetCont.length > 0)) {
							this.targetCont.append(errorList);
						}
						errorList.show();
					} else {
						errorList.remove();
					}
				} else if (errorList.length > 0){
					errorList.hide();
					if (this.targetCont && (this.targetCont.length > 0)) {
						this.targetCont.append(errorList);
					}
					errorList.show();
				}
				$('td.contentColumn form input:text').eq(0).blur();//to fix an IE bug (missplaced required arrows)
			},
			removeDuplicates: function (errorList, errorBlocks) {
				var errors, errorBlocksMsgs, errorBlocksList;
				errorBlocksMsgs = [];
				errors = errorList.find('li');
				
				errorBlocks.each(function () {
					errorBlocksMsgs.push($(this).text());
				});
				
				errors.each(function () {
					var errorText = $(this).text();
					if ($.inArray(errorText, errorBlocksMsgs) > -1) {
						//$(this).addClass('forRemove');
						$(this).remove();
					}
				});
			}
		}
	);
//<<


//>> Partner search prev text handling
	// Cuts off all 'cutOffForSearchResults' paragraphs right before partner search element.
	PartnerSearchPrevTextHandler = $.extend(
		$.clone(LLObject),
		{
			init: function () {
				var o = LLObject.create.call(this);
				o.text = $('div.co_cutOffForSearchResults');
				o.partnerItems = $('div.partnerItem');
				o.removeText();
				return o;
			},
			removeText: function () {
				if (this.text.length > 0 && this.partnerItems.length > 0) {
					this.text.hide();
				}
			}
		}
	);
//<<


//>> GlowHandler (standard)
	GlowHandler = $.extend(
		$.clone(LLObject),
		{
			init: function (itemClass) {
				var o = LLObject.create.call(this);
				o.itemClass = itemClass || null;
				o.adaptItems();
				return o;
			},
			adaptItems: function () {
				var self = this, items;
				if (this.itemClass) {
					items = $('td.massDataItem div.' + this.itemClass)
					//set highlight
					items.hover(
						function () {$(this).addClass(self.itemClass + "_highlight");},
						function () {$(this).removeClass(self.itemClass + "_highlight");}
					);
				}
			}
		}
	);
//<<



