/**
 * tools.scrollable 1.1.2 - Scroll your HTML with eye candy.
 * 
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/scrollable.html
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Launch  : March 2008
 * Date: ${date}
 * Revision: ${revision} 
 */

//(function($) { 
//		
//	// static constructs
//	$.tools = $.tools || {};
//	
//	$.tools.scrollable = {
//		version: '1.1.2',
//		
//		conf: {
//			
//			// basics
//			size: 5,
//			vertical: false,
//			speed: 400,
//			keyboard: true,		
//			
//			// by default this is the same as size
//			keyboardSteps: null, 
//			
//			// other
//			disabledClass: 'disabled',
//			hoverClass: null,		
//			clickable: true,
//			activeClass: 'active', 
//			easing: 'swing',
//			loop: false,
//			
//			items: '.items',
//			item: '.grid-row',
//			
//			// navigational elements			
//			prev: '.prev',
//			next: '.next',
//			prevPage: '.prevPage',
//			nextPage: '.nextPage', 
//			api: false
//			
//			// CALLBACKS: onBeforeSeek, onSeek, onReload
//		} 
//	};
//				
//	var current;		
//	
//	// constructor
//	function Scrollable(root, conf) {   
//		
//		// current instance
//		var self = this, $self = $(this),
//			 horizontal = !conf.vertical,
//			 wrap = root.children(),
//			 index = 0,
//			 forward;  
//		
//	
//		if (!current) { current = self; }
//		
//		// bind all callbacks from configuration
//		$.each(conf, function(name, fn) {
//			if ($.isFunction(fn)) { $self.bind(name, fn); }
//		});
//		
//		if (wrap.length > 1) { wrap = $(conf.items, root); }
//		
//		// navigational items can be anywhere when globalNav = true
//		function find(query) {
//			var els = $(query);
//			return conf.globalNav ? els : root.parent().find(query);	
//		}
//		
//		// to be used by plugins
//		root.data("finder", find);
//		
//		// get handle to navigational elements
//		var prev = find(conf.prev),
//			 next = find(conf.next),
//			 prevPage = find(conf.prevPage),
//			 nextPage = find(conf.nextPage);
//
//		
//		// methods
//		$.extend(self, {
//			
//			getIndex: function() {
//				return index;	
//			},
//			
//			getClickIndex: function() {
//				var items = self.getItems(); 
//				return items.index(items.filter("." + conf.activeClass));	
//			},
//	
//			getConf: function() {
//				return conf;	
//			},
//			
//			getSize: function() {
//				return self.getItems().size();	
//			},
//	
//			getPageAmount: function() {
//				return Math.ceil(this.getSize() / conf.size); 	
//			},
//			
//			getPageIndex: function() {
//				return Math.ceil(index / conf.size);	
//			},
//
//			getNaviButtons: function() {
//				return prev.add(next).add(prevPage).add(nextPage);	
//			},
//			
//			getRoot: function() {
//				return root;	
//			},
//			
//			getItemWrap: function() {
//				return wrap;	
//			},
//			
//			getItems: function() {
//				return wrap.children(conf.item);	
//			},
//			
//			getVisibleItems: function() {
//				return self.getItems().slice(index, index + conf.size);	
//			},
//			
//			/* all seeking functions depend on this */		
//			seekTo: function(i, time, fn) {
//
//				if (i < 0) { i = 0; }				
//				
//				// nothing happens
//				if (index === i) { return self; }				
//				
//				// function given as second argument
//				if ($.isFunction(time)) {
//					fn = time;
//				}
//
//				// seeking exceeds the end				 
//				if (i > self.getSize() - conf.size) { 
//					return conf.loop ? self.begin() : this.end(); 
//				} 				
//
//				var item = self.getItems().eq(i);					
//				if (!item.length) { return self; }				
//				
//				// onBeforeSeek
//				var e = $.Event("onBeforeSeek");
//
//				$self.trigger(e, [i]);				
//				if (e.isDefaultPrevented()) { return self; }				
//				
//				// get the (possibly altered) speed
//				if (time === undefined || $.isFunction(time)) { time = conf.speed; }
//				
//				function callback() {
//					if (fn) { fn.call(self, i); }
//					$self.trigger("onSeek", [i]);
//				}
//				
//				if (horizontal) {
//					wrap.animate({left: -item.position().left}, time, conf.easing, callback);					
//				} else {
//					wrap.animate({top: -item.position().top}, time, conf.easing, callback);							
//				}
//				
//				
//				current = self;
//				index = i;				
//				
//				// onStart
//				e = $.Event("onStart");
//				$self.trigger(e, [i]);				
//				if (e.isDefaultPrevented()) { return self; }				
//	
//				
//				/* default behaviour */
//				
//				// prev/next buttons disabled flags
//				prev.add(prevPage).toggleClass(conf.disabledClass, i === 0);
//				next.add(nextPage).toggleClass(conf.disabledClass, i >= self.getSize() - conf.size);
//				
//				return self; 
//			},			
//			
//				
//			move: function(offset, time, fn) {
//				forward = offset > 0;
//				return this.seekTo(index + offset, time, fn);
//			},
//			
//			next: function(time, fn) {
//				return this.move(1, time, fn);	
//			},
//			
//			prev: function(time, fn) {
//				return this.move(-1, time, fn);	
//			},
//			
//			movePage: function(offset, time, fn) {
//				forward = offset > 0;
//				var steps = conf.size * offset;
//				
//				var i = index % conf.size;
//				if (i > 0) {
//				 	steps += (offset > 0 ? -i : conf.size - i);
//				}
//				
//				return this.move(steps, time, fn);		
//			},
//			
//			prevPage: function(time, fn) {
//				return this.movePage(-1, time, fn);
//			},  
//	
//			nextPage: function(time, fn) {
//				return this.movePage(1, time, fn);
//			},			
//			
//			setPage: function(page, time, fn) {
//				return this.seekTo(page * conf.size, time, fn);
//			},			
//			
//			begin: function(time, fn) {
//				forward = false;
//				return this.seekTo(0, time, fn);	
//			},
//			
//			end: function(time, fn) {
//				forward = true;
//				var to = this.getSize() - conf.size;
//				return to > 0 ? this.seekTo(to, time, fn) : self;	
//			},
//			
//			reload: function() {				
//				$self.trigger("onReload");
//				return self;
//			},			
//			
//			focus: function() {
//				current = self;
//				return self;
//			},
//			
//			click: function(i) {
//				
//				var item = self.getItems().eq(i), 
//					 klass = conf.activeClass,
//					 size = conf.size;			
//				
//				// check that i is sane
//				if (i < 0 || i >= self.getSize()) { return self; }
//				
//				// size == 1							
//				if (size == 1) {
//					if (conf.loop) { return self.next(); }
//					
//					if (i === 0 || i == self.getSize() -1)  { 
//						forward = (forward === undefined) ? true : !forward;	 
//					}
//					return forward === false  ? self.prev() : self.next(); 
//				} 
//				
//				// size == 2
//				if (size == 2) {
//					if (i == index) { i--; }
//					self.getItems().removeClass(klass);
//					item.addClass(klass);					
//					return self.seekTo(i, time, fn);
//				}				
//		
//				if (!item.hasClass(klass)) {				
//					self.getItems().removeClass(klass);
//					item.addClass(klass);
//					var delta = Math.floor(size / 2);
//					var to = i - delta;
//		
//					// next to last item must work
//					if (to > self.getSize() - size) { 
//						to = self.getSize() - size; 
//					}
//		
//					if (to !== i) {
//						return self.seekTo(to);		
//					}
//				}
//				
//				return self;
//			},
//			
//			// bind / unbind
//			bind: function(name, fn) {
//				$self.bind(name, fn);
//				return self;	
//			},	
//			
//			unbind: function(name) {
//				$self.unbind(name);
//				return self;	
//			}			
//			
//		});
//		
//		// callbacks	
//		$.each("onBeforeSeek,onStart,onSeek,onReload".split(","), function(i, ev) {
//			self[ev] = function(fn) {
//				return self.bind(ev, fn);	
//			};
//		});  
//			
//			
//		// prev button		
//		prev.addClass(conf.disabledClass).click(function() {
//			self.prev(); 
//		});
//		
//
//		// next button
//		next.click(function() { 
//			self.next(); 
//		});
//		
//		// prev page button
//		nextPage.click(function() { 
//			self.nextPage(); 
//		});
//		
//		if (self.getSize() < conf.size) {
//			next.add(nextPage).addClass(conf.disabledClass);	
//		}
//		
//
//		// next page button
//		prevPage.addClass(conf.disabledClass).click(function() { 
//			self.prevPage(); 
//		});		
//		
//		
//		// hover
//		var hc = conf.hoverClass, keyId = "keydown." + Math.random().toString().substring(10); 
//			
//		self.onReload(function() { 
//
//			// hovering
//			if (hc) {
//				self.getItems().hover(function()  {
//					$(this).addClass(hc);		
//				}, function() {
//					$(this).removeClass(hc);	
//				});						
//			}
//			
//			// clickable
//			if (conf.clickable) {
//				self.getItems().each(function(i) {
//					$(this).unbind("click.scrollable").bind("click.scrollable", function(e) {
//						if ($(e.target).is("a")) { return; }	
//						return self.click(i);
//					});
//				});
//			}				
//			
//			// keyboard			
//			if (conf.keyboard) {				
//				
//				// keyboard works on one instance at the time. thus we need to unbind first
//				$(document).unbind(keyId).bind(keyId, function(evt) {
//
//					// do nothing with CTRL / ALT buttons
//					if (evt.altKey || evt.ctrlKey) { return; }
//					
//					// do nothing for unstatic and unfocused instances
//					if (conf.keyboard != 'static' && current != self) { return; }
//					
//					var s = conf.keyboardSteps;				
//										
//					if (horizontal && (evt.keyCode == 37 || evt.keyCode == 39)) {					
//						self.move(evt.keyCode == 37 ? -s : s);
//						return evt.preventDefault();
//					}	
//					
//					if (!horizontal && (evt.keyCode == 38 || evt.keyCode == 40)) {
//						self.move(evt.keyCode == 38 ? -s : s);
//						return evt.preventDefault();
//					}
//					
//					return true;
//					
//				});
//				
//			} else  {
//				$(document).unbind(keyId);	
//			}				
//
//		});
//		
//		self.reload(); 
//		
//	} 
//
//		
//	// jQuery plugin implementation
//	$.fn.scrollable = function(conf) { 
//			
//		// already constructed --> return API
//		var el = this.eq(typeof conf == 'number' ? conf : 0).data("scrollable");
//		if (el) { return el; }		 
// 
//		var globals = $.extend({}, $.tools.scrollable.conf);
//		conf = $.extend(globals, conf);
//		
//		conf.keyboardSteps = conf.keyboardSteps || conf.size;
//		
//		this.each(function() {			
//			el = new Scrollable($(this), conf);
//			$(this).data("scrollable", el);	
//		});
//		
//		return conf.api ? el: this; 
//		
//	};
//			
//	
//})(jQuery);
(function(a){a.tools=a.tools||{version:"v1.2.5"},a.tools.scrollable={conf:{activeClass:"active",circular:!1,clonedClass:"cloned",disabledClass:"disabled",easing:"swing",initialIndex:0,item:null,items:".items",keyboard:!0,mousewheel:!1,next:".next",prev:".prev",speed:400,vertical:!1,touch:!0,wheelSpeed:0}};function b(a,b){var c=parseInt(a.css(b),10);if(c)return c;var d=a[0].currentStyle;return d&&d.width&&parseInt(d.width,10)}function c(b,c){var d=a(c);return d.length<2?d:b.parent().find(c)}var d;function e(b,e){var f=this,g=b.add(f),h=b.children(),i=0,j=e.vertical;d||(d=f),h.length>1&&(h=a(e.items,b)),a.extend(f,{getConf:function(){return e},getIndex:function(){return i},getSize:function(){return f.getItems().size()},getNaviButtons:function(){return m.add(n)},getRoot:function(){return b},getItemWrap:function(){return h},getItems:function(){return h.children(e.item).not("."+e.clonedClass)},move:function(a,b){return f.seekTo(i+a,b)},next:function(a){return f.move(1,a)},prev:function(a){return f.move(-1,a)},begin:function(a){return f.seekTo(0,a)},end:function(a){return f.seekTo(f.getSize()-1,a)},focus:function(){d=f;return f},addItem:function(b){b=a(b),e.circular?(h.children("."+e.clonedClass+":last").before(b),h.children("."+e.clonedClass+":first").replaceWith(b.clone().addClass(e.clonedClass))):h.append(b),g.trigger("onAddItem",[b]);return f},seekTo:function(b,c,k){b.jquery||(b*=1);if(e.circular&&b===0&&i==-1&&c!==0)return f;if(!e.circular&&b<0||b>f.getSize()||b<-1)return f;var l=b;b.jquery?b=f.getItems().index(b):l=f.getItems().eq(b);var m=a.Event("onBeforeSeek");if(!k){g.trigger(m,[b,c]);if(m.isDefaultPrevented()||!l.length)return f}var n=j?{top:-l.position().top}:{left:-l.position().left};i=b,d=f,c===undefined&&(c=e.speed),h.animate(n,c,e.easing,k||function(){g.trigger("onSeek",[b])});return f}}),a.each(["onBeforeSeek","onSeek","onAddItem"],function(b,c){a.isFunction(e[c])&&a(f).bind(c,e[c]),f[c]=function(b){b&&a(f).bind(c,b);return f}});if(e.circular){var k=f.getItems().slice(-1).clone().prependTo(h),l=f.getItems().eq(1).clone().appendTo(h);k.add(l).addClass(e.clonedClass),f.onBeforeSeek(function(a,b,c){if(!a.isDefaultPrevented()){if(b==-1){f.seekTo(k,c,function(){f.end(0)});return a.preventDefault()}b==f.getSize()&&f.seekTo(l,c,function(){f.begin(0)})}}),f.seekTo(0,0,function(){})}var m=c(b,e.prev).click(function(){f.prev()}),n=c(b,e.next).click(function(){f.next()});!e.circular&&f.getSize()>1&&(f.onBeforeSeek(function(a,b){setTimeout(function(){a.isDefaultPrevented()||(m.toggleClass(e.disabledClass,b<=0),n.toggleClass(e.disabledClass,b>=f.getSize()-1))},1)}),e.initialIndex||m.addClass(e.disabledClass)),e.mousewheel&&a.fn.mousewheel&&b.mousewheel(function(a,b){if(e.mousewheel){f.move(b<0?1:-1,e.wheelSpeed||50);return!1}});if(e.touch){var o={};h[0].ontouchstart=function(a){var b=a.touches[0];o.x=b.clientX,o.y=b.clientY},h[0].ontouchmove=function(a){if(a.touches.length==1&&!h.is(":animated")){var b=a.touches[0],c=o.x-b.clientX,d=o.y-b.clientY;f[j&&d>0||!j&&c>0?"next":"prev"](),a.preventDefault()}}}e.keyboard&&a(document).bind("keydown.scrollable",function(b){if(e.keyboard&&!b.altKey&&!b.ctrlKey&&!a(b.target).is(":input")){if(e.keyboard!="static"&&d!=f)return;var c=b.keyCode;if(j&&(c==38||c==40)){f.move(c==38?-1:1);return b.preventDefault()}if(!j&&(c==37||c==39)){f.move(c==37?-1:1);return b.preventDefault()}}}),e.initialIndex&&f.seekTo(e.initialIndex,0,function(){})}a.fn.scrollable=function(b){ var c=this.data("scrollable");if(c)return c;b=a.extend({},a.tools.scrollable.conf,b),this.each(function(){c=new e(a(this),b),a(this).data("scrollable",c)});return b.api?c:this}})(jQuery);

