;(function($){
/*******************************************************************************************/	
// philips.inPageNavigation.js - version 1.2 - 8-7-2011 - AR/RvdV
// [1.0]				First implementation (AR/RvdV)
// [1.1]	27-10-2011	Removed console out (IS)
// [1.2]	16-11-2011	Zero, one or two chapters possible to show (AR)
//	
// A jQuery plugin for the Philips In Page Navigation (IPN).
/*******************************************************************************************/
	publicMethod = $.fn.inPageNavigation = function(options){
	
		// Setup default option values
		var defaults = {
			data: {},
			prefix: ".ipn-navigation .detail .prod-container",
			template: "/c/catalog/fragments/template/catalog_ipn_template.jsp"
		};
	
		var panel_id = "#" + $(this).attr('id');
		
		//override default values with options
		var options = $.extend(defaults,options);
		var data = options.data;
		var container = $(this);
		var loadedImages = 0;
		var template;
		var pageDirection = "";
		var numberOfCategories = 0;
	
		var totalImages = 2;
		var marginElement = 15;
		var oneLineHeight = 20;
		var maxTitleChars = 21;
		var cobrandingImageMaxWidth = 165;
		var maxCategoriesForResize = 1;
 		 if($("html").attr('dir') != undefined){ 	
			 if ($("html").attr('dir').toLowerCase() == "rtl") {
				pageDirection = "_rtl";
			 } 
		 }
		
		//start loading template
		loadTemplate();
	
		/**
		* Load the template
		*/
		function loadTemplate() {
			$.get(options.template, function(response) {
				container.html(response);
				createIPN();
			});
		}
	
		/**
		* Construct the InPageNavigation component,
		* + append to page using the loaded template,
		* + modify IPN for ribbon, cobrand,
		* + call sIFR from CRSC framework.
		*/
		function createIPN() {
			renderIPN();	
			modifyIPN();	
		}
		
		/**
		* Adds the template to the IPN container with
		* IPN JSON response.
		*/
		function renderIPN() {
			
			if (data) {
				if (data.content) {
					container.html(renderLayout($("#philips-ipn-template").html(), data));
					template = "DETAIL_TEMPLATE";
				} else if (data.objects) {
					container.html(renderLayoutCategoryPage($("#philips-ipn-template-catpage").html(), data));
					template = "CATEGORY_TEMPLATE";
					container.addClass("ipn-category");
					
					//activate scroller for Category IPN
					$(panel_id).inPageNavigationScroller({
						direction: pageDirection
					});
				} else {
					container.html("");
					container.append("<p class='error philips-ipn-error-message' style='display:none;'>&nbsp;&nbsp;" + data.error.message +"</p>");
				}
			} else {
				container.html("<p class='error philips-ipn-error-message' style='display:none;'>&nbsp;&nbsp;IPN JSON response is not valid (empty)</p>");
			}
		}
		
		/**
		* Inserts the data of the IPN JSON in the
		* template.
		*/
		function renderLayout(template, data) {
			
			//product details
			var content =  data.content || {};
			var chapter1, chapter2;
			
			//look for available chapters
			if (data.chapters) {
				chapter1 = data.chapters.chapter;
				if (data.chapters.chapter && data.chapters.chapter.length) {			
					chapter1 = data.chapters.chapter[0];
					chapter2 = data.chapters.chapter[1];
				}
			}
			
			//inject ribbon and/or cobranding (if there is any)
			var templateFragments =  {ribbon: "", cobranding: ""};
			if (data.content && data.content.cobrand  && data.content.cobrand !="") {
				templateFragments.cobranding = $("#philips-ipn-fragments-cobranding").html();
			}
			if (data.content && data.content.newproduct) {
				templateFragments.ribbon = $("#philips-ipn-fragments-ribbon").html();
			}
			template = insertTemplateData(template, templateFragments, "template.");
			
			//inject data in template
			template = insertTemplateData(template, content, "content.");
			template = insertTemplateData(template, chapter1, "chapter1.");
			template = insertTemplateData(template, chapter2, "chapter2.");
			
			return template;
		}
		
		/**
		* Inserts the data of the IPN JSON in the
		* template for category page.
		*/
		function renderLayoutCategoryPage(template, data) {
			var categories = "";
			numberOfCategories = 1;
			
			if (!data.objects.object.length) {
				categories += createCategory(data.objects.object);
			} else {
				numberOfCategories =  data.objects.object.length;
				if (pageDirection == "_rtl") {
					for (var i = numberOfCategories - 1; i >= 0; i--) {
						categories += createCategory(data.objects.object[i]);
					}				
				}
				else {
					for (var i = 0; i < numberOfCategories; i++) {
						categories += createCategory(data.objects.object[i]);
					}
				}
			}
			
			var chapter = data.chapters.chapter;
			data.chapters.chapter.direction = pageDirection;
			if (pageDirection == "_rtl") {
				data.chapters.chapter.rtl_image_extension = "left";
			} else {
				data.chapters.chapter.rtl_image_extension = "normal";
			}
			template = insertTemplateData(template, chapter, "chapter.");
			template = template.replace("{CATEGORIES}", categories);

			return template;
		}
		
		/**
		* Modifies the IPN template run-time according to the 
		* loaded data (subcat, new ribbon, co-branding logo)
		*/
		function modifyIPN() {
			selector = panel_id + " ";
			
			if (template == "DETAIL_TEMPLATE") {
			
				//make chapters flexible
				$.each($(selector + " .category .outer-container .inner-container a.lead"), function() { 				
					if ($(this).height() < oneLineHeight) {
						obj = $(this.parentNode.parentNode.parentNode.parentNode);
						obj.css("width", $(this).width()+marginElement);
					}
				});

				//add new ribbon when product is new
				if (data.content && data.content.newproduct) {
					$(selector + " .detail .category-image").addClass("category-image-ribbon");
				}
				
				//remove all nav chapters when no chapter is available in data
				if (!data.chapters || !data.chapters.chapter) {	
					len = 0;
				} else {
					if (data.chapters.chapter.length) {
						len = data.chapters.chapter.length;
					} else {
						len = 1;
					}		
				}
				$.each($(selector + " .category"), function(counter) {  
					if ((counter+1)>len) {
						$(this).remove();
					}
				});
			
				//remove cobranding logo
				if (data.content && (!data.content.cobrand || data.content.cobrand == '')) {
					$(selector + " li.cobranding-logo").remove();
					$(selector + " img[title='cobranding-logo']").remove();
					imageLoaded(false);
				} else {
					addLoadHandler("img[title='cobranding-logo']", true); 	//look for co-branding logo	
				}
				addLoadHandler("img[title='product-image']", false);			//add product image load handler
				
			} else if (template == "CATEGORY_TEMPLATE") {
				//make chapters flexible
				$.each($(selector + " .category .outer-container .inner-container a.lead"), function() {  
				
					titleHeight = $(this).height();
					subTitleHeight = $(selector + " .category .outer-container .inner-container .a-blue-arrow").height();
					
					titleWidth = $(this).width();
					subTitleWidth = $(selector + " .category .outer-container .inner-container .a-blue-arrow").width();
					
					newWidth = titleWidth;
					if (subTitleWidth > titleWidth) {
						newWidth = subTitleWidth;
					}

					if (titleHeight < oneLineHeight && subTitleHeight < oneLineHeight) {
						obj = $(this.parentNode.parentNode.parentNode.parentNode);
						obj.css("width", newWidth+marginElement);
					} 
				});	
				
				//check nr of categories and make changes to page when needed
				if (numberOfCategories <= maxCategoriesForResize) {
					$(selector + " .detail .cat-scroller-container .cat-scroller-list .cat-scroller-item").css("width","120px");
				} 
			}
		}
		
		//add handler to loading
		function addLoadHandler(element, checkImageDimension) {
			selector = panel_id + " .detail .prod-container .prod-container-image ";
			var elem = $(selector + " " + element); 

			if (elem.length > 0) {
				elem.load(function() {
					if (checkImageDimension) {
						if ($(this).width() > cobrandingImageMaxWidth) {
							
							src = $(this).attr("src");
							urlLength = src.indexOf("?");
							
							if (urlLength != -1) {
								newSrc = src.substring(0, urlLength) + "?$pnglarge$&wid=" + cobrandingImageMaxWidth;
							} else {
								newSrc = src + "?$pnglarge$&wid=" + cobrandingImageMaxWidth;
							}
									
							//add new dimension image from scene7
							$($(this).parent()).css("background-image","url("+newSrc+")");
							$(this).attr("src", newSrc);
							addLoadHandler("img[title='cobranding-logo']", true); //new text length check
						
						} else {
							imageLoaded(true);
						}
					} else {
						imageLoaded(true);			
					}
				});
			} else {
				imageLoaded(false);
			}	
		}
		
		//count loaded images for calculation callbac
		function imageLoaded(loaded) {
			if (loaded) {
				loadedImages++;
			} else {
				totalImages--;
			}
			
			if (loadedImages == totalImages) {
					
				checkLineHeight(); 			
				activateIPNsIFR(panel_id);

				finish();
			}
		}
		
		function activateIPNsIFR(ipn_container_prefix) {
			$(document).ready(function(){
				swf = _page.sIFR.getSWFByFont({language: _page.locale.split("_")[1]});
				if (swf){
					sIFR.activate(swf);
					sIFR.replace(header, {
						selector: ipn_container_prefix + ' ul .detail .prod-container .product-descriptor'
						,css: '.sIFR-root {background-color:#FFFFFF;color:#0B5ED7;font-size:20px}'
						,wmode: 'transparent'
					});
					sIFR.replace(header, {
						selector: ipn_container_prefix + ' ul .detail .prod-container .versionstring'
						,css: '.sIFR-root {background-color:#FFFFFF;color:#252F47;font-size:14px}'
						,wmode: 'transparent'
					});
				}	
			});
		}
		
		//check 2-lines text
		function checkLineHeight() {
			selector = panel_id + " .detail .prod-container ";
			heightProductDescriptor = $(selector + " .product-descriptor").height();

			if (heightProductDescriptor > oneLineHeight) {
				$(selector + ".product-descriptor").addClass("sIFR-ignore");
				$(selector + ".versionstring").addClass("sIFR-ignore");
				$(selector + ".product-descriptor").addClass("product-descriptor-long-content");
				$(selector + ".versionstring").addClass("versionstring-long-content");
			} else {
				$(selector + ".product-descriptor").removeClass("sIFR-ignore");
				$(selector + ".versionstring").removeClass("sIFR-ignore");
				$(selector + ".product-descriptor").removeClass("product-descriptor-long-content");
				$(selector + ".versionstring").removeClass("versionstring-long-content");
			}
			
			heightVersionString = $(selector + " .versionstring-long-content").height();
			if (heightVersionString > oneLineHeight) {
				$(selector + ".versionstring-long-content").remove();
			}
		}

		/**
		* Helper function to insert JSON data in HTML template.
		*/
		function insertTemplateData(t, obj, prefix) {
			if (obj && t) {
				$.each(obj, function(key) {
					value = (this =="[object Object]") ? " " : this;
					t = t.replace(new RegExp("{"+prefix+key+"}", 'gi'), value);
				});
			}
			return t;
		}
		/**
		* Helper function to create CATEGORY objects.
		*/
		function createCategory(catObj) {
			url = catObj.thumb + " "; //space fix for $-sign in url
			title = catObj.title;
			subcatid = ""
			
			if(typeof catObj.subcategoryid != 'undefined')subcatid =  catObj.subcategoryid;
			//check available space 
			if (!(numberOfCategories <= (maxCategoriesForResize)) && title.length > maxTitleChars) {
				title = title.substring(0,maxTitleChars) + "...";
			}

			catItem = "<li class=\"cat-scroller-item\">";
		 	catItem+= "<a href=\""+catObj.href+"\" title=\""+catObj.tooltip+"\">";
			catItem+= "<img class=\"cat-scroller-item-image\" src=\""+url+"\" title='"+catObj.tooltip+"'>";

		 	catItem+= "</a>";
			catItem+= "<input   type=\"checkbox\" keytype=\"OR\" id='" + subcatid + "' /> <a href=\""+catObj.href+"\" title=\""+catObj.tooltip+"\">";
			catItem+= "<div class=\"cat-scroller-item-desc\">"+title+" <small>("+catObj.count+")</small></div>";
			catItem+= "</a></li>";
			
			return catItem;
		}			
		/**
		* Helper function to construct JSON data url with params.
		*/
		function getConstructedDataUrl(url) {
			var u = url.replace("{type}", options.type);
			u = u.replace("{ctn}", options.ctn);
			u = u.replace("{language}", options.language);
			u = u.replace("{country}", options.country);
			return u;
		}
		/**
		* Helper function which is executed at the end
		*/
		function finish() {
			
		}
	};
})(jQuery);

