/**
 * @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);
		if ($.support.waiAria) {
			obj.nextBtn.add(obj.prevBtn).add(obj.playPauseBtn)
				.each(function(){
					if($.nodeName(this, 'a')){
						$(this)
							.removeAttr('href')
							.attr({tabindex: '0'});
					}
				})
			;
		}
		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});
				
				if (o.addLiveRegion) {
					$('div.content-box', obj.element).attr({
						'aria-busy': 'true'
					});
				}
				
				$.each($.createUrlIndex.mmContent.types, function(name, mmHanlder){
					if(mmHanlder.filter(url, nextAnchor)){
						mmHanlder.load(url, nextAnchor, obj, function(url, width){
							
							var uiEvent = {oldAnchor: oldAnchor, index: index, opener: nextAnchor};
							uiEvent.content = obj.content;
							obj.options.getTextContent(nextAnchor, obj.content, obj);
							o.showContentAnim(obj, obj.content['multimedia-box'], e, uiEvent);
							obj._trigger('indexChange', e, uiEvent);
							obj.element.queue(function(){
								obj.element.removeClass('loading');
								obj.mask.removeClass('loading-mask');
								obj.element.dequeue();
							});
							if(obj.isPlaying){
								slideShowLoad(o.slideshowDelay);
							}
							if(o.addLiveRegion){
								$('div.content-box', obj.element).attr({'aria-live': 'polite', 'aria-busy': 'false'});
							}
							$.ui.SR.update();
						});
						return false;
					}
				});
				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;
		};
	};
	
	$.createUrlIndex.mmContent = {
		types: {},
		add: function(name, obj){
			this.types[name] = obj;
		}
	};
	
	var imgReg = /\.jpg|\.jpeg|\.gif|\.png/i;
	
	$.createUrlIndex.mmContent.add('img', {
		filter: function(url, opener){
			if(opener.is('.img, .image, .picture')){
				return true;
			}
			return (imgReg.test(url));
		},
		load: function(url, opener, ui, fn){
			var inst = ui.instance || ui;
			$.imgPreLoad.loadNow(url, 
				function loadImg(e){
					var imgWidth 	= this.width,
						jElm 		= $(this)
					;
					if(ui.extras){
						ui.extras.mm = jElm;
					}
					inst.content = {
						'multimedia-box': jElm
					};
					fn(url, imgWidth);
				}
			);
		}
	});
	
	$.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;
	};
	
	function addFollowScroll(overlay, ui){
		var o 	= ui.options,
			doc = $(document),
			timer
		;
		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);
				}
			});
		}
	}
		
	$.ui.cOverlay.posMethods.centerHorizontalView = function(overlay, e, extra, ui){
		var o 	= ui.options,
			doc = $(document),
			pos
		;
		
		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();
		addFollowScroll(overlay, ui);
		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.mm);
		});
		
		pos.top += doc.scrollTop();
		pos.left += doc.scrollLeft();
		
		dim.width = imgDim.width + pos.widthSubtraction;
		dim.height = imgDim.height + pos.heightSubtraction;
		if(extra.mm.css && extra.mm.attr && extra.mm[0] && !$.nodeName(extra.mm[0], 'object')){
			extra.mm.css(dim).attr(dim);
		}
		delete pos.widthSubtraction;
		delete pos.heightSubtraction;
		addFollowScroll(overlay, ui);
		return pos;
	};
	
	$.ui.cOverlay.posMethods.constrainHorizontalView = function(overlay, e, extra, ui){
		var o 	= ui.options,
			pos = $.ui.cOverlay.posMethods.constrainInsideView(overlay, e, extra, ui)
		;
		pos.top = $(document).scrollTop();
		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.mm){
					var inst 	= ui.instance, 
						url 	= ui.extras.opener.attr('href')
					;
					
					inst.mask.addClass('loading-mask').mask('show');
					
					
					$.each($.createUrlIndex.mmContent.types, function(name, mmHanlder){
						if(mmHanlder.filter(url, inst.currentOpener)){
							mmHanlder.load(url, inst.currentOpener, ui, function(url, width){
								
								inst.options.getTextContent(inst.currentOpener, inst.content, inst);
								
								inst.fillContent();
								
								inst.widthElement.css({
									width: inst.calcWidth(ui.extras.mm, width)
								});
								
								inst.stopShow = false;
								inst.updateIndex(url);
								
								inst.show(e, ui.extras);
								
								inst._trigger('indexChange', e, {oldAnchor: null, index: inst.currentIndex, opener: inst.currentOpener, content: inst.content});
								inst.mask.removeClass('loading-mask');
							});
							return false;
						}
					});
					
					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();
				$('div.content-box', ui.element).removeAttr('aria-live').removeAttr('aria-busy');
			})
			.cOverlay(opts);
		
		return this;
	};
	
	$.fn.showbox.defaults = {
		mask: true,
		maskOpts: {
			fadeInTime: 600
		},
		focusOnShow: 'h1.showbox-title',
		addRole: 'dialog',
		positionType: 'centerHorizontalView',
		followScroll: true,
		widthElementSel: '.content-box',
		structure: '<div class="showbox">' +
						'<div class="showbox-box">'+
							'<div class="showbox-head">'+
								'<h1 class="showbox-title"></h1>'+

							'</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,
		addLiveRegion: 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);
