(function ($) {

	var $this, $content, $maxScrollPos, $scrollPos, $arrowStep, $mouseX, $mouseXOff, $mouseDown, $bar, $track, $left, $right, $slider, leftArraow, rightArrow, arrowTimer, snapTimer, scrollPosTarget, snap, hideWhenInactive;
	
	var methods = {
		snapIndex : function (index) {
			if ( snap ) {
				var _scrollPosTarget = Math.max(Math.min(snap / $maxScrollPos * index, 1), 0);
				if ( _scrollPosTarget != scrollPosTarget ) {
					scrollPosTarget = _scrollPosTarget;
					startSnap();
				}
			}
		},
		setScroll : function (scroll) {
			$maxScrollPos = Math.max ( $content.width() + 24 - $this.width(), 0 );
			$scrollPos = Math.max(Math.min(scroll / $maxScrollPos, 1), 0);
			methods.update();
		},
		update : function() {
			$maxScrollPos = Math.max ( $content.width() + 24 - $this.width(), 0 );
			var $bw = 390 * ( 1 - $maxScrollPos / ( $content.width() + 24 ) )
			$bar.css('width', $bw );
			$bar.css('margin-left', Math.round($scrollPos * ( 390 - $bw )) );
			$this.scrollLeft( $scrollPos * $maxScrollPos );
			$($bar).css('display', $maxScrollPos > 0 ? 'block' : 'none');
			$($left).css('display', $maxScrollPos > 0 ? 'block' : 'none');
			$($right).css('display', $maxScrollPos > 0 ? 'block' : 'none');
			$($slider).css('display', !$maxScrollPos && hideWhenInactive ? 'none' : 'block' );
		}
	};
	
	var startSnap = function() { stopSnap(); snapTimer = setInterval(function(){ var step = ( scrollPosTarget - $scrollPos ) / 5; if ( Math.abs(step) < 0.0005 ) { stopSnap(); $scrollPos = scrollPosTarget; } else { if ( Math.abs(step) < 0.001 ) step = ( scrollPosTarget - $scrollPos ) / 2; $scrollPos += step; } methods.update();  }, 25); }
	var stopSnap = function() { if ( snapTimer ) { clearInterval( snapTimer ); snapTimer = 0; } }
	
$.fn.folioslider = function ( param, snapStep ) {
	if ( param && methods[param] ) {
		return methods[ param ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else {
		hideWhenInactive = param;
		snap = snapStep;
		$this = $(this);
		$content = $this.find('div:first');
		$maxScrollPos = 0;
		$scrollPos = 0;
		$arrowStep = 15;
		$mouseX;
		$mouseXOff = 0;
		$mouseDown = false;
		
		$this.after('<div class="front-slider"><div class="slider-arrow-left"></div><div class="slider-track"><div class="slider-bar"></div></div><div class="slider-arrow-right"></div></div>');
		$bar = $this.next().find('.slider-bar');
		$track = $this.next().find('.slider-track');
		$left = $this.next().find('.slider-arrow-left');
		$right = $this.next().find('.slider-arrow-right');
		$slider = $track.parent();
		
		$this.next().mousedown( function(event){ if(event.preventDefault) event.preventDefault(); } );
		
		var mousePos = function() {
			if ( $mouseDown ) {
				var $bw = 390 * ( 1 - $maxScrollPos / ( $content.width() + 24 ) );
				$scrollPos = Math.max ( Math.min( ( $mouseX - $mouseXOff )/ ( 390 - $bw ), 1), 0);
				methods.update();
			}
		}
		
		leftArraow = function(){ $scrollPos = Math.max( $scrollPos - $arrowStep / $maxScrollPos, 0 ); methods.update(); };
		rightArrow = function(){ $scrollPos = Math.min( $scrollPos + $arrowStep / $maxScrollPos, 1 ); methods.update(); };
		arrowTimer = 0;
		snapTimer = 0;
		scrollPosTarget = 0;
		
		$left.mousedown( function () { 
			if ( snap ) {
				scrollPosTarget = Math.max( Math.round($scrollPos * $maxScrollPos / snap) * snap / $maxScrollPos - snap / $maxScrollPos, 0 );
				startSnap();
			} else
				arrowTimer = setInterval(leftArraow, 25); 
		});
		$right.mousedown( function () { 
			if ( snap ) {
				scrollPosTarget = Math.min( Math.round($scrollPos * $maxScrollPos / snap) * snap / $maxScrollPos + snap / $maxScrollPos, 1 );
				startSnap();
			} else
				arrowTimer = setInterval(rightArrow, 25); 
		});
		
		$(document).mousemove(function(e){ $mouseX = e.pageX - $track.offset().left; mousePos(); });
		$bar.mousedown(function(){ stopSnap(); if ( $mouseDown )	return; $mouseXOff = $mouseX - $bar.css('margin-left').replace('px', ''); $mouseDown = true; mousePos();  });
		$track.mousedown(function(){ stopSnap(); if ( $mouseDown )	return; var $bw = 390 * ( 1 - $maxScrollPos / ( $content.width() + 24 ) ); $mouseXOff = $bw / 2; $mouseDown = true; mousePos(); });
		$(document).mouseup(function(){ 
			$mouseDown = false; 
			clearInterval(arrowTimer);
			if ( !snapTimer && snap ) {
				scrollPosTarget = Math.round($scrollPos * $maxScrollPos / snap) * snap / $maxScrollPos;
				startSnap();
			}
		});
		
		$(window).resize(methods.update);
		methods.update();
	}
};

})(jQuery);