;(function($){
/*******************************************************************************************/	
// philips.inPageNavigationScroller.js - version 1.0 - 22-6-2011 - AR/RvdV
// A jQuery plugin for the Philips In Page Navigation (scrolling categories) (IPN).
/*******************************************************************************************/
	publicMethod = $.fn.inPageNavigationScroller = function( options ) {
		
		// Set a few defaults for the plugin's properties
		options = $.extend({
			direction: '',
			list: '.cat-scroller-list',
			mask: '.cat-scroller-container',
			visible: 7,
			ctrlLeft: '.cat-scroller-ctrl-right',
			ctrlRight: '.cat-scroller-ctrl-left'
		},options );
		
		// Get the correct items within the IPN container by referring to the ID
		var panel_class = $(this).attr('id');
		if (panel_class) {
			panel_class = "#" + $(this).attr('id') + " ";
			options.list = panel_class + options.list;
			options.mask = panel_class + options.mask;
			options.ctrlLeft = panel_class + options.ctrlLeft;
			options.ctrlRight = panel_class + options.ctrlRight;
		}
		
		var items = $( options.list ).children();		
		var itemWidth, listWidth, maskWidth;

		if( items.length < options.visible ) {	
			options.visible = items.length;
		}
		
		var current = 0;
		var isAnimating = false;
		
		setMaximumWidthList();
		setControls();
		checkControls();

		/**
		 * This function handles the actual animation based.
		 * 
		 * @param {Object} fadeIn		The object that fades in during the animation.
		 * @param {Object} fadeOut		The object that fades out during the animation.
		 * @param {Object} newPosition	The position the categories has to slide to.
		 */
		function animateAction( fadeIn, fadeOut, newPosition ) {
			$( fadeOut ).find( 'a' ).fadeOut( 100, function(){	
				$( options.list ).animate({ left: newPosition }, 200, function(){					
					$( fadeIn ).find( 'a' ).fadeIn( 100, function() {					
						checkControls();
					});
				});
			});
		}

		/**
		 * Check if one of the controls has to be disabled;
		 * - This is done by setting the disable variable,
		 * - or by checking the position of the array.
		 * 
		 * @param {Object} disable		The position of the control that needs to be disabled (begin / end).
		 */
		function checkControls( disable ) {
			$( options.ctrlRight ).css( 'visibility', ( ( disable == 'begin' || items[ current - 1 ] == undefined ) ? 'hidden' : 'visible' ) );
			$( options.ctrlLeft ).css( 'visibility', ( ( disable == 'end' || items[ ( current + options.visible ) ] == undefined ) ? 'hidden' : 'visible' ) );
			isAnimating = false;
		}

		/**
		 * Initialize the animation based on the direction.
		 * 
		 * @param {Object} direction	The direction of the animation, -1 -> left and 1 -> right.
		 */
		function initAnimation( direction ) {
			
			// If we are already animating, return the function
			if( isAnimating ) return;
			isAnimating = true;
			
			// Check the current position of the slider and check if we are at the begin or the end.
			if( items[ current + direction ] == undefined && direction == -1 ) {
				current = 0;
				checkControls( 'begin' );
				return;
			}
			
			if( items[ ( current + options.visible - 1 ) + direction ] == undefined && direction == 1 ) {
				checkControls( 'end' );
				return;
			}
			
			current += direction;

			// Get the fadeIn and fadeOut items based on the current position in combination with the direction of the animation.
			var fadeIn, fadeOut;
			if (direction == 1) {
				fadeOut = items[ current - 1 ];
				fadeIn = items[ current + options.visible - 1 ];
			}
			else {
				fadeOut = items[current + options.visible];
				fadeIn = items[current];
			}
						
			// Now animate the action for real, based on the above set variables.
			animateAction( fadeIn, fadeOut, pxToInt( $( options.list ).css( 'left' ) ) - ( itemWidth * direction ) );
		}

		/**
		 * Convert a CSS property as a string with px to a real number.
		 * 
		 * @param {String} px	The string which ends with px.
		 */
		function pxToInt( px ) {
			return parseFloat( px.replace( 'px', '' ) );
		}

		/**
		 * Hang some eventlisteners to the arrows of the scroller.
		 */
		function setControls() {
			
			$(options.ctrlLeft).click(function() {
				if(isAnimating) return;
				initAnimation(1);
			});
			
			$(options.ctrlRight).click(function() {		
				if(isAnimating) return;
				initAnimation(-1);
			});
		}

		/**
		 * By calculating and sum all the widths of all containers except the mask, calculate the maximum width of the mask.
		 */
		function setMaximumWidthList() {
			
			var container = $( options.list ).closest( '.ipn-container' );

			var maxWidth = $( container ).width();
			maxWidth -= $( container ).find( '.category' ).width();
			maxWidth -= pxToInt( $( container ).find( '.category' ).css( 'margin-left' ) );
			maxWidth -= pxToInt( $( container ).find( '.category' ).css( 'margin-right' ) );
			
			maxWidth -= $( container ).find( '.category-arrow' ).width();
			
			maxWidth -= pxToInt( $( options.mask ).css( 'margin-left' ) );
			maxWidth -= pxToInt( $( options.mask ).css( 'margin-right' ) );
			
			maxWidth -= $( options.ctrlLeft ).width();
			maxWidth -= pxToInt( $( options.ctrlLeft ).css( 'margin-left' ) );
			maxWidth -= pxToInt( $( options.ctrlLeft ).css( 'margin-right' ) );
						
			maxWidth -= $( options.ctrlRight ).width();
			maxWidth -= pxToInt( $( options.ctrlRight ).css( 'margin-left' ) );
			maxWidth -= pxToInt( $( options.ctrlRight ).css( 'margin-right' ) );

			// Some strange behaviour in IE6, who adds 16px somewhere.
			if ($.browser.msie && $.browser.version.substr(0, 1) < 7) {
				maxWidth -= 16;
			}
			
			// Center all items in the slider, based on the available space in the slider.
			itemWidth = $( items[ 0 ] ).width();
			$( items ).css( 'margin-left', Math.round( ( maxWidth / options.visible ) - itemWidth ) / 2 );
			$( items ).css( 'margin-right', Math.round( ( maxWidth / options.visible ) - itemWidth ) / 2 );
						
			itemWidth += pxToInt( $( items[ 0 ] ).css( 'margin-left' )  );
			itemWidth += pxToInt( $( items[ 0 ] ).css( 'margin-right' )  );
								
			listWidth = itemWidth * items.length;
			maskWidth = maxWidth;
			if(maskWidth==737){maskWidth=727;}
			$( options.list ).width( listWidth );
			$( options.mask ).width( maskWidth );
						
			if( options.direction == "_rtl" ) {
				$( options.list ).css( 'left', ( ( ( items.length - options.visible ) * itemWidth ) * -1 ) + 'px' );
				current = items.length - options.visible;
			}			
						
			var count = 0;
			if( options.direction == "_rtl" ) {
				$( items ).reverse().each(function() {
					if( count > options.visible - 1 ) {
						$( this ).find( 'a' ).css( 'display', 'none' );
					}
					count++;
				});	
			}
			else {
				count = 0;
				$( items ).each(function() {
					if( count * itemWidth >= maskWidth ) {
						$( this ).find( 'a' ).css( 'display', 'none' );
					}
					count++;
				});
			} 
		}
	};
	
	$.fn.reverse = [].reverse;
})(jQuery);

function showIPNError() {
	$(".philips-ipn-error-message").css("display","inline");
}
