/*
** Photo Slide 1.0 05/15/2010
**  Author: Jesse Janzer, Copyright 2010
**   jjanzer@lanthera.net http://jjanzer.subculture.org
*/
jQuery.fn.slide = function(settings){
	var settings = jQuery.extend({
		'duration_transition' : 250, //the number of ms of the transition
		'duration_show' : 1250, //the number of ms to show the current image
		'seamless_loop' : true, //if true fakes a continous infinite loop of images
		'duration_drag' : 1000, //how many ms does the drag animation take?
		'pre_load_threshold' : 5 //if not false will start playing (when possible) after N many images have loaded
	},settings);
	
	return this.each(function(k,v){
		
		(function(){
			
			var el = $(v);
			el.addClass('slide_enabled');
			el.wrap('<div class="slide_window"></div>');
			var el_window = el.closest(".slide_window");
			var window_size = el_window.width();
			var el_holder = el.find('.slide_img_holder:first');
			var el_holder_width = el_holder.width();

			var img_cnt = el_holder.find('img').length;

			//el_holder.css({'right':window_size+'px'}); //push the images off the window
			el_holder.data('index.slide',0);
			el_holder.data('cnt.slide',img_cnt);
			
			var play = false;

			var click = {x:0,y:0};
			var drag = {x:0,y:0};
			var drag_delta = {x:0,y:0};
			
			var track_last = {x:0,y:0};
			
			var drag_interval = null;
			var drag_restart = null;
			var drag_last_time = null;
			
			var play_interval = null; //tracks the player interval so we can stop and start
			
			//each image stores it's width here indexed by the element
			// we use this to determine the current neareset offset
			var offsets = [];
			
			var running_x = 0;
			var running_y = 0;
			
			var loaded = 0;
			var drawn = 0; //used if the image has a defined width (the image may or may not be loaded);
			
			var current_middle = 1;
			var current_middle_max_right = null;
			var total_holder_width = null;
			
			var el_holders = [];
			
			var img_urls = [];
			
			//do we need to wait for the images to load before playing or not?
			var imgs_have_width = true;
			
			var threshold = 5; //how many images do we need to load before starting to play
			
			//we're going to rip the images src out and reinsert them using a preloader that forces the images to load in order
			var images = el_holder.find('img');
			
			var load_image = function(obj){
				//restore the image
				var tmp = $(images[loaded]);
				var slot = tmp.data('slot.slide');
				var src = tmp.data('src.slide');
				tmp.attr('src',src);
				if(el_holders && el_holders[0]){
					el_holders[0].find('img:eq('+slot+')').attr('src',src);
					el_holders[2].find('img:eq('+slot+')').attr('src',src);
				}
				
				tmp.data('loaded.slide',true);
				
				loaded += 1;
				
				if(settings.pre_load_threshold && settings.pre_load_threshold >= loaded){
					if(!play){
						play = true;
						play_slide();
					}
				}
				
				if(loaded == img_cnt){
					delete img_urls;
					if(!play){
						play = true;
						play_slide();
					}
				}
			};
			
			var move_offset = function(origins,offset,animate,duration,transition){
				for(var i=0;i<3;i++){
					SKEL.EFFECTS.Slide.stop(el_holders[i]);
					
					var move_to_right = origins[i]+offset;
					
					//console.log('moving',i,move_to_right);
					
					if(!animate){
						el_holders[i].css('right',move_to_right+'px');
					} else {
						var current_right = parseInt(el_holders[i].css('right'));
						SKEL.EFFECTS.Slide.animate(el_holders[i],'right',current_right+'px',move_to_right+'px',duration,transition);
					}
				}
			};
			
			var play_slide = function(){
				//this interval handles the automatic picture rotation
				if(play_interval){
					window.clearInterval(play_interval);
				}
				play_interval = window.setInterval(function(){
					if(!play){
						return false;
					}

					var current_el = el_holders[current_middle];
					var current_right = parseInt(current_el.css('right'));
					var current_img_index = 0;
					var offset = 0;

					for(var i=0;i<offsets.length;i++){
						if(offsets[i].offset_right == current_right){
							current_img_index = i+1;
						} else if(offsets[i].offset_right <= current_right){
							current_img_index = i;
							break;
						}
					}
					
					//make sure this image is loaded
					if(current_img_index != img_cnt && current_img_index>=loaded){
						return;
					}

					var origins = [];
					for(var i=0;i<3;i++){
						origins[i] = parseInt(el_holders[i].css('right'));
					}

					if(current_img_index >= img_cnt){
						//jump to the first img in the index
						var new_right = offsets[current_img_index-1];
						var old_right = current_right;
						var offset = new_right.offset_right - old_right - offsets[0].width;
					} else if (current_img_index == 0){
						var new_right = offsets[current_img_index];
						var old_right = current_right;

						var offset = -1 * offsets[img_cnt-1]['width'];
						
						var skipped_rotate = false;

						//we're at the end so rotate the right most cell to the left
						if(current_middle == 1){
														
							//quick check to verify that we're not going to rotate a cell that doesn't need to be rotated
							var cell_right = parseInt(el_holders[2].css('right'));
							
							if(cell_right + total_holder_width < 0){
								var new_right = parseInt(el_holders[0].css('right')) + total_holder_width;
								el_holders[2].css('right',new_right+'px');
								origins[2] = origins[0] + total_holder_width;
								current_middle = 0;
							} else {
								skipped_rotate = true;
							}
						} else if (current_middle == 0){
							var cell_right = parseInt(el_holders[1].css('right'));
							if(cell_right + total_holder_width < 0){
								var new_right = parseInt(el_holders[2].css('right')) - total_holder_width;
								el_holders[1].css('right',new_right+'px');
								origins[1] = origins[2] + total_holder_width;
								current_middle = 2;
							} else {
								skipped_rotate = true;
							}
						} else if (current_middle == 2){
							
							var cell_right = parseInt(el_holders[0].css('right'));
							
							if(cell_right + total_holder_width < 0){
								var new_right = parseInt(el_holders[1].css('right')) - total_holder_width;
								el_holders[0].css('right',new_right+'px');
								origins[0] = origins[1] + total_holder_width;
								current_middle = 1;
							} else {
								skipped_rotate = true;
							}
						}
						
						if(skipped_rotate){
							offset = new_right.offset_right - old_right;
						}				

					} else {
						var new_right = offsets[current_img_index];
						var old_right = current_right;
						var offset = new_right.offset_right - old_right;
					}

					move_offset(origins,offset,true,settings.duration_transition,SKEL.Transitions.quadIn);

				},settings.duration_show);
			};
			
			
			
			
			total_holder_width = 0;
			var position = null;
			var delta_x = null;
			var width = 0;
			var height = 0;
			
			var last_offset_left = el_holder_width;
			
			//abort the load
			images.each(function(kk,vv){
				var tmp = $(vv);
				tmp.data('loaded.slide',false);
				if(imgs_have_width && (width = tmp.outerWidth())>0){
					height = tmp.outerHeight();
					total_holder_width += width;
					
					//why are we guessing the positions? It's because the left isn't true at this point...
					
					position = tmp.position();
					delta_x = el_holder_width - last_offset_left;
					last_offset_left -= width;
					
					offsets[kk] = {
						'width': width,
						'height': height,
						'img': tmp,
						'left': last_offset_left,
						'offset_right': -1 * delta_x
					};
				} else {
					imgs_have_width = false;
				}
				
				var src = vv.src;
				img_urls.push(src);
				vv.src = '';
				tmp.data('slot.slide',kk);
				tmp.data('src.slide',src);
			});
			
			if(imgs_have_width){
				//we don't need to wait for all the images to load we can clone the holders and play when we're ready
				el_holder.css('width',total_holder_width+'px');
				
				//we also want to "clone" this element and lay 3 side by side, one to the left and one to the right, this will allow us to have an artificial "seamless" transition
				el_holders[0] = el_holder.clone(); //this will start to the left
				el_holders[1] = el_holder; //just reference this, this will start in the middle
				el_holders[2] = el_holder.clone(); //this will start to the right
				
				el_holders[0].css('right',total_holder_width+'px');
				el_holders[2].css('right',(-1*total_holder_width)+'px');
				
				current_middle_max_right = -1*total_holder_width;
				
				el_holder.before(el_holders[0]);
				el_holder.after(el_holders[2]);
			}
			
			SKEL.Image.preloadArray(img_urls,load_image);
			
			
			$(el_window).mousedown(function(ev){
				play = false;
				
				click = {
					x:ev.clientX,
					y:ev.clientY
				};
				
				//var old_right = parseInt(el_holder.css('right'));
				var old_top = parseInt(el_holder.css('top'));
				
				var date = new Date();
				var drag_current_time = date.getTime();
				
				var velocity = {x:0,y:0};
				
				track_last.x = click.x;
				track_last.y = click.y;
				
				var move_to_right = 0;
				
				var origins = [];
				origins[0] = parseInt(el_holders[0].css('right'));
				origins[1] = parseInt(el_holders[1].css('right'));
				origins[2] = parseInt(el_holders[2].css('right'));
				
				//when the user clicks and drags
				$(document).bind('mousemove.slide',function(ev){
					SKEL.EFFECTS.Slide.stop(el_holders[0]);
					SKEL.EFFECTS.Slide.stop(el_holders[1]);
					SKEL.EFFECTS.Slide.stop(el_holders[2]);
					
					drag = {x:ev.clientX,y:ev.clientY};
					drag_delta = {x:drag.x - click.x,y:drag.y - click.y};
					
					var offset = (-1*drag_delta.x);
					
					//do we need to rotate the holders?
					var center_position = (origins[current_middle]+offset);
					if(center_position < current_middle_max_right){
						//rotate the right cell to the left and make the current left cell the middle
						if(current_middle == 1){
							var new_right = parseInt(el_holders[0].css('right')) - total_holder_width;
							el_holders[2].css('right',new_right+'px');
							origins[2] = origins[0] + total_holder_width;
							current_middle = 0;
						} else if (current_middle == 0){
							var new_right = parseInt(el_holders[2].css('right')) - total_holder_width;
							el_holders[1].css('right',new_right+'px');
							origins[1] = origins[2] + total_holder_width;
							current_middle = 2;
						} else if (current_middle == 2){
							var new_right = parseInt(el_holders[1].css('right')) - total_holder_width;
							el_holders[0].css('right',new_right+'px');
							origins[0] = origins[1] + total_holder_width;
							current_middle = 1;
						}
					} else if (center_position > (current_middle_max_right + total_holder_width)){
						//rotate the left cell to the right and make the current right cell the middle
						if(current_middle == 1){
							var new_right = parseInt(el_holders[2].css('right'))-total_holder_width;
							el_holders[0].css('right',new_right+'px');
							origins[0] = origins[2] - total_holder_width;
							current_middle = 2;
						} else if (current_middle == 0){
							var new_right = parseInt(el_holders[1].css('right')) - total_holder_width;
							el_holders[2].css('right',new_right+'px');
							origins[2] = origins[1] - total_holder_width;
							current_middle = 1;
						} else if (current_middle == 2){
							var new_right = parseInt(el_holders[0].css('right')) - total_holder_width;
							el_holders[1].css('right',new_right+'px');
							origins[1] = origins[0] - total_holder_width;
							current_middle = 0;
						}
					}
					
					move_offset(origins,offset,false);
					
					return false;
				});
				
				$(document).bind('mouseup.slide',function(){
					//play = true;
					if(drag_interval){
						window.clearInterval(drag_interval);
					}
					
					if(drag_restart){
						window.clearTimeout(drag_restart);
					}
					
					//console.log('velocity',velocity);
					
					if(velocity.x != 0){
						var offset = parseInt(el_holder.css('right'));
						var distance = ((velocity.x*1000) ) /7
						var right = offset + distance;
						
						//determine the offset we'll be moving to
						
						//console.log('right',offset,right);
						//el_holder.stop().animate({'right':right+'px'},1000,"swing");
						var origins = [];
						for(var i=0;i<3;i++){
							origins[i] = parseInt(el_holders[i].css('right'));
						}
						move_offset(origins,(distance),true,settings.duration_drag,SKEL.Transitions.expoOut);
						
						//SKEL.EFFECTS.Slide.animate(el_holder,'right',offset+'px',right,1000,SKEL.Transitions.expoOut);
						
						//in the time it takes to drag + half the time of showing an image re-enable playing
						drag_restart = window.setTimeout(
							function(){
								play=true;
							}
							,settings.duration_drag+(settings.duration_show/2)
						);
					} else {
						play = true;
					}
					
					$(document).unbind('mousemove.slide');
					$(document).unbind('mouseup.slide');
				});
				
				//constantly recalculate our velocity
				drag_interval = window.setInterval(function(){
					var date = new Date();
					var drag_current_time = date.getTime();
					
					var delta_ms = drag_current_time-drag_last_time;
					
					var current_x = drag.x;
					var current_y = drag.y;
					
					var delta_x = track_last.x - current_x;
					var delta_y = track_last.y - current_y;
					
					var velocity_x = delta_x / delta_ms;
					var velocity_y = delta_y / delta_ms;
					
					if(velocity_x != 0){
						velocity.x = velocity_x;
					}
					if(velocity_y != 0){
						velocity.y = velocity_y;
					}
					
					drag_last_time = drag_current_time;
					track_last.x = current_x;
					track_last.y = current_y;
				},50);
				
				return false;
			});
		})();
		
		
	});
}
