/**
 * @author alexander.farkas
 */
(function($){
	// helper für createUrlIndex
	var controlState = {};
	$.each({disable: ['-1', 'true', 'addClass'], enable: ['0', 'false', 'removeClass']}, function(name, sets){
		controlState[name] = function(){
			var jElm = $(this);
			if(!jElm.is('span, div')){
				jElm.attr({tabindex: sets[0], 'aria-disabled': sets[1]});
			}
			jElm[sets[2]]('ui-disabled');
		};
	});
		
	$.createUrlIndex = function(anchors, obj){
		var o = obj.options;
		obj.uniqueUrls = [];
		obj.uniqueOpeners = [];
		anchors.each(function(){
			var url = $(this).attr('href');
			
			if($.inArray(url, obj.uniqueUrls) === -1){
				obj.uniqueUrls.push(url);
				obj.uniqueOpeners.push(this);
			}
			
		});
		
		obj.nextBtn = $('.next', obj.element);
		obj.prevBtn = $('.prev', obj.element);
		obj.playPauseBtn = $('.play-pause', obj.element);
		
		obj.currentIndexDisplay = $('.current-index', obj.element).html('1');
		obj.lengthDisplay = $('.item-length', obj.element).html(obj.uniqueUrls.length);
		
		obj.play = function(delay, playAgain){
			if(obj.isPlaying){return;}
			obj.isPlaying = true;
			obj.playPauseBtn.addClass('ui-isplaying').html(o.pauseText);
			if(o.pauseTitle){
				obj.playPauseBtn.attr({
					title: o.pauseTitle
				});
			}
			slideShowLoad((delay) ? o.slideshowDelay : 0, (playAgain !== undefined) ? playAgain : true);
		};
		
		obj.pause = function(){
			if(!obj.isPlaying){return;}
			obj.isPlaying = false;
			obj.playPauseBtn.addClass('ui-isplaying').html(o.playText);
			if(o.playTitle){
				obj.playPauseBtn.attr({
					title: o.playTitle
				});
			} 
			clearTimeout(obj.slideshowTimer);
		};
		
		obj.playPauseToggle = function(time, playAgain){
			obj[(obj.isPlaying) ? 'pause' : 'play'](time, playAgain);
			return false;
		};
		
		
		
		obj.isPlaying = false;
		
		if(obj.uniqueUrls.length > 1){
			
			obj.nextBtn.bind('ariaclick', function(e){
				obj.loadNext(e);
				return false;
			});
			
			obj.prevBtn.bind('ariaclick', function(e){
				obj.loadPrev(e);
				return false;
			});
			
			obj.playPauseBtn.bind('ariaclick', function(){
				obj.playPauseToggle(undefined, true);
				return false;
			});
			
			if(o.addKeyNav){
				obj.element.bind('keydown', function(e){
					var prevent; 
					
					switch(e.keyCode) {
						case $.ui.keyCode.LEFT:
							prevent = obj.loadPrev(e);
							break;
						case $.ui.keyCode.RIGHT:
							prevent = obj.loadNext(e);
							break;
						case $.ui.keyCode.SPACE:
							obj.playPauseToggle();
							break;
					}
					return prevent;
				});
			}
			
		} else {
			if(o.controlsWrapper){
				$(o.controlsWrapper, obj.element).hide();
			}
			obj.prevBtn.hide();
			obj.nextBtn.hide();
			obj.playPauseBtn.hide();
		}
		
		function slideShowLoad(time, playAgain){
			clearTimeout(obj.slideshowTimer);
			obj.slideshowTimer = setTimeout(function(){
				if(!obj.loadNext({type: 'slideshow'})){
					if(o.carousel || playAgain){
						obj.loadIndex(0, {type: 'slideshow'});
					} else {
						obj.pause();
					}
				}
			}, time || 0);
		}
		
		
		obj.uniqueOpeners = $(obj.uniqueOpeners);
		
		obj.updateIndex = function(url){
			var extendUI = {
				disable: $([]),
				enabled: $([])
			};
			
			obj.currentUrl = url;
			obj.currentIndex = $.inArray(url, obj.uniqueUrls);
			obj.currentAnchor = obj.uniqueOpeners.filter(':eq('+ obj.currentIndex +')');
			
			obj.currentIndexDisplay.html(String( obj.currentIndex + 1 ));
			
			
			
			if(obj.currentIndex === 0){
				if(!o.carousel){
					extendUI.disable = obj.prevBtn.each(controlState.disable);
				}
				obj._trigger('indexStartEndReachedChange', {type: 'indexStartReached'}, obj.ui(extendUI));
			} else if(obj.prevBtn.is('.ui-disabled')){
				extendUI.enable = obj.prevBtn.each(controlState.enable);
				obj._trigger('indexStartEndReachedChange', {type: 'indexStartReachedChanged'}, obj.ui(extendUI));
			}
			if(obj.uniqueUrls.length <= obj.currentIndex + 1){
				if(!o.carousel){
					obj.pause();
					extendUI.disable = obj.nextBtn.each(controlState.disable);
				}
				obj._trigger('indexStartEndReachedChange', {type: 'indexEndReached'}, obj.ui(extendUI));
			} else if(obj.nextBtn.is('.ui-disabled')){
				extendUI.enable = obj.nextBtn.each(controlState.enable);
				obj._trigger('indexStartEndReachedChange', {type: 'indexEndReachedChanged'}, obj.ui(extendUI));
			}
		};
		
		obj.loadIndex = function(index, e){
			if(index === obj.currentIndex || index === -1){return false;}
			var nextAnchor 	= obj.uniqueOpeners.filter(':eq('+ index+ ')'),
				oldAnchor 	= obj.currentAnchor,
				url
			;
			
			if(nextAnchor[0]){
				url = nextAnchor.attr('href');
				e = e || {type: 'loadIndex'};
				obj.updateIndex(url);
				obj.element.addClass('loading');
				obj.mask.addClass('loading-mask');
				o.hideContentAnim(obj, e, {oldAnchor: oldAnchor, index: index, opener: nextAnchor, content: obj.content});
				$.imgPreLoad.loadNow(url, function(){
					var uiEvent = {oldAnchor: oldAnchor, index: index, opener: nextAnchor, content: obj.content};
					obj.content = {
						'multimedia-box': $(this)
					};
					obj.options.getTextContent(nextAnchor, obj.content, obj);
					o.showContentAnim(obj, obj.content['multimedia-box'], e, uiEvent);
					obj._trigger('imageChange', e, uiEvent);
					obj.element.queue(function(){
						obj.element.removeClass('loading');
						obj.mask.removeClass('loading-mask');
						obj.element.dequeue();
					});
					if(obj.isPlaying){
						slideShowLoad(o.slideshowDelay);
					}
					$.ui.SR.update();
				});
				return true;
			}
			return false;
		};
		
		obj.loadNext = function(e){
			var retVal = obj.loadIndex(obj.currentIndex + 1, e);
			if(retVal === false && o.carousel){
				retVal = obj.loadIndex(0, e);
			}
			return retVal;
		};
		
		obj.loadPrev = function(e){
			var retVal = obj.loadIndex(obj.currentIndex - 1, e);
			if(retVal === false && o.carousel){
				retVal = obj.loadIndex(obj.uniqueOpeners.length - 1, e);
			}
			return retVal;
		};
	};

	
	$.addOuterDimensions = function(jElm, dim, dir){
		var adds = (dir === 'height') ? ['Top', 'Bottom'] : ['Left', 'Right'];
		$.each(['padding', 'border', 'margin'], function(i, css){
			if(css !== 'border'){
				dim += parseInt( jElm.css(css + adds[0]), 10) || 0;
				dim += parseInt( jElm.css(css + adds[1]), 10) || 0;
			} else {
				dim += parseInt( jElm.css(css + adds[0] +'Width'), 10) || 0;
				dim += parseInt( jElm.css(css + adds[1] +'Width'), 10) || 0;
			}
		});
		return dim;
	};
		
	$.ui.cOverlay.posMethods.centerHorizontalView = function(overlay, e, extra, ui){
		var o 	= ui.options,
			doc = $(document),
			pos, timer
		;
		
		if(!$.objScale){
			setTimeout(function(){
				throw('please install the objScale plugin');
			},0);
			return {};
		}
		
		pos = $.objScale.centerObjTo(overlay, $(window), o.positionOpts);
		pos.top = doc.scrollTop();
		
		if(isFinite(o.marginTop)){
			pos.top += o.marginTop;
		}
		
		pos.left += doc.scrollLeft();
		if(o.followScroll){
			$(window).bind('scroll.'+ this.id +' resize.'+ this.id, function(e){
				if($(window).height() > overlay.height()){
					clearTimeout(timer);
					timer = setTimeout(function(){
						overlay.animate({top: doc.scrollTop()});
					}, 400);
				}
			});
		}
		return pos;
	};
	
	$.ui.cOverlay.posMethods.constrainInsideView = function(overlay, e, extra, ui){
		var o 			= ui.options,
			doc 		= $(document),
			imgDim		= {},
			dim 		= {},
			pos
		;
		
		if(!$.objScale){
			setTimeout(function(){
				throw('please install the objScale plugin');
			},0);
			return {};
		}
		
		pos = $.objScale.constrainObjTo(overlay, $(window), o.positionOpts);
		
		$.swap(overlay[0], { position: "absolute", visibility: "hidden", display:"block" }, function(){
			imgDim = $.objScale.getDim(extra.img);
		});
		
		pos.top += doc.scrollTop();
		pos.left += doc.scrollLeft();
		
		dim.width = imgDim.width + pos.widthSubtraction;
		dim.height = imgDim.height + pos.heightSubtraction;
		extra.img.css(dim).attr(dim);
		delete pos.widthSubtraction;
		delete pos.heightSubtraction;
		return pos;
	};
	
	$.ui.cOverlay.posMethods.constrainHorizontalView = function(overlay, e, extra, ui){
		var o 	= ui.options,
			pos = $.ui.cOverlay.posMethods.constrainInsideView(overlay, e, extra, ui)
		;
		delete pos.top;
		return pos;
	};
	$.fn.showbox = function(opts){
		opts = $.extend({}, $.fn.showbox.defaults, opts);
		opts.openerSel = this;
		$(opts.structure)
			.appendTo('body')
			.bind('cOverlayinit', function(e, ui){
				var inst 	= ui.instance,
					o 		= inst.options
				;
				
				$.createUrlIndex(inst.openers, inst);
				
				inst.widthElement = (inst.element.is(o.widthElementSel)) ? inst.element : $(inst.options.widthElementSel, inst.element);
				
				inst.calcWidth = function(img, initialWidth){
					var width 	= initialWidth || img[0].width,
						elem 	= img
					;
					
					while(!elem.is(o.widthElementSel) && elem[0]){
						width = $.addOuterDimensions(elem, width, 'width');
						elem = elem.parent();
					}
					return width;
				};
			})
			.bind('cOverlaybeforeShow', function(e, ui){
				if(!ui.extras.img){
					var inst 	= ui.instance, 
						url 	= ui.extras.opener.attr('href')
					;
					
					inst.mask.addClass('loading-mask').mask('show');
					
					$.imgPreLoad.loadNow(url, function(e){
						var imgWidth = this.width;
						ui.extras.img = $(this);
						
						inst.stopShow = false;
						
						inst.content = {
							'multimedia-box': ui.extras.img
						};
						
						opts.getTextContent(inst.currentOpener, inst.content, inst);
						
											
						inst.fillContent();
						
						inst.widthElement.css({
							width: inst.calcWidth(ui.extras.img, imgWidth)
						});
						
						
						inst.updateIndex(url);
						
						inst.show(e, ui.extras);
						
						
						inst._trigger('imageChange', e, {oldAnchor: null, index: inst.currentIndex, opener: inst.currentOpener, content: inst.content});
						inst.mask.removeClass('loading-mask');
					});
					inst.stopShow = true;
				}
			})
			.bind('cOverlayshow', function(e, ui){
				var inst = ui.instance;
				if(inst.options.slideShowAutostart){
					inst.play(true);
				}
			})
			.bind('cOverlayhide', function(e, ui){
				ui.instance.pause();
			})
			.cOverlay(opts);
		
		return this;
	};
	
	$.fn.showbox.defaults = {
		mask: true,
		maskOpts: {
			fadeInTime: 600
		},
		a11yMode: 'specialdialog',
		focusOnShow: 'h1.showbox-title',
		//labelledbySel: 'h1.showbox-title',
		//describedbySel: 'div.content-box',
		positionType: 'centerHorizontalView',
		followScroll: true,
		widthElementSel: '.content-box',
		structure: '<div class="showbox">' +
						'<div class="showbox-box">'+
							'<div class="showbox-head">'+
								'<h1 class="showbox-title"></h1>'+
								'<span class="showbox-toolbar">'+ 
									'<a role="button" class="prev" href="#" /> <a role="button" class="next" href="#" />'+
									' <a class="play-pause" role="button" href="#" />'+ 
									' <span class="current-index" /> / <span class="item-length" />'+
								'</span>'+
							'</div>'+
							'<div class="content-box"><div class="multimedia-box"></div><div class="text-content"></div></div>'+
							' <a role="button" class="close-button" href="#"></a>'+
						'</div>'+
					'</div>',
		getTextContent: function(opener, content, ui){
			content['text-content'] = opener.attr('title');
		},
		addKeyNav: true,
		showContentAnim: function(ui, img, e, extras){
			var contentBox 	= $('div.content-box', ui.element);
			
			contentBox
				.queue(function(){
					ui.fillContent();
					
					ui.widthElement.css({width: ui.calcWidth(img)});
					
					contentBox.fadeTo(300, 1);
					contentBox.dequeue();
				});
		},
		hideContentAnim: function(ui){
			var contentBox = $('div.content-box', ui.element);
			contentBox.fadeTo(300, 0);
		},
		controlsWrapper: '.showbox-toolbar', // versteckt toolar wenn nur ein Bild - optionen: false 
		slideShowAutostart: false,
		slideshowDelay: 4000,
		playTitle: '',  // title text play button 
		playText: 'play',
		pauseText: 'pause',
		pauseTitle: '' // title text Pause button 
	};
})(jQuery);
