/*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.iSliderJSVertical = {
	build : function(user_options)
	{
		var defaults = {
			direction:"vertical",
			list_height: 6740,
			list_width: 200,
			window_width: 350,
			window_height: 500,
			list_margin_left: 0,
			window_padding_top: 0,
			window_padding_right: 0,
			window_padding_bottom: 0,
			window_padding_left: 0,
			pikachoose: false
		};
		return jQuery(this).each(function(){
			//declare variables. God knows I've missed half of them I'll use
			var options = jQuery.extend(defaults, user_options); 
			var acceleration = 0;
			var initx = 0; //intial
			var inity = 0;
			var movey = [];
			var downtime = 0;
			//wrap the list in a sliderjs div.
			jQuery(this).wrap("<div class='sliderjs'></div>");
			var sliderul = jQuery(this);
			var sliderjs = jQuery(this).parent();
			var divcss = {
				width: options.window_width+"px",
				height: options.window_height+"px",
				overflow:"hidden",
				position:"relative",
				paddingTop: options.window_padding_top+"px",
				paddingRight: options.window_padding_right+"px",
				paddingBottom: options.window_padding_bottom+"px",
				paddingLeft: options.window_padding_left+"px"
			};
			var ulcss = {
				position: "relative",
				width: options.list_width+"px",
				height: options.list_height+"px"
			};
			sliderjs.css(divcss);
			sliderul.css(ulcss);
			//TODO:add a scroll bar and buttons maybe.
			//if IE
			if(!jQuery.support.cssFloat)
			{
				//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);
				inity = e.pageY;
				var date = new Date();
				downtime = date.getTime();
				var ylen = 0;
				var ulinity =  sliderul.position().top;
				jQuery().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(ulinity, 10)+parseInt((e.pageY-inity)/1.5, 10);
					if(newtop<((options.list_height*-1)+parseInt(options.window_height, 10)-50)){
						newtop=((options.list_height*-1)+parseInt(options.window_height, 10)-50);
					}
					if(newtop>50){newtop=50;}
					//jQuery('.pika_navigation').html(newleft);
					sliderul.css("top",newtop+"px");
				});
				jQuery().bind("mouseup", MeatAndPatatos);
				return false;
			});
				
			function Animate(yvalue){
				sliderul.stop();
				sliderul.dequeue();
				sliderul.animate({
					top:yvalue+"px"
				},1500,"easeOutCubic");
			}
			
			//TODO: find a better name for this func... nevermind I like it
			function MeatAndPatatos(e){
				jQuery().unbind("mousemove");
				jQuery().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 ulinity =  sliderul.position().top;
				var animatetop =  parseInt(ulinity, 10)+(velocity * distance * negative)/2;
				if(animatetop<(options.list_height*-1)+parseInt(options.window_height, 10)){
					animatetop=(options.list_height*-1)+parseInt(options.window_height, 10);
				}
				//alert(animateleft);
				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 = jQuery(this).parent('li').position();
				var height = jQuery(this).css("height").slice(0,-2);
				var litop = pos.top;
				var libottom = parseInt(pos.top, 10)+parseInt(height, 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_height;
				//is my li in that?
				if((litop>=low)&&(libottom<=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 = ((libottom-high)*-1)+parseInt(ultop, 10);
					}
					
					Animate(slide);
				}
			
			}
		
			if(options.pikachoose){
				var lis = sliderul.children('li');
				lis.children().bind("click", MoveToLi);
				
			}
		});
		
	}
};
jQuery.fn.SliderJSVertical = jQuery.iSliderJSVertical.build;
