//***************************************************************************************
//		jQuery Plugin
//		Name : AdSlider
//		Version : 0.1
//		Release date : 2011-08-20
//		Licence: 
//		Author : Filip Różański
//		Description: Scroll-bar plugin
//		Notes : Full functionality is only available in vertical mode
//***************************************************************************************
//***************************************************************************************

(function($) 
{	
	//*****************************************************************
	// DEFAULTS - default options sets during "init" method 
	//*****************************************************************
	var defaults = {
		scroll_range : 200, // scroll jump value
		scroll_time : 1000,
		auto : 0,
		init_scroll : 0, // scroll start value ( intiger or "max" )
		bind_to_body : true,    // binduje mousemove do Body zamiast do scrollowanego kontenera
		//always : function(){},  // funkcja do wykonania zawsze (np na początku i na końcu scrollingu lub przy wykonaniu akcji elementu - np reset licznika czasu do wylogowania )
		get_sliders_by_id : 1,
		buttons : 0,
		slider_ver : false,
		slider_hor : false,
		slider_size : 'box',  //box , manual ,
		buttons_offset : 0,
		wheelscroll_step : 10,
	};
	//*****************************************************************
	// DEFAULTS END
	//*****************************************************************
	
	//*****************************************************************
	// HELPER - unpublic methods
	//*****************************************************************
	var helper = {	
		
		margeSetts : function( sets , options ) {
			if( options )
			{
				return $.extend({}, sets, options);
			}
			return sets;
		},
		
		getEvent : function( e ) {
			if(e.originalEvent.touches && e.originalEvent.touches.length) {
       		return e.originalEvent.touches[0];
    		} else if(e.originalEvent.changedTouches && e.originalEvent.changedTouches.length) {
      		return e.originalEvent.changedTouches[0];
    		}
    		else {
    			return e;
    		}
		},
		
		
		//used to set slider's position by actual scroll value
		setSlider : function( sets , pos , props , animTime ){
			sets.slider.stop();
			if(pos < 0 ){ pos = 0; }
			var scrPer = Number(pos / (sets.maxScroll - sets.boxSize )).toFixed(3);
			var sbPos = Math.round(sets.sbSize * scrPer);
			if( sbPos > sets.sbSize ){ sbPos = sets.sbSize; }
			if(animTime) {
				var animProps = {};
					animProps[ props.pos ] = sbPos;
				sets.slider.animate( animProps , animTime );
			}
			else {
				sets.slider.css( props.pos , sbPos+'px' );
			}
		},
		
		
		//used by slider to set scroll position
		setScroll : function( $box, sets , pos , props, animTime ){
			$box.stop();
			var scrPer = Number( pos / ( sets.sbSize ) ).toFixed(3);
			var toPos = Math.round( (sets.maxScroll - sets.boxSize )  * scrPer );

			if(animTime)
			{
				var animProps = {};
					animProps[ props.moveProp ] = toPos;
				$box.animate( animProps , animTime );
			}
			else
			{
				$box[props.moveProp]( toPos );
			}
		},
		
		
		getSliderByDirect : function( boxData , direct ){
			var slrObj = { slider : false , orient : false };
				//orient = false;
			switch( direct )
			{
				case 'left':
				case 'right':
					slrObj.orient = 'hor';
				break;
				
				case 'top':
				case 'up':
				case 'bottom':
				case 'down':
					slrObj.orient = 'ver';
				break;
			}
			//if( orient )
			//{
			//	slrObj.orient = orient;
				if( boxData.scrollBars[ slrObj.orient ] )
				{
					slrObj.slider = boxData.scrollBars[ slrObj.orient ];
				}
			//}
			return slrObj;
		},
		
		
		getObjInfo : function( $obj )
		{
			return { 'width' : $obj.width() , 'height' : $obj.height(), 'position' : $obj.css("position") , 'top' : parseInt( $obj.css('top') ) , 'left' : parseInt( $obj.css('left') ) };
		},
		
		
		initBar : function( $bar ) {
			if( typeof $bar != 'Object' )
			{
				$bar = $( $bar );
			}
			if( $bar.size() > 0 )
			{
				return $bar
			}
			return false;
		},
		
		createSBInfo : function() {
			return { 'bar' : false , 'content' : false ,'buttonPos' : false , 'buttonCPos' : false , 'slider' : false , 'sliderArea' : false };
		},
		
		
		initBars : function( data ) {
			if( data.settings.auto == 1 ) {
				var $parent = data.target.parent(),
					parentInfo = helper.getObjInfo( $parent ),
					boxInfo = helper.getObjInfo( data.target );
				//debug('parentInfo' , parentInfo , 'boxInfo' , boxInfo );
					
			}
			else if( data.settings.get_sliders_by_id == 1 ) {
				var id = data.target.attr('id');
				data.settings.slider_ver	= '#'+id+'-sliderVer';
				data.settings.slider_hor = '#'+id+'-sliderHor';
			}
			data.scrollBars.ver = helper.createSBInfo();
			data.scrollBars.hor = helper.createSBInfo();
			
			if( data.settings.slider_ver !== false ) {
				data.scrollBars.ver.bar = helper.initBar( data.settings.slider_ver );
			}
			if( data.settings.slider_hor !== false ) {
				data.scrollBars.hor.bar = helper.initBar( data.settings.slider_hor );		
			}
		},
		
		
		
		getProps : function( pos ) {
			switch( pos )
			{
				case 'X':
				case 'x':
				case 'hor':
				case 'horizontal':
					return { eProp : "pageX" , moveProp : "scrollLeft" , maxScroll : "scrollWidth" , outerSize : "outerWidth" , size : "width" , pos : "left"  , counterPos : "right" };
				break;
				case 'Y':
				case 'y':
				case 'ver':
				case 'vertical':
					return { eProp : "pageY" , moveProp : "scrollTop" , maxScroll : "scrollHeight" , outerSize : "outerHeight" , size : "height" , pos : "top" , counterPos : "bottom" };
				break;
			}
			return false;
		},
		
		initButtons : function( boxData , $buttons , orient ) {
			
			
		},
		
		initScrollBar : function( $box , boxData , orient ) {
			var $scrollBar = boxData.scrollBars[orient].bar,
				props = helper.getProps( orient ),
				maxScroll = $box[0][props.maxScroll],
				actScroll = $box[props.moveProp](),
				boxSize = $box[props.outerSize](),
				startStyle = 'position: relative; ';
			
			$scrollBar.html('');
			if( maxScroll <= boxSize ) {
				$scrollBar.hide();
			}
			else {
				$scrollBar.show();
			}
			$("div.adslider-slider.adslider-slider-"+orient).unbind('mousedown touchstart').remove();
			
			var cont = '<div class="adslider-bar-content adslider-bar-'+orient+'-content">';
			if( boxData.settings.buttons == 1 )
			{
				cont += '<div class="adslider-bar-button adslider-bar-button-'+props.pos+'" scrollto="'+props.pos+'"></div><div class="adslider-bar-button adslider-bar-button-'+props.counterPos+'" scrollTo="'+props.counterPos+'"></div>';
			}
			cont += '<div class="adslider-bar-slidearea adslider-bar-'+orient+'-slidearea"></div>';
			cont += '</div>';
			
			if( boxData.settings.slider_size == 'box' )
			{
				var scrollSize = boxSize - parseInt($scrollBar.css( 'padding-'+props.pos )) - parseInt($scrollBar.css( 'padding-'+props.counterPos )) - parseInt($scrollBar.css( 'border-'+props.pos+'-width' )) - parseInt($scrollBar.css( 'border-'+props.counterPos+'-width' ));
				$scrollBar[props.size]( scrollSize );
			}
			
			$scrollBar.append( cont );
			var $sbContent = $('div.adslider-bar-content',$scrollBar);
			var $sbArea = $('div.adslider-bar-slidearea',$scrollBar);
			var $sbButtons = $('div.adslider-bar-button',$scrollBar);
			
			var $sbButtonPos = $('div.adslider-bar-button-'+props.pos, $scrollBar);
			var $sbButtonCPos = $('div.adslider-bar-button-'+props.counterPos, $scrollBar);
			
			var sbContentInfo = { 'width' : $sbContent.innerWidth() , 'height' : $sbContent.innerHeight() };
			//debug(sbContentInfo); 
			
			//helper.setButtons( $sbButtons , sbContentInfo );
			
			$sbButtons.mousedown(function(){
				methods.scroll.apply( $box, new Array( $(this).attr('scrollto') ) );
			});
			
			/*
			//var pos = 0;
			var setsButtOff = boxData.settings.buttons_offset;
			var buttOff = { 'top' : 0 ,'bottom' : 0 , 'left' : 0 , 'right' : 0 };
			if( setsButtOff )
			{
				//pos = setsButtOff;
				var buttOff = { 'top' : setsButtOff ,'bottom' : setsButtOff , 'left' : setsButtOff , 'right' : setsButtOff };
			}
			*/
			//$sbButtonPos.css({ props.pos = buttOff[props.pos];  });
			
			$sbArea.append( '<div class="adslider-slider adslider-slider-'+orient+' " style="'+startStyle+'"></div>' );
			
			$slider = $( 'div.adslider-slider', $sbArea );
			boxData.scrollBars[orient] = {
				'orient' : orient,
				'bar' : $scrollBar,
				'maxScroll' : maxScroll,
				'boxSize' : boxSize,
				'sbSize' : $sbArea[props.size]() - $slider[props.outerSize](),
				'slider' : $slider,
				'sliderSize' : $slider[props.outerSize](),
			};
			
			helper.setSlider( boxData.scrollBars[orient] , actScroll , props );
			
			$slider.unbind('mousedown touchstart').bind('mousedown touchstart',function( e ){
				//var $slider = $( this );
				e.preventDefault();
				e = helper.getEvent( e );
				helper.bindSlider( $box, boxData, $scrollBar,  $( this ), e , orient , helper.getProps( orient ) );
				return false;
			});
			
			$sbArea.unbind('mousedown touchstart').bind('mousedown touchstart', function( e ){
				e.preventDefault();
				e = helper.getEvent( e );
				var $scrollBar = $( this ),
					$slider = $( '.adslider-slider' , $scrollBar );
					sbOff = $scrollBar.offset(),
					props = helper.getProps( orient );
					evtActPos = e[ props.eProp ],
					//debug(evtActPos);
					posInSBar = evtActPos - sbOff[props.pos] - parseInt( $scrollBar.css('padding-'+props.pos) ) - parseInt( $scrollBar.css('border-'+props.pos+'-width') ) - Math.round( ( boxData.scrollBars[orient].sliderSize /2 ) );	
				//debug('POSINBAR',orient,posInSBar,boxData.scrollBars[orient].sbSize);
				if( posInSBar < 0 )
				{
					posInSBar = 0;	
				}
				else if( posInSBar > boxData.scrollBars[orient].sbSize )
				{
					posInSBar = boxData.scrollBars[orient].sbSize;
				}
				
				$slider.css( props.pos , posInSBar+'px');
				helper.setScroll( $box , boxData.scrollBars[orient] , posInSBar , props );
				$slider.data('adslider',{ newPos : posInSBar });
				
				helper.bindSlider( $box , boxData , $scrollBar , $slider , e , orient , props );
				
			});
			
		},
		
		
		bindSlider : function( $box , boxData, $bar , $slider , e , orient , props ) {
			var $bind = $('body'),
				evtStartPos = e[props.eProp],
				slrStartPos = parseInt( $slider.css( props.pos ) );	
					
			$bind.unbind('mouseup touchend').bind('mouseup touchend',function( e ){
				$bind.unbind('mousemove touchmove').unbind('mouseup touchend');
			});
			
			$bind.unbind('mousemove touchmove').bind('mousemove touchmove',function( e ){
				e = helper.getEvent( e );

				var evtActPos = e[props.eProp],
					evtPosDif = evtActPos - evtStartPos,
					slrOldPos = parseInt($slider.css(props.pos)),
					slrNewPos = slrStartPos + evtPosDif;

				//odczytanie sługości paska musi odbyć się wyżej
				if( slrNewPos > 0 && slrNewPos < boxData.scrollBars[orient].sbSize)
				{
					$slider.css(props.pos, slrNewPos+'px');
					helper.setScroll( $box , boxData.scrollBars[orient] , slrNewPos , props );
				}
				else
				{
					if( slrNewPos <= 0 )
					{
						$slider.css(props.pos, '0px');
						helper.setScroll( $box , boxData.scrollBars[orient] , 0 , props );
					}
					else
					{
						$slider.css(props.pos, boxData.scrollBars[orient].sbSize+'px');
						helper.setScroll( $box , boxData.scrollBars[orient] , boxData.scrollBars[orient].maxScroll  , props );
					}	
				}	
			});
		},
		
		clearScrollBars : function( boxData ){
			if( boxData.scrollBars.ver )
			{
				helper.clearScrollBar( boxData.scrollBars.ver );
			}
			if( boxData.scrollBars.hor )
			{
				helper.clearScrollBar( boxData.scrollBars.hor );
			}
		},
		
		clearScrollBar : function( dataBar ){
			if( dataBar.slider )
			{
				
			}
			if( dataBar.sliderArea )
			{
				
			}
			if( dataBar.buttonPos )
			{
				
			}
			if( dataBar.buttonCPos )
			{
				
			}
			if( dataBar.content )
			{
				
			}
			if( dataBar.bar )
			{
				
			}
			
		},
	};
	//*****************************************************************
	// HELPER END
	//*****************************************************************
	
	
	//*****************************************************************
	// METHODS - public methods
	//*****************************************************************
	var methods = {
		init : function( options ) {
			var sets = $.extend({}, defaults, options);
			return this.each(function(){
				var $this = $(this),
					data=$this.data('adslider');
				if(!data)
				{
					var data = {
						settings : sets,
						scrollBars : { 'ver' : false , 'hor' : false },
						target : $this,
					};
					//helper.initBars( data );
					$this.css('overflow','hidden').data( 'adslider', data );
					methods.initScrollBars.apply( $this, new Array() );
					
					if( sets.slider_size == 'box' )
					{
						$this.bind('resize',function(){
						});
					}
					var props = helper.getProps( 'ver' );
					//debug( props );
					$this.bind('mousewheel', function( e , delta ){
						e.preventDefault();
						if( delta > 0 ) {
							$this.scrollTop( Math.round ( $this.scrollTop() - ( Math.abs( delta * Number( data.settings.wheelscroll_step ) ) ) ) );
						}
						else {
							$this.scrollTop( Math.round ( $this.scrollTop() + ( Math.abs( delta * Number( data.settings.wheelscroll_step ) ) ) ) );
						}
						var actScroll = $this.scrollTop();
						helper.setSlider( data.scrollBars.ver , actScroll , props );
						return false;
					});

				}
       	});
		},
		
		
		initScrollBars : function( ){
			return this.each(function(){
				var $box = $(this),
					boxData = $box.data('adslider');
				if( !boxData )
				{
					return;
				}
				helper.initBars( boxData );
				if( boxData.scrollBars.ver.bar )
				{
					helper.initScrollBar( $box , boxData , 'ver' );
					
				}
				if( boxData.scrollBars.hor.bar )
				{
					helper.initScrollBar( $box , boxData , 'hor' );
					
				}
       	});
		},
		
		destroy : function( ){
			return this.each(function(){
				var $this = $(this),
					data=$this.data('adslider');
				if(data)
				{
					//if(data.settings.scrollBars.vertical)
					//{
					//	data.scrollBars.vertical.slider.remove();
						//$data.scrollBars.vertical.slider.hide();
					//	$(data.settings.scrollBars.vertical).hide();
					//}
					data = false;
					$this.data( 'adslider', data ).unbind('resize');
				}				
       	});
		},
		
		//settings change ( after change plugin will be reinited )
		option : function( options ){
			return this.each(function(){
				var $this = $(this),
					data=$this.data('adslider');
				if(data) {
					var sets = $.extend({}, data.settings, options);
					data.settings = sets;
					$this.data('adslider',data);
					methods.initScrollBars.apply( $this, new Array() );	
				}
       	});
		},
		

		
		scroll : function( direct ) {
			return this.each(function(){
				var $box = $(this),
					boxData = $box.data('adslider');
				if( !boxData ) {
					return;	
				}
				var slrObj = helper.getSliderByDirect( boxData , direct ),
					props = helper.getProps( slrObj.orient );
				if( props )
				{
					var startScroll = $box[ props.moveProp ]();
					if( slrObj.slider )
					{ 
						var params = {};
						var step =  Number(boxData.settings.scroll_range);
						if( direct == 'top' || direct == 'left' ) {
							step = -step;
						}
						params[ props.moveProp ] = startScroll + step;
						$box.stop();
						$box.animate( params , boxData.settings.scroll_time );
						helper.setSlider( slrObj.slider , params[ props.moveProp ] , props , boxData.settings.scroll_time );
					}	
				}
				
       	});
		},
		
		
	};
  	//**************************************************
  	// METHODS END
  	//**************************************************
	
	//*** plugin definition **************
	$.fn.adslider = function(method)
	{
		if ( methods[method] ) {
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.AdSlider' );
		}
	};
	//*** end plugin definition **************
	
})(jQuery);
