/***************************************************
The function is applied to the content-containing
element. The element must have a height set for it.
***************************************************/

(function($){

	$.fn.clikScroll = function(o){
		return this.each(function() {
            new $.cS(this, o);
        });
	}
	
	$.cS = function(e,options){
		
		options = $.extend({
			move:50,
			//speed:200,
			barWidth:20,
			barPosition:'right',
			contentSeparation:4,
			deactivatedClassUp:'deactivatedU',
			deactivatedClassDown:'deactivatedD',//Need separate deactive classes for IE6
			downControlClass: 'scrollControlD',
			upControlClass: 'scrollControlU',
			barClass: 'scrollBar',
			outerClass: 'scrollBarOuter'//,
			//controlSpace:5, Now set in style sheet and picked up via clikScroll
			//direction:'vertical' //Vertical or horizontal - NOT WORKING YET
		}, options || {});
				
		options.id = $(e).attr('id');//?$(e).attr('id'):'none';		
		options.topPos = 0;
		options.barTop = 0;
		//var running = false;
		
		/*options.contentH = $(e).height();
		options.contentW = $(e).width();
		options.parentH = $(e).parent().height();
		options.parentW = $(e).parent().width();*/
		
		/* Remove the scrollbar HTML if it's already there and store any position information, allowing us to run the function again to reset. */
		if($('div#innerWrap'+options.id).size() > 0 && $('div#outerWrap'+options.id).size() > 0){
			options.topPos = $('div#innerWrap'+options.id).position().top;
			options.barTop = $('div#bar'+options.id).position().top;			
			$('div#scrollBar'+options.id+'.'+options.outerClass).remove();
			$('div#innerWrap'+options.id).contents().appendTo($(e));
			$('div#outerWrap'+options.id).remove();
		}
		
		$(e).wrapInner('<div id="outerWrap'+options.id+'"><div id="innerWrap'+options.id+'"></div></div>');
		
		options.parentH = parseInt($(e).css('height'))?parseInt($(e).css('height')):$(e).height();
		options.parentW = parseInt($(e).css('width'))?parseInt($(e).css('width')):$(e).width();
		
		// Set the width of the wrapper before getting the height to allow for contriction from scroll bar
		options.contentW = $('div#outerWrap'+options.id).width(options.parentW - options.barWidth - options.contentSeparation - 2);
		options.contentH = $('div#outerWrap'+options.id).height();
		
		options.dspH = options.parentH - 
					((parseInt($(e).css('margin-top')) || 0) +
					(parseInt($(e).css('margin-bottom')) || 0));
		
		options.dspW = options.parentW - 
					((parseInt($(e).css('margin-left')) || 0) +
					(parseInt($(e).css('margin-right')) || 0));
		
		/* If the dimension available for display is less than that of the content then add what's needed */
		if(options.dspH < options.contentH){
			//$(e).wrapInner('<div id="outerWrap'+options.id+'"><div id="innerWrap'+options.id+'"></div></div>');
			$(e)
			.prepend(scrollbarHTML())
			.bind('mouseover',function(){
				$(document).bind('mousewheel DOMMouseScroll',mouseWheel);
			})
			.bind('mouseout',function(){
				$(document).unbind('mousewheel DOMMouseScroll',mouseWheel);
			});
			
			//var contentPadding = 'padding-'+options.barPosition;
			options.scrollBarBorder = parseInt($('div#scrollBar'+options.id).css('borderLeftWidth')) + 
									parseInt($('div#scrollBar'+options.id).css('borderRightWidth'));

			options.maxContentTop = -(options.contentH-options.dspH);
			
			options.topPos = options.topPos<options.maxContentTop?options.maxContentTop:options.topPos;
			
			$('div#innerWrap'+options.id)
			.css({
				height:options.contentH,
				position:'absolute',
				//position:'relative',
				top:options.topPos,
				left:0,
				width:options.parentW - options.barWidth - options.scrollBarBorder - options.contentSeparation
			});
			//Set padding as using variable name in object above doesn't work.
			$('div#innerWrap'+options.id).css('margin-'+options.barPosition,options.contentSeparation);
			
			options.contentPosition = options.barPosition === 'left'?'right':'left';
			outWidth = options.parentW - options.barWidth - options.scrollBarBorder;
			// Crappy browser detection for crappier IE6 which has a problem with italic text
			if($.browser.msie && $.browser.version < 7){outWidth -= 2;}
			$('div#outerWrap'+options.id).css({
				height:options.dspH,
				'overflow':'hidden',
				position:'relative',
				'float':options.contentPosition,
				width:outWidth
			});
			
			/*bg = $('span#scrollUp'+options.id)
			.css('background-image');*/
			
			$('span#scrollUp'+options.id+', span#scrollDown'+options.id)
			.css({
				position:'absolute',
				width:options.barWidth,
				'text-align':'center',
				left:0
			})
			.mouseover(function(){
				$(this).css({cursor:'pointer'});
			});
			
			options.upButtonH = $('span#scrollUp'+options.id)
			/*.css({
				//top:options.controlSpace
			})*/
			.click(function(){
				newPos = options.topPos + options.move;
				moveContent(newPos);
				return false;
			})
			.height();
			
			
			options.downButtonH = $('span#scrollDown'+options.id)
			/*.css({
				//bottom:options.controlSpace
			})*/
			.click(function(){
				newPos = options.topPos - options.move;
				moveContent(newPos);
				return false;
			})
			.height();
			
			options.controlSpace = parseInt($('span#scrollUp'+options.id).css('top'))>parseInt($('span#scrollDown'+options.id).css('bottom'))?
									parseInt($('span#scrollUp'+options.id).css('top')):
									parseInt($('span#scrollDown'+options.id).css('bottom'));
									
			/* Calculate track/bar relationship */
			//NOW DONE FUTHER UP options.maxContentTop = -(options.contentH-options.dspH);
			
			options.borderVertical = parseInt($('div#scrollBar'+options.id).css('borderTopWidth')) + parseInt($('div#scrollBar'+options.id).css('borderBottomWidth'));
			
			options.trackLen = options.dspH - (2*options.controlSpace) - options.upButtonH - options.downButtonH - options.borderVertical;
			
			options.fraction = options.dspH/options.contentH;
			
			options.barHeight = options.trackLen*options.fraction;
			
			options.maxBarTop = options.trackLen - options.barHeight;
			
			options.barTop = options.barTop>options.maxBarTop?options.maxBarTop:options.barTop;
			
			options.relation = options.maxBarTop/options.maxContentTop;
			
			$('div#scrollBar'+options.id)
			.css({
				'float':options.barPosition,
				height:options.dspH - options.borderVertical,
				width:options.barWidth,
				position:'relative'
			});
			
			$('div#barOuter'+options.id)
			.css({
				height:options.trackLen,
				width:options.barWidth,
				position:'absolute',
				top:options.controlSpace + options.upButtonH,
				left:0
			});
			
			$('div#barInner'+options.id)
			.css({
				height:options.trackLen,
				width:options.barWidth,
				position:'relative'
			});
			
			/*options.trackLen = options.dspH - (2*options.controlSpace) - options.upButtonH - options.downButtonH;
			fraction = options.dspH/options.contentH;*/
			//options.barMove = options.move*fraction;
			
			$('div#bar'+options.id)
			.css({
				height:options.barHeight,
				width:options.barWidth/2,
				//'margin-left':options.barWidth/4,
				//'margin-right':options.barWidth/4,
				position:'absolute',
				top:options.barTop,
				left:options.barWidth/4
			})
			.mousedown(dragStart)
			.mouseup(dragCancel)
			//.mouseout(dragCancel)
			.mouseover(function(){
				$(this).css({cursor:'pointer'});
			});
			
			$(document)
			.mouseup(dragCancel);
									
			toggleActiveControls();
						
		}
		else{
			//$(e).html($('div#innerWrap'+options.id).html());
			//$('div#innerWrap'+options.id).children().appendTo($(e));
			$('div#innerWrap'+options.id).contents().appendTo($(e));
			$('div#outerWrap'+options.id).remove();
			//$('div#outerWrap'+options.id,$(e)).replaceWith($('div#innerWrap'+options.id,$(e)).html());
		}
		
		function moveContent(pos,dragEvent){
			//if(!running){
				//running = true;
				pos>=0?pos=0:pos=pos;
				pos<-(options.contentH-options.dspH)?pos=-(options.contentH-options.dspH):pos=pos;
				
				// Move scroll bar
				//options.barTop = pos*options.relation;
				tmpBar = pos*options.relation;
				//$('div#bar'+options.id).animate({top:options.barTop});
				//$('div#bar'+options.id).css({top:options.barTop});
				$('div#bar'+options.id).css({top:tmpBar});
				//If this is NOT the scroll bar being dragged then set the global scroll bar position to be the newly calculated one.
				!dragEvent?options.barTop=tmpBar:false;
				/*$('div#innerWrap'+options.id)
				.animate({top:pos},options.speed,function(){
					//options.topPos = pos;
					//toggleActiveControls();					
					running = false;
				});*/
				
				$('div#innerWrap'+options.id).css({top:pos});
				
				options.topPos = pos;
				toggleActiveControls();					
				//running = false;
			//}			
		}
		
		function scrollbarHTML(){
			html = '';
			html += '<div id="scrollBar'+options.id+'" class="'+options.outerClass+'">';
			//html += '<a href="#" id="scrollUp'+options.id+'">U</a>';
			html += '<span id="scrollUp'+options.id+'" class="'+options.upControlClass+'">&nbsp;</span>'; // Set image for controls using background image on CSS
			html += '<div id="barOuter'+options.id+'">';
			html += '<div id="barInner'+options.id+'">';
			html += '<div id="bar'+options.id+'" class="'+options.barClass+'"></div>';
			html += '</div>';
			html += '</div>';
			//html += '<a href="#" id="scrollDown'+options.id+'">D</a>';
			html += '<span id="scrollDown'+options.id+'" class="'+options.downControlClass+'">&nbsp;</span>';
			html += '</div>';
			return html;
		}
		
		function toggleActiveControls(){
			options.topPos>=0?
				$('span#scrollUp'+options.id).addClass(options.deactivatedClassUp):
				$('span#scrollUp'+options.id).removeClass(options.deactivatedClassUp);
			options.topPos<=-(options.contentH-options.dspH)?
				$('span#scrollDown'+options.id).addClass(options.deactivatedClassDown):
				$('span#scrollDown'+options.id).removeClass(options.deactivatedClassDown);
		}
				
		function mouseWheel(event){
			move = 0;
			if(event.wheelDelta){
				move = event.wheelDelta/120;
			}
			if(event.detail){
				move = -(event.detail/3);
			}
			if(move != 0){
				newPos = options.topPos + (move*options.move);
				moveContent(newPos);				
			}
			return false;
		}
		
		var tmpBarTop = options.barTop;
		
		function dragFn(event){
			dX = event.pageX - startX;
			dY = event.pageY - startY;
			tmpBarTop = options.barTop + dY;
			moveContent(tmpBarTop/options.relation,1)
			return false;
		}
		
		function dragStart(event){
			startX = event.pageX;
			startY = event.pageY;
			$('div#bar'+options.id).mousemove(dragFn);
			$(document).mousemove(dragFn);
			return false;
		}
		
		function dragCancel(event){
			options.barTop = tmpBarTop;
			$($('div#bar'+options.id)).unbind('mousemove',dragFn);
			$(document).unbind('mousemove',dragFn);
		}
		
	}

})(jQuery)
