/** 
/** ScrollerMa
/**	@version 4.2 rc2
/** @autor Łukasz Staliś
/**	@date 03.11.2010
/**	@company MediaAmbassador
/**	@rights All rights reserved
**/
jQuery.fn.extend({

	scroller: function(type,data){
		var $ = jQuery;
		var manager= $().scroller.manager?$().scroller.manager:($().scroller.manager = new Array());
		var idLb = idGenerator($(this).selector);
		if(!manager[idLb]){
			type = jQuery.extend({
				id: idLb,
				type: 'default',//cycle
				selector: $(this).selector,
				mode:"horizontal",//how to move the items: custom(not supported),vertical,horizontal
				nav: 'button', //button, none
				steps:5,	//steps 
				duration:500, //in milisecond
				itemsPerStep:1,
				items:'li',
				next:'',
				prev:'',
				scroll:'',
				easing: 'linear',
				buttonsStillVisible:false,
				afterInit:function(){},
				beforeMove:function(callback){ callback();},
				afterMove:function(){ },
				afterDestruct:function(){}			
			},type);
			//zabezpieczenie dla osób próbujących uruchomić scroller dla nieistniejącego elementu lub dla pustego elementu
			if($($(this).selector).size()==0 || $($(this).selector+' '+type.items).size()==0)return false;
			
			manager[idLb] = type.type==='cycle'?new ScrollerCycleClass(type): new ScrollerClass(type);
			
		} else {
			var obj = manager[idLb];
			switch(type){
				case 'goto':obj.goto(data);break;
				case 'next':obj.next();break;
				case 'prev':obj.prev();break;
				case "beforeDestruct":case "beforeMove":case "afterMove":case "afterDestruct": obj.addHandler(type,data);break;
				case 'destruct':obj.destruct(data);break;
			};
			
			return manager[idLb];
			
		};
		
		function ScrollerClass(sets){
			var parent = this;
			//public vars
			this.id = sets.id;
			this.selector = sets.selector;
			this.mode = sets.mode;
			this.nav = sets.nav;
			this.steps = sets.steps;
			this.duration = sets.duration;
			this.itemsPerStep = sets.itemsPerStep;
			this.items = sets.items;
			this.navNext = sets.next;
			this.navPrev = sets.prev;
			this.navScroll = sets.scroll;
			this.easing = sets.easing;
			this.buttonsStillVisible = sets.buttonsStillVisible;
			//private vars
			this.length = 0;
			this.lineLength = 0;
			this.current = 0;
			this.max = 0;
			this.lock = false;
			this.wraper = '#'+this.id+'Wraper';
			this.area = '#'+this.id+'MovingArea';
			this.elements = '#'+this.id+' '+this.items;
			this.counter = 0;
			//events
			this.afterInit = sets.afterInit;
			this.beforeMove = sets.beforeMove;
			this.afterMove = sets.afterMove;
			this.afterDestruct = sets.afterDestruct;
			//methods
			this.prev = function(){
				if($(this.navPrev).hasClass("disable") || this.current==0)return false;
				
				var pos=this.current-this.steps;
				if(pos<0)pos=0;
			
				this.move(pos);
			};
			this.next = function(){
				if($(this.navNext).hasClass("disable")||this.current ==(this.lineLength-1))return false;
				
				var pos=this.current+this.steps;
				if(pos>=this.lineLength)pos = this.lineLength -1;
	
				this.move(pos);
			};
			this.goto = function(pos){
				if(pos<0||pos>=this.lineLength)return false;
			
				this.move(pos);
			};
			this.move = function(pos){
				if(this.lock) return false;
				this.lock = true;
				parent.current = pos;
				
				this.beforeMove(function(){
					var x = 0;
					var y = 0;
					var hideNext = false;
					
					var off = $(parent.elements).eq(parent.mode=='horizontal'?parent.current:(parent.current*parent.itemsPerStep)).position();
					
					switch(parent.mode){
						case 'horizontal':{
							parent.max = $(parent.area).width() - 1 - $(parent.wraper).width();
							if(off.left>parent.max){
								x=-parent.max>0?0:-parent.max;		
								hideNext = true;						
							} else x=-off.left;
						};break;
						case 'vertical':{
							parent.max = $(parent.area).height() - 1 - $(parent.wraper).height();
							if(off.top>parent.max){
								y=-parent.max>0?0:-parent.max;				
								hideNext = true;								
							} else y=-off.top;
						};break;
					};
					if(parent.nav=='button'){
						if(hideNext){
							$(parent.navNext).addClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navNext).hide();
						} else {
							$(parent.navNext).removeClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navNext).show();
						};
						if(parent.current>0){
							$(parent.navPrev).removeClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navPrev).show();	
						} else {
							$(parent.navPrev).addClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navPrev).hide();
						};
					};
					parent.lock = false;				
					
					$(parent.area).stop().animate({left:x,top:y},parent.duration,parent.easing,function(){
							parent.afterMove();						
					});
				
				});
				
			};
			this.addHandler = function(type, fun){
				alert('not implemented');
			}
			//handlers
			this.nextHandler = function(ev){
				parent.next();
				return false;
			};
			this.prevHandler = function(ev){
				parent.prev();
				return false;
			};
			this.loadHandler = function(ev){
				parent.counter++;
				if(parent.counter==parent.length)parent.loadedHandler();
			};
			this.loadedHandler = function(){
				var w = 0;
				var h = 0;
				var wo = $(parent.elements).eq(0).outerWidth(true);
				var ho = $(parent.elements).eq(0).outerHeight(true);
				
				$(parent.elements).each(function(i,obj){
					w+= $(obj).outerWidth(true);
					h+= $(obj).outerHeight(true);
				});
				switch(parent.mode){
					case 'horizontal':{
						if(parent.itemsPerStep!=1) w = parent.lineLength*wo;
						w++;
						h=ho*parent.itemsPerStep+1;
						if($(parent.wraper).width()<w&&parent.nav=='button'){
							$(parent.navNext).removeClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navNext).show();
						};
					};break;
					case 'vertical':{
						if(parent.itemsPerStep!=1) h = parent.lineLength*ho;
						h++;
						w=wo*parent.itemsPerStep+1;
						if($(parent.wraper).height()<h&&parent.nav=='button'){
							$(parent.navNext).removeClass('disable');
							if(!parent.buttonsStillVisible)$(parent.navNext).show();
						};
					};break;
				};

				$(parent.area).css({'width': w, 'height': h});
				
				parent.afterInit();		
				
			};
			this.destruct = function(vars){
				if(parent.nav=='button'){
					$(this.navNext).unbind('click',this.nextHandler);
					$(this.navPrev).unbind('click',this.prevHandler);		
				};
				var contentHtml = $(this.selector+' .scrollerMovingArea').html();
				$(this.selector).empty().append(contentHtml);
				
				$().scroller.manager[this.id] = 0;
				
			};
			this.construct = function(){
			
				var contentHtml='<div id="'+this.id+'Wraper" class="scrollerWraper"><div id="'+this.id+'MovingArea" class="scrollerMovingArea">'+$(this.selector).html()+'<\/div><\/div>';
				if(parent.nav=='button'){
					if(this.navPrev==''){
						this.navPrev='#'+this.id+'Prev';
						contentHtml='<a href="#" id="'+this.id+'Prev" class="scrollerPrev">Poprzednie</a>'+contentHtml;
					};
					if(this.navNext==''){
						this.navNext='#'+this.id+'Next';
						contentHtml=contentHtml+'<a href="#" id="'+this.id+'Next" class="scrollerNext">Następne</a>';
					};
				};
				$(this.selector).empty().append(contentHtml).css('position','relative');
				if(parent.nav=='button'){
					$(this.navNext).bind('click',this.nextHandler).addClass("disable");
					$(this.navPrev).bind('click',this.prevHandler).addClass("disable");
				
					if(!this.buttonsStillVisible){
						$(this.navNext).hide();
						$(this.navPrev).hide();
					};				
				};
				$(this.wraper).css({position:'relative',overflow:'hidden'});
				$(this.area).css({top:0,left:0,position:'relative'});
				$(this.elements).css({float:'left',margin:0});
			
				this.length=$('#'+this.id+' '+this.items).length;
				this.lineLength=Math.floor(this.length/this.itemsPerStep)+(this.length%this.itemsPerStep!=0?1:0);
				
				if($(this.elements+' img').length!=0)$(this.elements+' img').bind('load',this.loadHandler); else this.loadedHandler();			
			
			
			
			};			
			this.construct();
			
		};
		function ScrollerCycleClass(sets){
			var parent = this;
			//public vars
			this.id = sets.id;
			this.selector = sets.selector;
			this.mode = sets.mode;
			this.nav = sets.nav;
			this.steps = sets.steps;
			this.duration = sets.duration;
			this.itemsPerStep = sets.itemsPerStep;
			this.items = sets.items;
			this.navNext = sets.next;
			this.navPrev = sets.prev;
			this.navScroll = sets.scroll;
			this.easing = sets.easing;
			this.buttonsStillVisible = sets.buttonsStillVisible;
			//private vars
			this.length = 0;
			this.lineLength = 0;
			this.current = 0;
			this.max = 0;
			this.lock = true;
			this.wraper = '#'+this.id+'Wraper';
			this.area = '#'+this.id+'MovingArea';
			this.elements = '#'+this.id+' '+this.items;
			this.counter = 0;
			this.pos = 0;
			//events
			this.afterInit = sets.afterInit;
			this.beforeMove = sets.beforeMove;
			this.afterMove = sets.afterMove;
			this.afterDestruct = sets.afterDestruct;
			//methods
			this.console = function(msg){
				if (!window.console) {
				  var log = window.opera ? window.opera.postError : alert;
				  window.console = { log: function(str) { log(str) } };
				};
				window.console.log(this.id+": "+msg);	
			};
			this.prev = function(){
				
				var pos=(this.current-this.steps+this.lineLength)%this.lineLength;
								
				
				this.tikPrev(pos);
			};
			this.next = function(){
				
				var pos=this.current+this.steps;
							
				this.tikNext(pos%this.lineLength);
				
			};
			this.goto = function(pos){
			
				this.tikNext(pos%this.lineLength);
			};
			this.tikNext = function(pos){
				if(this.lock)return;
				
				this.lock = true;
				
				function doTick(){
					var x = 0;
					var y = 0;
					var way = parent.mode=='vertical'?'top':'left';
					
					var off = $(parent.elements).eq((parent.current+1)%parent.lineLength).position();
					if(parent.mode=='vertical')y = -off.top; else x = -off.left;
					$(parent.area).animate({left:x,top:y},parent.duration/parent.steps,parent.easing,function(){
							$(parent.elements).eq(parent.current).css(way, parent.pos);
							parent.current = (parent.current +1)%parent.lineLength;
							
							var req = $(parent.elements).eq(parent.current).css(way);
							$(parent.elements).each(function(i, obj){
								$(obj).css(way,parseInt($(obj).css(way)) - parseInt(req));
							});
							$(parent.area).css(way, 0);
							
												
							if(parent.current==pos){
								parent.lock = false;
								parent.afterMove();
								
							} else doTick();					
					});
				
				};
				
				parent.beforeMove(doTick);
			};
			this.tikPrev = function(pos){
				if(this.lock)return;
				
				this.lock = true;
				
				function doTick(){
					var x = 0;
					var y = 0;
					var way = parent.mode=='vertical'?'top':'left';
					
					parent.current = (parent.current -1+parent.lineLength)%parent.lineLength;
					
					
					var last = $(parent.elements).eq(parent.current);
					
					$(last).css(way, parseInt($(last).css(way))-parent.pos);
					
					if(parent.mode=='vertical')y = -parseInt($(last).css(way)); else x = -parseInt($(last).css(way));
					
					$(parent.area).animate({left:x,top: y},parent.duration/parent.steps,parent.easing,function(){
							
							
							var req = -parseInt($(last).css(way));
							$(parent.elements).each(function(i, obj){
								$(obj).css(way,parseInt($(obj).css(way)) + parseInt(req));
							});
							$(parent.area).css(way, 0);
							
												
							if(parent.current==pos){
								parent.lock = false;
								parent.afterMove();
								
							} else doTick();					
					});
				
				};
				
				parent.beforeMove(doTick);				
			};
			this.addHandler = function(type, fun){
				alert('not implemented');
			}
			//handlers
			this.nextHandler = function(ev){
				parent.next();
				return false;
			};
			this.prevHandler = function(ev){
				parent.prev();
				return false;
			};
			this.loadHandler = function(ev){
				parent.counter++;
				if(parent.counter==parent.length)parent.loadedHandler();
			};
			this.loadedHandler = function(){
				var w = 0;
				var h = 0;
				var wo = $(parent.elements).eq(0).outerWidth(true);
				var ho = $(parent.elements).eq(0).outerHeight(true);
				
				$(parent.elements).each(function(i,obj){
					if(parent.mode=='vertical')$(obj).css('top',h); else $(obj).css('left',w);
					w+= $(obj).outerWidth(true);
					h+= $(obj).outerHeight(true);
				});
				switch(parent.mode){
					case 'horizontal':{
						parent.pos = w;
						if(parent.itemsPerStep!=1) w = parent.lineLength*wo;
						w++;
						h=ho*parent.itemsPerStep+1;
					};break;
					case 'vertical':{
						parent.pos = h;
						if(parent.itemsPerStep!=1) h = parent.lineLength*ho;
						h++;
						w=wo*parent.itemsPerStep+1;
					};break;
				};	
				
				$(parent.area).css({'width': w, 'height': h});
				
				$(parent.navNext).removeClass('disable');
				$(parent.navPrev).removeClass('disable');
				parent.lock = false;
				parent.afterInit();		
				
			};
			this.destruct = function(vars){
				if(parent.nav=='button'){
					$(this.navNext).unbind('click',this.nextHandler);
					$(this.navPrev).unbind('click',this.prevHandler);		
				};
				var contentHtml = $(this.selector+' .scrollerMovingArea').html();
				$(this.selector).empty().append(contentHtml);
				
				$().scroller.manager[this.id] = 0;
				
			};
			this.construct = function(){
			
				var contentHtml='<div id="'+this.id+'Wraper" class="scrollerWraper"><div id="'+this.id+'MovingArea" class="scrollerMovingArea">'+$(this.selector).html()+'<\/div><\/div>';
				if(parent.nav=='button'){
					if(this.navPrev==''){
						this.navPrev='#'+this.id+'Prev';
						contentHtml='<a href="#" id="'+this.id+'Prev" class="scrollerPrev">Poprzednie</a>'+contentHtml;
					};
					if(this.navNext==''){
						this.navNext='#'+this.id+'Next';
						contentHtml=contentHtml+'<a href="#" id="'+this.id+'Next" class="scrollerNext">Następne</a>';
					};
				};
				$(this.selector).empty().append(contentHtml).css('position','relative');
				if(parent.nav=='button'){
					$(this.navNext).bind('click',this.nextHandler).addClass("disable");
					$(this.navPrev).bind('click',this.prevHandler).addClass("disable");	
				};
				$(this.wraper).css({position:'relative',overflow:'hidden'});
				$(this.area).css({top:0,left:0,position:'relative'});
				$(this.elements).css({float:'left',margin:0, position: 'absolute', top: 0, left: 0});
			
				this.length=$('#'+this.id+' '+this.items).length;
				this.lineLength=Math.floor(this.length/this.itemsPerStep)+(this.length%this.itemsPerStep!=0?1:0);
				
				if($(this.elements+' img').length!=0)$(this.elements+' img').bind('load',this.loadHandler); else this.loadedHandler();			
			
			
			
			};			
			this.construct();
			
		};
		function idGenerator(str){
			var exp= new RegExp("[^a-zA-Z0-9]+","g");
			var tpl=str.replace(exp,'');
			return tpl;
		};			
		
	}
		
	
});
