/* 
works well with the interface 

- troubles with multiple clicks 
- pr/nx clicks during autoplay 

- autoplay builds up long queue / 
? possibly a difference in timings ?
? block next while animation's on?

-animation blocked, removes the bug with multiple click on prev/next

- should autoplay be going through prev and nextSlide methods? YES
 
- next iteration implements data store to hold index information and eliminate dependency on 



*/



(function($) {

    $.fn.carousel = function(options) {
	
		var defaults = {  
		            animation: 'fade',
					shift_by:300,
					speed:400,
					holdfor:2000,
					layout:'horizontal',
					direction:-1,
					autoplay:false,
					previous_btn:null,
					next_btn:null,
					listener:null,
					id:null,
					target:null
		}

		var options = $.extend(defaults, options); 
		var carousel = '';
		var source = '';
		var currentIndex = 0;
		var totalItems;
		var d = 0;
		var direction = options.direction;
		var timeout;
			
		// delay animation if autoplay
		if(options.autoplay){
			d = options.holdfor;
		}
		
		var is_in_motion = false;
		
		// new property height to autosize the carousel;
		var carousel_height = 0;
		var methods = {
			
			
			init : function(){
				
					
					//source and renaming lists
					
					
					if(options.id == null){	
						var id = $(this).attr('id');
						$(this).attr('id',id+'-datasrc').hide();	
						$(this).parent().append('<ul id="'+id+'" />');
						$('#'+id).fadeOut(0);
						source = $(this).children('li');
					}
					
					else{
						
						var id = options.id;
						$(this).hide();	
						$(options.target).append('<ul id="'+id+'" />');
						source = $(this);
					}
					
					totalItems = source.length;
					
					carousel  = $('#'+id);
					carousel.css({overflow:'hidden'});				
					
					
					//carousel_height = 500;


					$(window).load(function(){
						$(carousel).children('li').each(function(){
								$(carousel).css({'height':$(this).height()+'px'});
						});
						//$(carousel).css({visibility:'visible'}).fadeIn();
					})
					
					$(window).resize(function() {
							
							$(carousel).children('li').each(function(){
									$(carousel).css({'height':$(this).height()+'px'});
							});		
					});
					
					$(carousel).each(function(){
							$(carousel).css({'height':$(this).height()+'px'});
					});
					
					
					methods.appendSlide.call(this,0);

					carousel.bind('nextSlide',function(){
//						methods.clearAutoPlay.call(this);
						methods.nextSlide.call(this);
						
					});
					
					carousel.bind('previousSlide',function(){
//						methods.clearAutoPlay.call(this);
						methods.previousSlide.call(this);	
					});
					
					carousel.bind('updateIndex',function(e,ind){
						methods.updateIndex.call(this,ind);	
					});
					
					carousel.bind('displaySlide',function(e,ind){
						e.stopPropagation();
						methods.displaySlide.call(this,ind);	
					});
					
					carousel.bind('ajaxSlide',function(e,markup){
						e.stopPropagation();
						methods.addAjaxSlide.call(this,markup);
					});
					
					carousel.bind('stopAutoPlay',function(e){
						e.stopPropagation();
						methods.clearAutoPlay.call(this);
					});
					carousel.bind('restartAutoPlay',function(e){
						e.stopPropagation();
						methods.startAutoPlay.call(this);
					});
					
					if(typeof(options.listener) != undefined){}
					
					if(typeof(options.previous_btn) != undefined){
						$(options.previous_btn).click(function(){
							carousel.trigger('previousSlide');
						});
					}
					
					if(typeof(options.next_btn) != undefined){
						$(options.next_btn).click(function(){
							carousel.trigger('nextSlide');
						});
					}
					
					if(options.autoplay){
						timeout = setTimeout(function(){
							methods.nextSlide.call(this);							
							},options.holdfor+options.speed)
						
					}
					
					

				
							
							
			},
			updateIndex:function(ind){
				
				currentIndex=ind;
				
				
			},
			startAutoPlay:function(){
				options.autoplay = true;
				timeout = setTimeout(function(){
					methods.nextSlide.call(this);							
					},options.holdfor+options.speed);
			},
			clearAutoPlay:function(){
				
				options.autoplay = false;
				clearTimeout(timeout);
				
			},
			addAjaxSlide: function(markup){
				
				// find a slide to be cloned from source and attached to the output
			
				
				var i = carousel.children('li').length;				
				$(carousel).append('<li></li>');
				var slideLI = $(carousel).children('li:last-child');
				
				if(options.layout == 'vertical')
					$(slideLI).append(markup).css({top:direction*i*options.shift_by}).show().data('index',i);
				else
					$(slideLI).append(markup).css({left:direction*i*options.shift_by}).show().data('index',i);
			
					
				methods.dispatch.call(this,'onSlideReady');
				
				
			},
			appendSlide : function(index){
				
				// find a slide to be cloned from source and attached to the output
				var slide = source.get(index);
			


				var i = carousel.children('li').length;	
				var alpha = 0;
				if(i==0){alpha=1}
				
				$(carousel).append('<li style="position:absolute;"></li>');
			//	console.log('appendSlide')	
				var slideLI = $(carousel).children('li:last-child');
			//	console.log('appendSlide'+$(carousel).children('li:last-child'))	
				if(options.layout == 'vertical')
					$(slideLI).append($(slide).clone(true).show()).css({top:direction*i*options.shift_by}).show().data('index',i);
				else if(options.layout == 'horizontal')
					$(slideLI).append($(slide).clone(true).show()).css({left:direction*i*options.shift_by}).show().data('index',i);
				else if(options.layout == 'alpha'){
					//alert($(slide))
					var s= '<li class="'+$(slide).attr('class')+'">'+$(slide).html()+'</li>';
					$(s).show();
					$(slideLI).append(s).css({opacity:alpha}).show().data('index',i);
					
				}
				
				
				
					
					$('img',slideLI).load(function(){
							$(carousel).fadeIn(400);
								methods.dispatch.call(this,'onCarouselReady');
							})/**/
					
				
				/*	carousel_height = $(slideLI).height();

										
								$('img',slideLI).load(function(){
									
									if(carousel_height<$(this).parent().height()){
										carousel_height = $(this).parent().height();
									//	console.log(carousel_height);
									}
									$(carousel).css({'height':carousel_height+'px'});
								})	*/
				
				
				methods.dispatch.call(this,'onSlideReady');
			},
			
			// gets Slide from actual carousel
			getSlide : function(index){
				return $(carousel).children('li').get(index);
			},
			
			updateSlides : function(){
				
				$(carousel).find('li:first-child').remove();
			
				
			},
			
			nextSlide: function(){
					
				if(is_in_motion && !options.autoplay)
					return;
					
					currentIndex++;
					
					//$('#debug').html('totalItems'+totalItems);
					direction = options.direction;
					
				
					
					if(currentIndex>totalItems-1){
							currentIndex = 0;
							//methods.appendSlide.call(this,0);
					}

					
					methods.moveSlides.call(this);
					
					if(options.autoplay){

					timeout = setTimeout(function(){
					
						methods.nextSlide.call(this);
					//	$('#debug').html('timeout'+currentIndex);	
						
					},options.holdfor+options.speed)
						
						
					}
					
			},
			previousSlide:function(){
				
				if(is_in_motion)
					return;
					
				currentIndex--;	
				direction = (-1)*options.direction;
				
							
				if(currentIndex<0){
					currentIndex = totalItems-1;
						//methods.appendSlide.call(this,0);
				}
				//methods.appendSlide.call(this,currentIndex);
				methods.moveSlides.call(this);
				
			},
			
			displaySlide:function(ind){
				
				
				if(is_in_motion)
					return;
				
				/*
					if(ind > currentIndex)
									direction = (-1)*options.direction;
									else
									direction = options.direction;*/
				


					currentIndex=ind;	

					methods.moveSlides.call(this);	
				
			},
			
			moveSlides	: function(){
			
			is_in_motion = true;
			methods.appendSlide.call(this,currentIndex);
				
				
				
				$(carousel).children('li').each(function(){
						var i = $(this).index();
						//$('#debug').html('currentIndex'+currentIndex);
							
							
						if(options.layout == 'vertical'){
							$(this).animate({
								'top':(direction*i*options.shift_by) - (direction*options.shift_by) +'px'},
								 	options.speed, function() {
										// do it only once:
										if(i==0){
											$(this).remove();
											is_in_motion = false;
											methods.dispatch.call(this,'onTransitionComplete');
										}
								})
						}
						
						else if(options.layout == 'horizontal'){
							$(this).animate({
				    			'left':(direction*i*options.shift_by) - (direction*options.shift_by) +'px'}, 
								options.speed, 
								function() {
										// do it only once:
										if(i==0){
											$(this).remove();
											is_in_motion = false;
											methods.dispatch.call(this,'onTransitionComplete');
											
										}
								})
						}
						
						else if(options.layout == 'alpha'){
							if(i==0){
								$(this).animate({
									'opacity': 0}, 
									options.speed,
									function() {
										$(this).remove();
										is_in_motion = false;
										methods.dispatch.call(this,'onTransitionComplete');
										
									});
							}
							else{
								$(this).animate({
					    			'opacity': 1}, 
									options.speed)
							}
						}
				});
			},
			
			dispatch	: function(ev){
				
				$(options.listener).trigger(ev,currentIndex);
			}
						
			
		}; // end of methods
				
		methods.init.call(this);
		
			
				
		
	
}
})(jQuery);







