/*The easing code was provided by George Smith. Please check out his site
as without him this would look really horrible!
http://gsgd.co.uk/sandbox/jquery/easing/
*/

jQuery.easing.jswing = jQuery.swing;
jQuery.extend( jQuery.easing,
{
	def: 'easeOutCubic',
	swing: function (x, t, b, c, d) {
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	}
});

/*     
	12/20/08
	SliderJS
	Jquery plugin for smooth and pretty sliding divs
	Copyright (C) 2008 Jeremy Fry

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


jQuery.iSliderJS = {
	build : function(user_options)
	{
		var defaults = {
			direction:"vertical",
			list_width: 80,
			window_width: 80,
			window_height: 330,
			pikachoose: false
		};
		return $(this).each(function(){
			//declare variables. God knows I've missed half of them I'll use
			var options = $.extend(defaults, user_options); 
			var acceleration = 0;
			var inity = 0;
			var movey = [];
			var downtime = 0;
				
			//wrap the list in a sliderjs div.
			$(this).wrap("<div class='sliderjs'></div>");
			var $sliderul = $(this);
			var $sliderjs = $(this).parent("<div>");
			var divcss = {
				width: options.window_width+"px",
				height: options.window_height+"px",
				overflow:"hidden",
				position:"relative"
			};
			var ulcss = {
				position: "relative",
				width: options.list_width+"px"
			};
			$sliderjs.css(divcss);
			$sliderul.css(ulcss);
			//TODO:add a scroll bar and buttons maybe.
			if($.browser.msie){
				//$sliderjs.children().mousedown(function(){ return true;});
				$sliderul.children().mousedown(function(){
				return false;});
				$sliderul.children().children().mousedown(function(){
				return false;});
			}
			
			//mouse fucntions for tosses
			$sliderjs.bind('selectstart', function() {
                    return false; 
                });
			$sliderjs.bind("mousedown", function(e){
				$sliderul.stop();
				$sliderul.dequeue();
				movey.splice(0);
				initx = e.pageY;
				var date = new Date();
				downtime = date.getTime();
				var ylen = 0;
				var ulinitx =  $sliderul.position().top;
				$().bind("mousemove", function(e){
					//track the mouse movements
					//duplicates cause some issues. Though moving only one direction would
					//cause this. it tends to be unintentional
					if(movey[ylen-1]!=e.pageY){
						ylen = movey.push(e.pageY);
					}
					
					//keep trimming our array
					if(ylen>10){
						movey.splice(0,6);
						ylen = movey.push(e.pageY);
					}
					
					//track direction of last three movements. if directions changes reset time
					if(movey.length>3){
						if((movey[ylen-3]>=movey[ylen-2]) &&(movey[ylen-2]>=movey[ylen-1])){
						}else if((movey[ylen-3]<=movey[ylen-2]) &&(movey[ylen-2]<=movey[ylen-1])){
						}else{
							//if we made it here the user has changed direction so now we need to reset the time
							//downtime = date.getTime();
						}
					}
					
					//move the list around well the mouse is pressed
					var newtop = parseInt(ulinitx, 10)+parseInt((e.pageY-initx)/1.5, 10);
					if(newtop<((options.list_width*-1)+parseInt(options.window_width, 10)-50)){
						newtop=((options.list_width*-1)+parseInt(options.window_width, 10)-50);
					}
					if(newtop>50){newtop=50;}
					//$('.pika_navigation').html(newtop);
					$sliderul.css("top",newtop+"px");
				});
				$().bind("mouseup", MeatAndPatatos);
				return false;
			});
				
			function Animate(xvalue){
				$sliderul.stop();
				$sliderul.dequeue();
				$sliderul.animate({
					top:xvalue+"px"
				},1500,"easeOutCubic");
			}
			
			//TODO: find a better name for this func... nevermind I like it
			function MeatAndPatatos(e){
				$().unbind("mousemove");
				$().unbind("mouseup", MeatAndPatatos);
				var date = new Date();
				var uptime = date.getTime();
				
				//calculate velocity... did math class just pay off?
				var velocity = (movey[movey.length-1]*100-movey[movey.length-2]*100)/(uptime-downtime);
				var distance = movey[movey.length-1]-movey[movey.length-2];
				var negative = 1;
				//they're both negative when they get multiplied together we're going to end up with a positive
				if(distance<0){
					negative = -1;
				}
				var ulinitx =  $sliderul.position().top;
				var animatetop =  parseInt(ulinitx, 10)+(velocity * distance * negative)/2;
				if(animatetop<(options.list_width*-1)+parseInt(options.window_width, 10)){
					animatetop=(options.list_width*-1)+parseInt(options.window_width, 10);
				}
				//alert(animatetop);
				if(animatetop>0){animatetop=0;}
				//now that we have velocity figure out the distance to go and the time
				if(isNaN(animatetop)){}else{
					Animate(animatetop);
				}
				
			}
			
			

			function MoveToLi(){
				var pos = $(this).parent('li').position();
				var width = $(this).css("width").slice(0,-2);
				var litop = pos.top;
				var liright = parseInt(pos.top, 10)+parseInt(width, 10);
				var ultop = $sliderul.position().top;
				//find out if the li is inside the viewable area
				//first find range of viewable values
				var low = ultop*-1;
				var high = low+options.window_width;
				//is my li in that?
				if((litop>=low)&&(liright<=high)){
					//viewable we're gravy
					return;
				}else{
					//uh oh! not viewable lets slide
					//find how far outside view we are
					var slide =0;
					if(litop<low){
						//i know it seems like we should subtract.. however we have
						//negatives people! (I'm really writing this for me so I don't change
						//it later. :(
						slide = parseInt(litop, 10)*-1;
					}else{
						slide = ((liright-high)*-1)+parseInt(ultop, 10);
					}
					
					Animate(slide);
				}
			
			}
		
			if(options.pikachoose){
				var $lis = $sliderul.children('li');
				$lis.children().bind("click", MoveToLi);
				
			}
		});
		
	}
};
jQuery.fn.SliderJS = jQuery.iSliderJS.build;