/*
 * @author Marc Schuelper - www.schuelper.com
 * @version 0.1
 * @date December 20, 2009
 * based on jQuery infinitecarousel plugin
 * @author admin@catchmyfame.com - http://www.catchmyfame.com
 * @version 1.2.2
 * @date August 31, 2009
 * @category jQuery plugin
 * @copyright (c) 2009 admin@catchmyfame.com (www.catchmyfame.com)
 * @license CC Attribution-Share Alike 3.0 - http://creativecommons.org/licenses/by-sa/3.0/
 */

(function($){
	$.fn.extend({ 
		infiniteCarousel: function(options)
		{
			var defaults = 
			{
				transitionSpeed : 1500,
				displayTime : 6000,
				textholderHeight : .2,
				displayProgressBar : 1,
				displayThumbnails: 1,
				displayThumbnailNumbers: 1,
				displayThumbnailBackground: 1,
				displayCaption: 1,
				thumbnailWidth: '20px',
				thumbnailHeight: '20px',
				thumbnailFontSize: '.7em',
				galleryWidth:  0,
				galleryHeight:  0
			};
		var options = $.extend(defaults, options);
	
    		return this.each(function() {
    			var randID = Math.round(Math.random()*100000000);
				var o=options;
				var obj = $(this);
				var curr = 1;

				var numImages = $('img', obj).length; // Number of images
				if(!o.galleryWidth | !o.galleryHeight)
				{
					if($('img:first', obj).attr('longdesc'))
					{
						var firstImg = new Image();
						firstImg.src = $('img:first', obj).attr('longdesc')
						if(!o.galleryHeight)
							o.galleryHeight =firstImg.height;
						if(!o.galleryWidth)
							o.galleryWidth =firstImg.width;
					}
					else
					{
						if(!o.galleryHeight)
							o.galleryHeight =$('img:first', obj).height();
						if(!o.galleryWidth)
							o.galleryWidth =$('img:first', obj).width();
					}
				}
				
				var imgToShow = Math.ceil(o.galleryWidth/parseInt(o.thumbnailWidth));
				var autopilot = 1;
				
				//Wrap all images in a Div to get a consistent "picture" size
				$('img', obj).each(function(){ $(this).wrap('<div style="width:'+o.galleryWidth+'px;height:'+o.galleryHeight+';overflow:hidden;text-align:center;"></div>')});
				$('p', obj).hide(); // Hide any text paragraphs in the carousel
				$(obj).width(o.galleryWidth).height(o.galleryHeight);
			
			
				// Wrap Main-Image
				$(obj).children('ul').wrap('<div id="galleryWrapper'+randID+'" style="overflow:hidden;position:relative;height:'+o.galleryHeight+'px;border:1px solid #999;"></div>');
				// Build progress bar
				if(o.displayProgressBar)
				{
					$('#galleryWrapper'+randID).append('<div id="progress'+randID+'" style="position:absolute;bottom:0;background:#ccc;left:'+$(obj).css('paddingLeft')+'"></div>');
					$('#progress'+randID).width(o.galleryWidth).height(5).css('opacity','.5');
				}
			
				// Move last image and stick it on the front
				$(obj).css({'overflow':'hidden','position':'relative'});
				$('li:last', obj).prependTo($('ul', obj));
				$('ul', obj).css('left',-o.galleryWidth+'px');
				$('ul',obj).width(9999);

				$('ul',obj).css({'list-style':'none','margin':'0','padding':'0','position':'relative'});
				$('li',obj).css({'display':'inline','float':'left'});
			
				// Build textholder div thats as wide as the carousel and 20%-25% of the height
				// "textholderBox" contains the opaque background "textholder" and "textholderText" the non-opaque text
				$('#galleryWrapper'+randID).append('<div id="textholderBox'+randID+'" class="textholder" style="margin-bottom:'+-o.galleryHeight*o.textholderHeight+'px;left:'+$(obj).css('paddingLeft')+'"><div id="textholder'+randID+'"></div><div id="textholderText'+randID+'" class="textholderText"></div></div>');
				$('#textholderBox'+randID).hover(function(){$('#textholder'+randID).stop().animate({opacity:'0.8'},250)},function(){$('#textholder'+randID).stop().animate({opacity:'.5'},250)});
				var correctTHWidth = parseInt($('#textholderBox'+randID).css('paddingTop'));
				var correctTHHeight = parseInt($('#textholderBox'+randID).css('paddingRight'));
				$('#textholder'+randID).width(o.galleryWidth-(correctTHWidth * 2)).height((o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2)).css({'backgroundColor':'#FFF','opacity':'0.5'});
				$('#textholderText'+randID).width(o.galleryWidth-(correctTHWidth * 2)).height((o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2));
				showtext($('li:eq(1) p', obj).html());
			
				// Prev/next button(img) 
				html = '<div id="btn_rt'+randID+'" style="position:absolute;right:0;top:'+((o.galleryHeight/2)-15)+'px"><a href="javascript:void(0);"><img style="border:none;margin-right:2px" src="./javascript/images/rt.png" /></a></div>';
				html += '<div id="btn_lt'+randID+'" style="position:absolute;left:0;top:'+((o.galleryHeight/2)-15)+'px"><a href="javascript:void(0);"><img style="border:none;margin-left:2px" src="./javascript/images/lt.png" /></a></div>';
				$(obj).append(html);
			
				// Pause/play button(img)	
				html = '<a href="javascript:void(0);"><img id="pause_btn'+randID+'" src="./javascript/images/pause.png" style="position:absolute;top:3px;right:3px;border:none" alt="Pause" /></a>';
				html += '<a href="javascript:void(0);"><img id="play_btn'+randID+'" src="./javascript/images/play.png" style="position:absolute;top:3px;right:3px;border:none;display:none;" alt="Play" /></a>';
				$(obj).append(html);
				
				$('#pause_btn'+randID).css('opacity','.5').hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.5'},250)});
				$('#pause_btn'+randID).click(function(){changeAuto('deactivate');});
				$('#play_btn'+randID).css('opacity','.5').hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.5'},250)});
				$('#play_btn'+randID).click(function(){changeAuto('activate');});
				
				// Left and right arrow image button actions
				$('#btn_rt'+randID).css('opacity','.75').click(function(){
					autopilot = 0;
					$('#progress'+randID).stop().fadeOut();
					anim('next');
					setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
					clearTimeout(clearInt);
				}).hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.75'},250)});
				$('#btn_lt'+randID).css('opacity','.75').click(function(){
					autopilot = 0;
					$('#progress'+randID).stop().fadeOut();
					anim('prev');
					setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
					clearTimeout(clearInt);
				}).hover(function(){$(this).animate({opacity:'1'},250)},function(){$(this).animate({opacity:'.75'},250)});

				if(o.displayThumbnails)
				{
					// Build thumbnail viewer and thumbnail divs
					$(obj).css('height',(o.galleryHeight+parseInt(o.thumbnailHeight)+15)+'px').append('<div style="position:relative;overflow:hidden;text-align:left;margin-top:5px; padding-top:1px;border: 1px solid #999;height:'+(parseInt(o.thumbnailHeight)+5)+'px;width:'+o.galleryWidth+'px"><div id="thumbs'+randID+'" style="position:relative;height:'+o.thumbnailHeight+'px"></div></div>');
					$('#thumbs'+randID).width((numImages*(parseInt(o.thumbnailWidth)+8)+50));
					for(i=0;i<=numImages-1;i++)
					{
						thumb = $('img:eq('+(i+1)+')', obj).attr('src');
						$('#thumbs'+randID).append('<div class="thumb" id="thumb'+randID+'_'+(i+1)+'" style="cursor:pointer;background-image:url('+thumb+');display:inline;float:left;width:'+o.thumbnailWidth+';height:'+o.thumbnailHeight+';line-height:'+o.thumbnailHeight+';padding:0;overflow:hidden;text-align:center;border:2px solid #ccc;margin-right:4px;font-size:'+o.thumbnailFontSize+';font-family:Arial;color:#000;font-weight:bold;background-position:center center;">'+(i+1)+'</div>');
						if(i==0) 
						{
							$('#thumb'+randID+'_1').css({'border-color':'#ff0000'}).addClass('activeThumb'+randID);
							if($('img:eq(1)', obj).attr('longdesc'))
								$('img:eq(1)', obj).attr('src', $('img:eq(1)', obj).attr('longdesc'));
						}
						if($('img:eq('+(i+1)+')', obj).attr('longdesc'))
							$('img:eq('+(i+1)+')', obj).attr('rel', $('img:eq('+(i+1)+')', obj).attr('src'));
					}
					// Next two lines are a special case to handle the first list element which was originally the last
					thumb = $('img:first', obj).attr('src');
					$('#thumb'+randID+'_'+numImages).css({'background-image':'url('+thumb+')'});
					$('#thumbs'+randID+' div.thumb:not(:first)').css({'opacity':'.65'}); // makes all thumbs 65% opaque except the first one
					$('#thumbs'+randID+' div.thumb').hover(function(){$(this).stop().animate({'opacity':.99},150)},function(){if(curr!=this.id.split('_')[1]) $(this).stop().animate({'opacity':.65},250)}); // add hover to thumbs

					// Assign click handler for the thumbnails. Normally the format $('.thumb') would work but since it's outside of our object (obj) it would get called multiple times
					$('#thumbs'+randID+' div').bind('click', thumbclick); // We use bind instead of just plain click so that we can repeatedly remove and reattach the handler
				
					if(!o.displayThumbnailNumbers) $('#thumbs'+randID+' div').text('');
					if(!o.displayThumbnailBackground) $('#thumbs'+randID+' div').css({'background-image':'none'});
					afterAnim();
				}
				function thumbclick(event)
				{
					target_num = this.id.split('_'); // we want target_num[1]
					if(curr != target_num[1])
					{
						$('#thumb'+randID+'_'+curr).animate({'border-color':'#ccc'}, 250);
						$('#progress'+randID).stop().fadeOut();
						clearTimeout(clearInt);
						//alert(event.data.src+' '+this.id+' '+target_num[1]+' '+curr);
						$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
						autopilot = 0;
						setTimeout(function(){$('#play_btn'+randID).fadeIn(250);},o.transitionSpeed);
					}
					if(target_num[1] > curr)
					{
						diff = target_num[1] - curr;
						anim('next',diff);
					}
					if(target_num[1] < curr)
					{
						diff = curr - target_num[1];
						anim('prev', diff);
					}
				}

				function showtext(t)
				{
					// the text will always be the text of the second list item (if it exists)
					if(t != null)
					{
						$('#textholderText'+randID).html(t); 
						$('#textholderText'+randID).animate({opacity: 1},250);

						if(o.displayCaption == 1)
						{
							$('#textholderBox'+randID).animate({marginBottom:'0px'},500);// Raise textholder
							showminmax();
						}
						else if (o.displayCaption == 2)
						{
							$('#galleryWrapper'+randID).mouseover(function(){$('#textholderBox'+randID).stop().animate({marginBottom:'0px'},500);$('#textholder'+randID).stop().animate({opacity:'0.8'},500)});
							$('#galleryWrapper'+randID).mouseleave(function(){$('#textholderBox'+randID).stop().animate({marginBottom:(-o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2)+'px'},500);$('#textholder'+randID).stop().animate({opacity:'0.5'},500)});	
						}
					}
				}
				function showminmax()
				{
						if(!autopilot)
						{
							html = '<img style="position:absolute;top:2px;right:18px;display:none;cursor:pointer" src="./javascript/images/down.png" title="Minimize" alt="minimize" id="min" /><img style="position:absolute;top:2px;right:18px;display:none;cursor:pointer" src="./javascript/images/up.png" title="Maximize" alt="maximize" id="max" />';
							html += '<img style="position:absolute;top:2px;right:6px;display:none;cursor:pointer" src="./javascript/images/close.png" title="Close" alt="close" id="close" />';
							$('#textholderText'+randID).append(html);
							$('#min').fadeIn(250).click(function(){$('#textholderBox'+randID).animate({marginBottom:(-o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2)+24+'px'},500,function(){$("#min,#max").toggle();});});
							$('#max').click(function(){$('#textholderBox'+randID).animate({marginBottom:'0px'},500,function(){$("#min,#max").toggle();});});
							$('#close').fadeIn(250).click(function(){$('#textholderBox'+randID).animate({marginBottom:(-o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2)+'px'},500);});
						}
				}
				function borderpatrol(elid)
				{
					if(!elid)	elid = numImages;
					$('.activeThumb'+randID).css('border-color', '#ccc').animate({opacity: '0.65'},250).removeClass('activeThumb'+randID);
					var thumbW = parseInt(o.thumbnailWidth)+8;
					var leftPos = (parseInt(elid)-Math.round(imgToShow/2))*thumbW*(-1);
					if(leftPos < (numImages-imgToShow+1)*thumbW*(-1))	leftPos = (numImages-imgToShow+1)*thumbW*(-1);
					else if(leftPos > 0) leftPos = 0;
					$('#thumbs'+randID+'').animate({left:leftPos+'px'},o.transitionSpeed/2);
					$('#thumb'+randID+'_'+elid).css('border-color', '#f00').addClass('activeThumb'+randID);	
					setTimeout(function(){$('#thumb'+randID+'_'+elid).animate({opacity: '0.99'},300);},o.transitionSpeed/2);
					
				}
      			
				function anim(direction,dist)
				{
					if(!dist) dist = 1;
					$(document).unbind('keydown');
					// Fade left/right arrows out when transitioning
					$('#btn_rt'+randID).fadeOut(500);
					$('#btn_lt'+randID).fadeOut(500);
					
					// animate textholder out of frame
					$('#textholderBox'+randID).animate({marginBottom:(-o.galleryHeight*o.textholderHeight)-(correctTHHeight * 2)+'px'},500);
					$('#textholderText'+randID).animate({opacity: 0.001},500);

					//?? Fade out play/pause?
					$('#pause_btn'+randID).fadeOut(250);
					$('#play_btn'+randID).fadeOut(250);
					
					var lastSeenImg = $('img:eq(1)', obj);
														
					if(direction == "next")
					{
						if(curr==numImages) curr=0;
						if(dist>1)
						{
							borderpatrol((curr+dist));
							$('li:lt(2)', obj).clone().insertAfter($('li:last', obj));
							$('ul', obj).animate({left:-o.galleryWidth*(dist+1)},o.transitionSpeed,function(){
								$('li:lt(2)', obj).remove();
								for(j=1;j<=dist-2;j++)
								{
									$('li:first', obj).clone().insertAfter($('li:last', obj));
									$('li:first', obj).remove();
								}
								$('#play_btn'+randID).fadeIn(250);
								$(this).css({'left':-o.galleryWidth});
								curr = curr+dist;
								afterAnim();
							});
						}
						else
						{
							borderpatrol((curr+1));
							$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
							// Copy leftmost (first) li and insert it after the last li
							$('li:first', obj).clone().insertAfter($('li:last', obj));	
							// Update width and left position of ul and animate ul to the left
							$('ul', obj)
								.animate({left:-o.galleryWidth*2},o.transitionSpeed, "easeInOutCubic",function(){
									$('li:first', obj).remove();
									$('ul', obj).css('left',-o.galleryWidth+'px');
									if(autopilot) $('#pause_btn'+randID).fadeIn(250);
									if(autopilot)
									{
										$('#progress'+randID).width(o.galleryWidth).height(5);
										$('#progress'+randID).animate({'width':0},{duration: o.displayTime, easing: "linear"},function(){
											$('#pause_btn'+randID).fadeOut(50);
											setTimeout(function(){$('#pause_btn'+randID).fadeIn(250)},o.transitionSpeed)
										});
									}
									curr=curr+1;
									afterAnim();
								});
						}
						var imgToMax = $('img:eq('+(1+dist)+')', obj);
						if(imgToMax.attr('longdesc')) imgToMax.attr('src', imgToMax.attr('longdesc'));
					}
					if(direction == "prev")
					{
						if(dist>1)
						{
							borderpatrol((curr-dist));
							$('li:gt('+(numImages-(dist+1))+')', obj).clone().insertBefore($('li:first', obj));
							$('ul', obj).css({'left':(-o.galleryWidth*(dist+1))}).animate({left:-o.galleryWidth},o.transitionSpeed, "easeInOutCubic",function(){
								$('li:gt('+(numImages-1)+')', obj).remove();
								$('#play_btn'+randID).fadeIn(250);
								curr = curr - dist;
								afterAnim();
							});
						}
						else
						{
							borderpatrol((curr-1));
							$('#thumbs'+randID+' div').css({'cursor':'default'}).unbind('click'); // Unbind the thumbnail click event until the transition has ended
							// Copy rightmost (last) li and insert it after the first li
							$('li:last', obj).clone().insertBefore($('li:first', obj));
							// Update width and left position of ul and animate ul to the right
							$('ul', obj)
								.css('left',-o.galleryWidth*2+'px')
								.animate({left:-o.galleryWidth},o.transitionSpeed, "easeInOutCubic",function(){
									$('li:last', obj).remove();
									if(autopilot) $('#pause_btn'+randID).fadeIn(250);
									curr=curr-1;
									if(curr==0) curr=numImages;
									afterAnim();
								});
						}
						var imgToMax = $('img:eq(1)', obj);
						if(imgToMax.attr('longdesc')) imgToMax.attr('src', imgToMax.attr('longdesc'));
					}
					$('li:lt('+(dist+2)+')', obj).show();
					$('li:gt('+(dist+1)+')', obj).hide();
					//$('.thumb:lt('+(curr+imgToShow*2)+')', obj).show();
					//$('.thumb:gt('+(curr+imgToShow*2)+')', obj).hide();
					
				}
				
				function afterAnim (){
					inAnim = null;
					$('#btn_rt'+randID).fadeIn(500);
					$('#btn_lt'+randID).fadeIn(500);
					showtext($('li:eq(1) p', obj).html());
					var topImg = $('li:eq(1) img', obj);
					var tIWidth =  topImg.width();
					var tIHeight = topImg.height();
					var ar = tIWidth/tIHeight;
					if(tIHeight > o.galleryHeight & tIWidth > o.galleryWidth)
					{
						
						if(o.galleryWidth/o.galleryHeight >= ar){
							//topImg.animate({marginTop:'0px',marginLeft:((o.galleryWidth-o.galleryHeight*ar)/2)+'px', height: o.galleryHeight+'px', width: (o.galleryHeight*ar)+'px'},o.displayTime/6, "easeInOutSine");
							topImg.animate({marginLeft:'0px', height: o.galleryWidth/ar+'px', width: o.galleryWidth+'px'},o.displayTime/3, "easeInOutSine");
							topImg.animate({marginTop:(o.galleryHeight-o.galleryWidth/ar)+'px'},o.displayTime/3, "easeInOutSine");
							topImg.animate({marginTop:((o.galleryHeight-tIHeight)/2)+'px', marginLeft:((o.galleryWidth-tIWidth)/2)+'px', width:tIWidth, height:tIHeight},o.displayTime/6, "easeInOutSine");
						}
						else
						{
							topImg.animate({marginTop:((o.galleryHeight-o.galleryWidth/ar)/2)+'px',marginLeft:'0px', height: (o.galleryWidth/ar)+'px', width: o.galleryWidth+'px'},o.displayTime/6, "easeInOutSine");
							topImg.animate({marginTop:'0px', height: o.galleryHeight+'px', width: o.galleryHeight*ar+'px'},o.displayTime/3, "easeInOutSine");
							topImg.animate({marginLeft:(o.galleryWidth-o.galleryHeight*ar)+'px'},o.displayTime/3, "easeInOutSine");
							topImg.animate({marginTop:((o.galleryHeight-tIHeight)/2)+'px', marginLeft:((o.galleryWidth-tIWidth)/2)+'px', width:tIWidth, height:tIHeight},o.displayTime/6, "easeInOutSine");
						}
						//topImg.animate({top:(o.galleryHeight-tIHeight)+'px',left:+(o.galleryWidth-tIWidth)+'px'},o.displayTime/2, "easeInOutSine");
					}
					else
					{
						if(tIHeight > o.galleryHeight){
							//topImg.animate({marginTop: 0, marginLeft: ((o.galleryWidth-tIWidth)/2)+'px'},o.displayTime/8, "easeInOutSine");
							topImg.animate({marginTop:(o.galleryHeight-tIHeight)+'px'}, o.displayTime/4, "easeInOutSine");
							topImg.animate({marginTop:((o.galleryHeight-tIHeight)/2)+'px'}, o.displayTime/4, "easeInOutSine");
							topImg.animate({marginRight:0},o.displayTime/8, "easeInOutSine");
							topImg.animate({marginTop:'0px'}, o.displayTime/4, "easeInOutSine");	
						}
						if(tIWidth > o.galleryWidth){
							topImg.animate({marginLeft:(o.galleryWidth-tIWidth)+'px', marginTop: ((o.galleryHeight-tIHeight)/2)+'px'}, o.displayTime/4, "easeInOutSine");
							topImg.animate({marginLeft:'0px'}, o.displayTime*3/4, "easeInOutSine");	
						}
					}
					$('#thumbs'+randID+' div').bind('click', thumbclick).css({'cursor':'pointer'});
					$(document).bind('keydown', function(e){keynav(e)});
					$('img:gt('+(imgToShow/2)+')', obj).each(function(){ if($(this).attr('longdesc')) $(this).attr('src', $(this).attr('rel'));	});
					$('img:lt('+(imgToShow/2+1)+')', obj).each(function(){ if($(this).attr('longdesc')) $(this).attr('src', $(this).attr('longdesc'));	});
				}

				function keynav (e){
					if(e.keyCode == 37 | e.keyCode == 39){
						if(e.keyCode == 37) {
							anim('prev', 1);
      					}
						if(e.keyCode == 39) {
							anim('next', 1);
      					}
						changeAuto('deactivate');
					}
					if(e.keyCode == 38 | e.keyCode == 40){
						if(e.keyCode == 38) {
							o.displayTime = Math.round(o.displayTime*1.5);
      					}
						if(e.keyCode == 40) {
							o.displayTime = Math.round(o.displayTime/1.5);
      					}
						changeAuto('toggle');
						changeAuto('toggle');
					}
					if(e.keyCode == 32)
						changeAuto('toggle');
				}
				
				function changeAuto(act){
					if((!autopilot && act == 'toggle') | act == 'activate'){
						autopilot = 1;
						anim('next');
						$('#play_btn'+randID).hide();
						clearInt=setInterval(function(){anim('next');},o.displayTime+o.transitionSpeed);
						setTimeout(function(){$('#pause_btn'+randID).show();$('#progress'+randID).fadeIn().width(o.galleryWidth).height(5);},o.transitionSpeed);	
					}
					else if((autopilot && act == 'toggle') | act == 'deactivate'){
						autopilot = 0;
						$('#progress'+randID).stop().fadeOut();
						clearTimeout(clearInt);
						$('#pause_btn'+randID).fadeOut(250);
						$('#play_btn'+randID).fadeIn(250);
						showminmax();
					}
				}
				
				
				$(document).bind('keydown', function(e){keynav(e)});
				$('li:gt(2)', obj).hide();
				var clearInt = setInterval(function(){anim('next');},o.displayTime+o.transitionSpeed);
				$('#progress'+randID).animate({'width':0},{duration: o.displayTime+o.transitionSpeed, easing: "linear"},function(){
					$('#pause_btn'+randID).fadeOut(100);
					setTimeout(function(){$('#pause_btn'+randID).fadeIn(250)},o.transitionSpeed)
				});
  		});
    	}
	});
})(jQuery);
