/**
 * 	CHANGELOG
 * 
 * 	1.0.1
 * 
 * 		- Now the articles in the slider are highlighted without the use of the ugly url parameters
 * 		- The articles getting re-highlighted after the user has left the categorynavigation
 * 			- removed option "saveSelectedItem"
 * 
 * 
 * 	1.0.0
 * 
 *	 	Initial
 * 
 */
( function( $ ) 
{
	/**
	 * 	Factory to load and parse the results of the webservice
	 */
	function FArticleList()
	{
		/**
		 * 	The options for the factory
		 */
		var __options = {};
		
		/**
		 * 	The json data from an ajax call
		 */
		var __jsonData = "";
		
		/**
		 * 	An array to save the parsed objects in
		 */
		var __list = new Array();
		
		
		
		// - - -
		
		
		
		/**
		 * 	Starts loading the data from the webservice
		 * 
		 * 	@param	url	The url to the webservice
		 */
		this.load = function( options )
		{
			__options = options;
			
			var ajaxOptions = 
			{
				url: options.url,
				dataType: "json",
				beforeSend: __options.openHandler,
				error: __options.errorHandler,
				success: __handleRequestCompleted
			};
			
			$.ajax( ajaxOptions );
		}
		
		
		
		// - - -
		
		
		
		/**
		 * 	Dispatched after the data was loaded successfully
		 * 	from the webservice
		 */
		var __handleRequestCompleted = function( data )
		{
			__parseData( data );
		}
		
		
		/**
		 * 	Parses the given json object to our value object
		 * 
		 * 	@param {Object} response
		 */
		var __parseData = function( jsonData )
		{
			__jsonData = jsonData;
			
			if ( !__dataValid( __jsonData ) )
			{
				__options.completeHandler( null );
				return;
			}
			
			for ( i = 0; i < __jsonData.length; i++ )
			{
				if( !__jsonData[i] ) continue;
			
				__list.push( { image: __jsonData[i].oxpic1, title: __jsonData[i].oxtitle, articleID: __jsonData[i].oxid, url: __jsonData[i].oxseourl } );
			}
			
			__options.completeHandler( __list )
		}
				
		
		/**
		 * 	Checks whether the loaded data is valid or not
		 */
		var __dataValid = function( jsonData )
		{
			if( !jsonData ) return false;
			if( jsonData.length < 1 ) return false;
			
			return true;
		}
	}
	
		
		
		
		
		
	// - - -
		
		
		
		
		
		
	/**
	 * 
	 */
    var Slider = function( element, options )
    {
    	/**
    	 * 	The element this slider gets attached to
    	 */
    	var __element = $( element );
    	
    	/**
    	 * 	The options for the slider
    	 */
    	var __options = $.extend( { param: "defaultValue" }, options || {} );
    	
    	/**
    	 * 	An variable to save the current page number of the slider
    	 */
    	var __currentPage = 0;
    	
    	/**
    	 * 	The number of pages we have in the slider
    	 */
    	var __numberOfSlides = 0;
    	
    	/**
    	 * 	An reference to the UrlUtil class
    	 */
    	var __urlUtil;
    	
    	/**
    	 * 	The number of the page we have to show initialy
    	 */
    	var __activePage = 0;
    	
    	
    	
    	// - - -
    	
    	
    	
    	/**
    	 * 	Init the slider
    	 */
		this.init = function()
		{
			var factoryOptions = 
			{
				url: options.url + options.categoryID,
				openHandler: __handleRequestOpen,
				errorHandler: __handleRequestError,
				completeHandler: __handleParsingCompleted
			}
			
			var factory = new FArticleList();
			factory.load( factoryOptions );
			
			__urlUtil = new UrlUtil();
			__urlUtil.init();
		};
		
    	
    	
    	// - - -
    	
    	
    	
    	/**
    	 * 	Dispatched before the ajax call to the webservice. Shows
 		 *  an loading message to the user
    	 */
    	var __handleRequestOpen = function()
    	{
    		__showMessage( "Loading" );
    	};
    	
    	
    	/**
    	 * 	Called after the request to the webservice ended in an error
    	 */
    	var __handleRequestError = function()
    	{
    		__showMessage( "Daten konnten nicht geladen werden!", "error" );
    	};
    	
    	
    	/**
    	 * 	Called by the article list factory if parsing of the loaded data
    	 * 	was successfully
    	 * 
    	 * 	@param	articleList	An array of value objects
    	 */
    	var __handleParsingCompleted = function( articleList )
    	{
    		if( !articleList|| articleList.length == 0 ) __showMessage( "Es konnten keine Produkte gefunden werden!", "error" );
			else __initSlider( articleList );
    	};
    	
    	
    	/**
		 *  Inits the slider
		 * 
		 *  @param  articleList An array with article value objects
		 */
		var __initSlider = function( articleList )
		{
			// clear the status message
			__showMessage( "", "clear" );
			
			articleList.unshift( null );
			//  the number of the current page
			var currentPage = 1;
			// the container for the slides
			var slideContainer = "<div class='slideContainer' id='slideContainer'></div>";
			// the margin of this container gets animated by pressing one of the controls on the page
			var slideInner = "<div id='slideInner'></div>";
			// an helper variable to save the contents of a single page
			var page = "";
			//	set the selector for the articles container of our root element
			var selector = "#" + __element[0].id + " " + __options.articles;
			
			//	add the container to our main container				
			$( selector ).html( slideContainer );
			// aet the background to the main container
			$( "#" + __element[0].id ).css( "background", "url( " + __options.backgroundImage + " ) repeat-x scroll 0 0 #e0e0e0" );
			
			// iterate over the article list to create the slider pages
			for( var i = 1; i < articleList.length; i++ )
			{		
				//	create the articles
				var model = articleList[i];
				//	an var to save the classes for an article
				var classes = "";
				
				//alert (model.image);
				// awa: Ändern der URL zu Artikelbild_1 -> zur URL zu Icon_1
				model.image = model.image.replace(/_p1.jpg/, "_p1_ico.jpg");
				
				
				//	check if we have to highlight an article from an previous page
				if( model.articleID == __options.articleID )
				{
					classes = "article active";
					__activePage = Math.ceil( i / __options.numItemsPerPage ) - 1;
				}
				else classes = "article";
				
				page += "<div class='" + classes + "' id='" + model.articleID + "'>" +
							"<a href='" + model.url + "' title='" + model.title + "'>" +
								"<div class='categorynavigationImageDiv imgWrapper img_table' >" +
									"<div class='img_tableCell'>" +
										"<img src='" + model.image + "' alt='" + model.title + "' />" +
										"<div class='ieCenter'></div>" +
									"</div>" +
								"</div>" +
								"<p>" + model.title + "</p>" +
							"</a>" +
						"</div>";
				
				//  if the max number of items per page has reached, append the page
				//  to the slide container
				if( i % __options.numItemsPerPage == 0 || i == articleList.length - 1 )
				{
					//  create the page
				  	slidePage = "<div class='slidePage' id='slidePage_" + currentPage + "'></div>";
					$( slidePage ).appendTo( "#" + __element[0].id + " #slideContainer" );
					$( "#" + __element[0].id + " #slidePage_" + currentPage ).html( page );
					// reset the page content var
					page = "";
					// increase the pagenumber
					currentPage++;
				}
			}
			
			// get all slidePages an add it to the animation container
			var slides = $( "#" + __element[0].id + " .slidePage" );   
			slides.wrapAll( "<div id='slideInner'></div>" );
			$( "#" + __element[0].id + " .slidePage" ).css( "width", __options.slideWidth );
			 
			var slideInnerWidth = currentPage * __options.slideWidth;
			$( "#" + __element[0].id + " #slideInner" ).css( "width", slideInnerWidth );
			  
			//  init the slider controls
			__initControls();
			
			//	set the articles interactive if set in the options
			if( __options.interactive ) __setInteractiveArticles();
		}
		
		
		/**
		 *  Inits the controls for the slider
		 */
		var __initControls = function()
		{
			var slides = $( "#" + __element[0].id + " .slidePage" );
			__numberOfSlides = slides.length;
			
			//	add the controls to our main container
			$( "#" + __element[0].id + " #slideContainer" ).prepend( "<span class='control' id='leftControl'>Move left</span>" )
			$( "#" + __element[0].id + " #slideContainer" ).append( "<span class='control' id='rightControl'>Move right</span>" );
			
			//  mouse interaction
			$( "#" + __element[0].id + " .control" ).bind( "click", function()
			{
				__currentPage = ( $( this ).attr( "id" ) == "rightControl" ) ? __currentPage + 1 : __currentPage - 1;
				__navigateToPage( __currentPage, true );
			});
			
			//	set the initial shown page in the slider if not the first
			__setStartPage();
		}
		
		
		/**
		 * 	Shows the given page number either animated or not
		 * 
		 * 	@param	pageNumber	The number of the page you want to navigate to
		 * 	@param	animated	Whether you want to change the page with an
		 * 						animation or not
		 */
		var __navigateToPage = function( pageNumber, animated )
		{
			//	calculate the margin for the slider page we want to show
			var newMargin = __options.slideWidth * ( -pageNumber );
    		
    		//	change the current visible slider page based on the animated param
    		if( animated ) $( "#" + __element[0].id + " #slideInner" ).animate( { "marginLeft" : newMargin } );
    		else $( "#" + __element[0].id + " #slideInner" ).css( "marginLeft", newMargin );
    		
    		//	set the current page number to the data attribute of our main element. Used
    		//	to navigate to this slider page after the user has navigated to another page
    		$( __element ).data( "currentPage", __currentPage );
    		
    		//	update the controls
    		__manageControls( __currentPage );
		}
		
		
		/**
		 * 	Handles the visibility of the controls
		 * 
		 * 	@param	currentPage	The number of the current visible page
		 */
		var __manageControls = function( currentPage )
		{
			//	hide the left control if we on the first slider page
			if( currentPage == 0 ) $( "#" + __element[0].id + " #leftControl" ).hide();
			else $( "#" + __element[0].id + " #leftControl" ).show();
			
			if( currentPage == __numberOfSlides )
			{
				$( "#" + __element[0].id + " #leftControl" ).hide();
				__currentPage = 0;
				__navigateToPage( __currentPage, true );
				currentPage = 0;
			}
			else if( currentPage == ( __numberOfSlides - 1 ) )
			{
				$( "#" + __element[0].id + " #rightControl" ).hide();
			}
			else $( "#" + __element[0].id + " #rightControl" ).show();
			
			//	hide the right control if we have just one page to display
			if( __numberOfSlides == 1 ) $( "#" + __element[0].id + " #rightControl" ).hide();
		}
		
		
		/**
		 * 	Sets the initial shown page in the slider if given from the options
		 */
    	var __setStartPage = function()
    	{
    		if( __options.startPage > 0 && __options.startPage <= __numberOfSlides )
    		{
    			__currentPage = __options.startPage;
    			__navigateToPage( __currentPage, false );
    		}
    		else if( __activePage != 0 )
    		{
    			__currentPage = __activePage;
    			__navigateToPage( __activePage, false );
    		}
    		else __navigateToPage( 0, false );
    	}
    	
    	
    	/**
    	 * 	Adds a 'active' class to the hovered article
    	 */
    	var __setInteractiveArticles = function()
    	{
    		//	add a mouseover bindin to all articles in the root container
    		$( "#" + __element[0].id + " .article" ).bind( "mouseover", function()
			{
				//	first we remove the active class from all the articles
				$( "#" + __element[0].id + " .article" ).each( function()
	    		{
	    			$( this ).removeClass( "active" );
	    		});
				
				//	highlight the hovered article
				$( this ).addClass( "active" );
			});
			
			//	remove the active state if the user leaves the root container
			$( __element ).bind( "mouseout", function()
			{
				$( "#" + __element[0].id + " .article" ).each( function()
	    		{
	    			$( this ).removeClass( "active" );
	    		});
	    		
	    		if( __options.articleID ) __highlightArticle( __options.articleID );
			});
    	}
    	
    	
    	/**
    	 * 	Highlights an article in the slider with the given articleID
    	 * 
    	 * 	@param	articleID	The id of the article you want to hightlight
    	 */
    	var __highlightArticle = function( articleID )
    	{
    		$( "#" + __element[0].id + " .article" ).each( function()
	    	{	    		
	    		if( $( this ).attr( "id" ) == articleID )
	    		{
	    			$( this ).addClass( "active" );
	    		}
	    	});
    	}
    	
    	
    	/**
    	 * 	Use to get an parameter from the current url by its name
    	 * 
    	 * 	@param	name	The name of the parameter you want to get
    	 * 
    	 * 	@return	The value of the requested parameter
    	 */
    	var __getUrlParam = function( name )
    	{
    		var vars = [], hash;
			var hashes = window.location.href.slice( window.location.href.indexOf( "?" ) + 1 ).split( "&" );
			for( var i = 0; i < hashes.length; i++ )
			{
				hash = hashes[i].split( "=" );
				vars.push( hash[0] );
				vars[hash[0]] = hash[1];
			}
			
			return vars[name];
    	}
    	
    	
    	/**
    	 * 	Returns the position of the highlighted article in the slider
    	 * 
    	 * 	@return	The position of the highlighted article in the slider
    	 */
    	var __getHighlightedArticle = function()
    	{
    		console.log( "categorynavigation -> __getUrlParam()" );
			console.log( "   |---> article name: " + __urlUtil.getArticleName( "Theo Klein" ) );
    		
    		return __getUrlParam( "a" );
    	}
    	
    	
    	/**
    	 * 	Returns the id of the category the articles of the slider are from
    	 * 
    	 * 	@return	The id of the category the articles of the slider are from
    	 */
    	var __getCurrentCatID = function()
    	{
    		return __getUrlParam( "c" );
    	}
    	
    	
    	/**
		 *  Shows an status message to the user. 
		 * 
		 *  @param  message The message you want to show
		 *  @param  status  An status code. If no status code is
		 *                  given we show an spinning loader gif.
		 *                  Use 'error' to format the message as an
		 *                  error. If you use clear first the containers
		 *                  display mode is set to none and the content
		 *                  of the container gets removed
		 */
		var __showMessage = function( message, status )
		{
			var selector = "#" + __element[0].id + " " + __options.status;
			var imagePath = __getImagePath();
			
			// if status not set we show an error message
			if( !status )
			{
				$( "#" + __element[0].id + " " + __options.articles ).html( "" );
				$( selector ).css( "" );
		    	$( selector ).css( "display", "block" );
		    	$( selector ).css( "background-color", "#fff" );
		    	$( selector ).css( "padding", "45px 0 22px" );
		    	$( selector ).html( "<img src='" + imagePath + "' /><p>" + message + "</p>" );
			}
			else if( status == "error" )
		  	{
		  		$( selector ).html( "" );
		    	$( selector ).css( "display", "block" );
		    	$( selector ).css( "background-color", "#fff" );
		    	$( selector ).css( "padding", "60px 0 40px" );
		    	$( selector ).html( message );
		  	}
			else if( status == "clear" )
			{
				$( selector ).css( "display", "none" );
				$( selector ).css( "background-color", "none" );
				$( selector ).html( "" );
			}
		}
		
		
		/**
		 * 	Returns the path to the loading gif depending on the environment
		 */
		var __getImagePath = function()
		{
			
			var basePath = location.protocol + "//" + location.host;
			if( location.host.indexOf( "oxid-dev") != -1 ) basePath += "/kittoys/shop/";
			
			var imagePath = basePath + "/out/kittoys_theme/src/snippet/categorynavigation/img/ajax-loader.gif";
			return imagePath;
		}
    };
    
    	
    	
    // - - -
    	
    	
    	
    /**
	 * 	Util class to work with the url from the current window
	 */
    var UrlUtil = function()
    {
    	/**
    	 * 	The whole url of the opened page
    	 */
    	var __baseUrl = "";
    	
    	/**
    	 * 	The subparts of the url
    	 */
    	var __hashes = [];
    	
    	
    	
    	// - - -
    	
    	
    	
    	/**
    	 * 	Inits this class
    	 */
    	this.init = function()
    	{
    		__baseUrl = window.location.href;
    		__getHashes();
    	}
    	
    	
    	/**
    	 * 
    	 */
    	this.getUrl = function()
    	{
    		return __baseUrl;
    	}
    	
    	
    	/**
    	 * 
    	 */
    	this.getArticleName = function( exclude )
    	{
    		//for( var i = 0; i < )
    		
    		var articleName = "";
    		articleName = __hashes[ __hashes.length - 1 ];
    		while( articleName.indexOf( "-" ) != -1 ) articleName = articleName.replace( "-", " " );
    		
    		if( exclude != "" ) articleName = articleName.replace( exclude, "" );
    		
    		articleName = articleName.replace( "Bosch Mini", "- Bosch Mini")
    		
    		return articleName;
    	}
    	
    	
    	/**
    	 * 
    	 */
    	this.getCategoryName = function()
    	{
    		return __hashes[ __hashes.length - 2 ]; 
    	}
    	
    	
    	
    	// - - -
    	
    	
    	
    	/**
    	 * 
    	 */
    	var __getHashes = function()
    	{
    		var hostName = window.location.host;
			var urlParts = __baseUrl.slice( __baseUrl.indexOf( hostName ) + hostName.length + 1 ).split( "/" );
			
			for( var i = 0; i < urlParts.length; i++ )
			{
				hash = urlParts[i];
				if( hash.indexOf( "." ) != -1 ) hash = hash.substring( 0, hash.indexOf( "." ) );
				
				__hashes.push( hash );
			}
    	}
    };
    
		
		
		
		
		
	// - - -
		
		
		
		
		
		
	/**
	 * 	An jQuery plugin to show an category navigation as slider on your page.
	 * 
	 * 	Available options:
	 * 
	 * 		url:				The url to the webservice you want to get your data from
	 * 		id:					The id of the resource you want to get the information from
	 * 		additionalID		Another id you can pass to the plugin. If set this id gets added
	 * 							to the link of each item.
	 * 		status:				The name of the container the status messages gets posted to
	 * 		articles:			The main container of the slider
	 * 		startPage:			If you want to set the initial shown page in the slider, use
	 * 							this parameter
	 * 		backgroundImage		Since we use an white container during loading of the data, you
	 * 							can specify an alternative background image which gets set after
	 * 							the data was loaded successfully
	 * 		slideWidth			The width of the whole slider and each page within the slider
	 * 		interactive			Determine whether the hovered article gets highlighted or not
	 * 		articleID			The oxid of the article the user is currently visiting. Used to highlight the
	 * 							article
	 * 
	 * 
	 * 	Usage:
	 * 
	 * 		js:
	 * 
	 * 			CATEGORY_ID = '[{$product->getMainCategoryId()}]';
	 *			ARTICLE_ID = '[{$product->oxarticles__oxid->value}]'
	 * 
	 * 			var options = 
	 *			{
	 *				url: "../../../shop/api/json/categoryarticles/",
	 * 				categoryID: CATEGORY_ID,
	 *				status: "#status",
	 * 				articles: "#articles",
	 *				startPage: 2,
	 *				backgroundImage: "img/background.gif",
	 *				slideWidth: 960,
	 * 				interactive: true,
	 * 				articleID: ARTICLE_ID
	 * 				
	 *			};
	 *
	 *			$( "#categoryarticles" ).categorynavigation( options );
	 * 
	 * 
	 * 		markup:
	 * 
	 * 			<div id="categoryarticles">
	 *				<div id="status"></div>
	 *				<div id="articles"></div>			
	 *				<div class="clear"><!-- --></div>		
	 *			</div>
	 * 
	 * 
	 * 		data:
	 * 
	 * 			[{
	 * 				"oxtitle":"Popcornmaschine PINK",
	 * 				"oxpic1":"http:\/\/localhost\/kittelberger\/webshop\/kittoys\/shop\/out\/pictures\/1\/2025_p1.jpg",
	 * 				"oxseourl":"http:\/\/localhost\/kittelberger\/webshop\/kittoys\/shop\/Service\/Popcornmaschine-PINK.html"
	 * 			},
	 * 			{
	 * 				"oxtitle":"Kuyichi Jeans Anna",
	 * 				...
	 * 			}]
	 *  
	 */
    $.fn.categorynavigation = function ( options )
    {
        return this.each( function()
        {
			var element = $( this );
            var slider = new Slider( this, options );
            slider.init();
        });
        
        
        
    };
})( jQuery );
