/*
 * jQuery Audio Category Finder 1.0
 *
 * By Manuel Boy (http://www.polargold.de)
 * Copyright (c) 2010 polargold
*/
(function($){
	
	$.fn.olympusAudioCategoryFinder = function(options) {
		
		// base settings
		var settings = {
			animationDuration: 500,
			layerAnimationDuration: 1000,
			layerMarginTop: 80,
			layerHeightInactive: 20
		};

		var log = function(msg) {
			if (typeof console == "object") {
				console.log(msg);
			}
		}
		
		return this.each(function() {

			// handle plugin settings
			if (options) { 
				$.extend(settings, options);
			}
			
			// get main ui elements
			var categoryFinder = $(this);
			var container = $('.category-finder-app', categoryFinder);
			var wrapper = $('.category-finder-app-wrapper', container);
			
			// we need a small browser detection
			if($.browser.msie) {
				$(categoryFinder).addClass('ie');
				if($.browser.version.substr(0,1) == '6') {
					$(categoryFinder).addClass('ie6');
				}
				if($.browser.version.substr(0,1) == '7') {
					$(categoryFinder).addClass('ie7');
				}
			}
			
			// possible directions
			var DIR_LTR = 1;
			var DIR_RTL = 2;
			
			var navigationEnabled = true;
			var layerHandleVisible = false;
			var layerVisible = false;
			var hasChangedBefore = false;
			
			// build basic ui
			var initialStage = $('.category-finder-app-stage:first', container);
			var numberOfStages = $('.category-finder-app-stage', container).length;
			var wrapperWidth = numberOfStages * $(container).width();
			$(wrapper).css('width', '' + wrapperWidth + 'px');
			var layerHandle = $('<div class="category-finder-app-layer-handle-main"><div class="category-finder-app-layer-label"><h4><span></span></h4></div><div class="category-finder-app-layer-handle-content"></div></div>').prependTo(categoryFinder).hide();
			
			$('.category-finder-app-stage', container).each(function() {
				$(this).attr('data-order-index', $(this).index());
			});
			
			// we need to store the current stage
			var currentStage = $(initialStage);
			
			// handle events: navigation
			var navigateTo = function(elem) {
				hasChangedBefore = true;
				var link = $(elem);
				if(navigationEnabled && !layerVisible) {
					navigationEnabled = false;
					// handle link via history
					var linkValue = $(link).attr('href').replace(/^#/, '');
					if($.browser.msie && ($.browser.version.substr(0,1) == '6' || $.browser.version.substr(0,1) == '7')) { // ie adds url to link href...?
						var oc = linkValue.indexOf('#');
						if(oc != -1) {
							linkValue = linkValue.substr((oc + 1), (linkValue.length - oc - 1));
						}
					}
					$.address.value(linkValue);
				}
			}
			$('.category-finder-app-stage a', container).live('click', function(evt) {
				if($(this).is('.external') === false) {
					navigateTo($(this));
					evt.preventDefault();
				}
			});
			$('.category-finder-app-stage li, .category-finder-app-entry-group', container).live('click', function(evt) {
				var link = $('a:first', this);
				if($(link).is('.external') === false) {
					navigateTo($(link));
					evt.preventDefault();
				} else {
					if($(link).is('[target=_blank]')) {
						var windowTitle = 'win' + Math.round(Math.random() * 1000);
						window.open($(link).attr('href'), windowTitle);
					} else {
						document.location.href = $(link).attr('href');
					}
				}
			});
			
			// handle events: layer container
			$(layerHandle).bind('updateLabel', function(event) {
				var layer = $('#' + $(currentStage).attr('rel') + ':first', container);
				var newLabel = $(layer).find('.category-finder-app-layer-handle h4').clone();
				$('.category-finder-app-layer-label', layerHandle).html(newLabel);
			});
			$(layerHandle).bind('showLayer', function(event, callback) {
				if(!$(layerHandle).is('.visible')) {
					var contentArea = $(layerHandle).find('.category-finder-app-layer-handle-content');
					$('.category-finder-app-stage-container', currentStage).fadeOut('fast', function() {
						var newHeight = $(container).height() - settings.layerMarginTop;
						var newOffset = settings.layerMarginTop;						
						$(layerHandle).addClass('loading').animate({
							'margin-top': newOffset,
							'height': newHeight
						}, settings.layerAnimationDuration, function() {
							var layer = $('#' + $(currentStage).attr('rel') + ':first', container);
							$(contentArea).empty().hide();
							var layerContent = $('.category-finder-app-layer-content', layer).clone();
							$(layerContent).appendTo(contentArea);
							// preload bg sprite
							var url_match = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\-\.]*(\?\S+)?)?)?/;
							var urlMatches = ($(layerContent).find('ul li:first').css('background-image')).match(url_match);
							var imgUrl = urlMatches[0];
							var tmpImg = new Image();
							$(tmpImg).load(function () {
								// fade in content
								$(contentArea).fadeIn('slow', function() {
									$(layerHandle).removeClass('loading');
									if(callback != null && typeof callback == 'function') {
										callback();
									}
								});	
								layerVisible = true;
								var labelTextOn = $('.category-finder-app-layer-label h4', layerHandle).text();
								var labelTextOff = $('.category-finder-app-layer-label h4', layerHandle).attr('rel');
								$('.category-finder-app-layer-label h4', layerHandle).html('<span>' + labelTextOff + '</span>').attr('rel', labelTextOn);
							}).error(function () {
							}).attr('src', imgUrl);
						})
						$(layerHandle).addClass('visible');
					});
				}
			});
			$(layerHandle).bind('hideLayer', function(event, callback) {
				if($(layerHandle).is('.visible')) {
					var contentArea = $(layerHandle).find('.category-finder-app-layer-handle-content');
					$(contentArea).fadeOut('fast', function() {
						var newHeight = settings.layerHeightInactive;
						var newOffset = $(container).height() - settings.layerHeightInactive;
						$(layerHandle).animate({
							'margin-top': newOffset,
							'height': newHeight
						}, settings.layerAnimationDuration, function() {
							$(contentArea).fadeOut('fast', function() {
								$(contentArea).empty().show();
								$(layerHandle).removeClass('visible');
								$('.category-finder-app-stage-container', currentStage).fadeIn('fast', function() {});
								layerVisible = false;
								var labelTextOff = $('.category-finder-app-layer-label h4', layerHandle).text();
								var labelTextOn = $('.category-finder-app-layer-label h4', layerHandle).attr('rel');
								$('.category-finder-app-layer-label h4', layerHandle).html('<span>' + labelTextOn + '</span>').attr('rel', labelTextOff);
								if(callback != null && typeof callback == 'function') {
									callback();
								}
							});
						})
					});
				}
			});
			
			$('.category-finder-app-layer-label', layerHandle).bind('click', function() {
				if($(layerHandle).is('.visible')) {
					$(layerHandle).trigger('hideLayer');
				} else {
					$(layerHandle).trigger('showLayer');
				}				
			});
			
			// handle location change
			$.address.change(function(event) {
				
				var targetID = (event.value).replace(/^\//, '');
				if(targetID == '') {
					targetID = ($(initialStage).attr('id')).replace(/^\//, '');
				}
				var target = $(container).find('#' + targetID + ':first');
				if($(target).is('.category-finder-app-stage')) { // validate if target is a stage
				
					// get direction of animation
					var direction = ($(target).attr('data-order-index') > $(currentStage).attr('data-order-index')) ? DIR_RTL : DIR_LTR;
					
					// rebuild stage sequence
					var newTarget = null;
					var scrollDuration = settings.animationDuration;
					
					if(hasChangedBefore) {
						newTarget = target;
					} else {
						newTarget = target;
						scrollDuration = 0;
						hasChangedBefore = true;
					}
					
					var scrollToStage = function() {
						// scroll to new target
						$(container).scrollTo(newTarget, scrollDuration, {
							axis: 'x',
							onAfter: function() {
								currentStage = target;
								navigationEnabled = true;
								// manage the layer handle
								if($(currentStage).is('.category-finder-app-has-layer')) {
									if(!layerHandleVisible) {
										// handle is hidden, so fade it in 
										$(layerHandle).fadeIn('fast');
										layerHandleVisible = true;
									}
									$(layerHandle).trigger('updateLabel');
								} else {
									if(layerHandleVisible) {
										// handle is visible but not longer needed, so fade it out
										layerHandleVisible = false;
										$(layerHandle).fadeOut('fast');
									}
								}
							}
						});
					}
					
					if($(layerHandle).is('.visible')) {
						$(layerHandle).trigger('hideLayer', function() {
							scrollToStage();
						});	
					} else {
						scrollToStage();
					}
				}
				
			});
			
		});
	};
})(jQuery);
