//= require "controldepo"
//= require <vendor/dragdrop>

Event.wheel = function(element, callback){
	var __onwheel = function(event){
		Event.stop(event);
		var delta = 0;
		if (!event)
			event = window.event;
		if (event.wheelDelta){
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail)
			delta = -event.detail/3;
		delta = Math.round(delta, event); //Safari Round
		callback(delta);
	}

	if(window.addEventListener)	// FF/DOM-Compliant Browsers
		$(element).addEventListener('DOMMouseScroll', __onwheel, false);
	else if(document.attachEvent) // IE
		$(element).observe('mousewheel', __onwheel);
};

CD3.Scroller = Class.create({
	initialize: function(container, scroller, options){
		// options
		options = Object.extend({
			styleArrow:		'arrow',
			styleMoveUp:	'moveup',
			styleMoveDown:	'movedown',
			styleSlider:	'slider',
			drag:           true,
			speed:			1
		}, options || {});					
		
		// base elements
		this.speed		= options.speed;
		this.container	= $(container);
		this.scroller	= $(scroller);
		this.handle		= this.scroller.down('.' + options.styleSlider);
		
		// arrows
		this.scroller.select('.' + options.styleArrow).each(function(stop, arrow){
			arrow.observe('mouseup',  stop);
			arrow.observe('mouseout', stop);
		}.curry(this.stopScroll.bind(this)));
		
		this.scroller.observe('mousedown', function(e){
			var arrow = e.findElement('.' + options.styleArrow);
			if (arrow) this.startScroll(arrow.hasClassName(options.styleMoveUp) ? -1 : 1);
		}.bind(this));
		
		// handle
		if (options.drag) new Draggable(this.handle,{ 
			constraint:	'vertical', 
			snap:		function(x, y){ return [x, this.validateTopPosition(y)]; }.bind(this),
			change:		this.traceHandlePosition.bind(this)
		});

		// trackpath
		var trackpath = $(this.handle.parentNode).observe('click', this.traceSliderClick.bind(this));
		
		this.trackpathPositionY	= trackpath.cumulativeOffset()[1];
		this.sliderMaxHeight	= trackpath.getHeight() - this.handle.getHeight();
					
		// wheel
		Event.wheel(this.container, this.traceMouseWheel.bind(this));
		
		// check if needed	
		this.checkIfneeded();
	},
	startScroll: function(value){
		this.interval = setInterval(this.scrollBy.bind(this, value), 3);
	},
	stopScroll: function(){
		clearInterval(this.interval);
		this.interval = null;
	},
	scrollBy: function(dir){
		this.handle.style.top = this.validateTopPosition( this.getScrollPosition() + dir * this.speed ) + 'px';
		this.traceHandlePosition();
	},
	setHandlePosition: function(){
		this.handle.style.top = (this.sliderMaxHeight * (this.container.scrollTop / this.getVisibleHeight())) + 'px';
	},
	validateTopPosition: function(y){
		if (y <= 0)						return 0;
		if (y >= this.sliderMaxHeight)	return this.sliderMaxHeight;
		
		return y;
	},
	traceHandlePosition: function(){
		this.container.scrollTop = this.getVisibleHeight() * (this.getScrollPosition() / this.sliderMaxHeight);
	},
	traceMouseWheel: function(delta){
		if (delta != 0) this.scrollBy(delta > 0 ? -15 : 15);			
	},
	traceSliderClick: function(e){
		var clickedY = e.pointerY()  - this.trackpathPositionY,
			top		 = this.getScrollPosition(),
			height	 = this.handle.getHeight();

		// check to see we are no clicking the handle
		if (clickedY < top || (top+height) < clickedY)
			new Effect.Morph(this.handle, {
				style:		 	{ top : this.validateTopPosition(clickedY) + 'px'},
				duration:	 	0.5,
				afterUpdate:	this.traceHandlePosition.bind(this),
				queue:			{scope: 'cd3:scroller', limit:1}
			});
	},
	getScrollPosition: function(){
		return parseInt(this.handle.style.top) || 0;
	},
	getVisibleHeight: function(){
		return this.container.scrollHeight - this.container.offsetHeight;
	},
	checkIfneeded: function(){
		this.scroller[this.container.scrollHeight > this.container.offsetHeight ? 'hide' : 'show']();
	}
});
CD3.Scroller.createIfNeeded = function(container, scroller, options){
	container  = $(container);

	if (container.scrollHeight <= container.offsetHeight){
		$(scroller).hide();
		return null;
	}
	
	return new CD3.Scroller(container, scroller, options);
}
@@ -35,617 +35,69 @@
 ire 
-%3Cvendor/dragdrop%3E%0A%0AEvent.wheel = function(element, callback)%7B%0A%09var __onwheel = function(event)%7B%0A%09%09Event.stop(event);%0A%09%09var delta = 0;%0A%09%09if (!event)%0A%09%09%09event = window.event;%0A%09%09if (event.wheelDelta)%7B%0A%09%09%09delta = event.wheelDelta/120; %0A%09%09%09if (window.opera) delta = -delta;%0A%09%09%7D else if (event.detail)%0A%09%09%09delta = -event.detail/3;%0A%09%09delta = Math.round(delta, event); //Safari Round%0A%09%09callback(delta);%0A%09%7D%0A%0A%09if(window.addEventListener)%09// FF/DOM-Compliant Browsers%0A%09%09$(element).addEventListener('DOMMouseScroll', __onwheel, false);%0A%09else if(document.attachEvent) // IE%0A%09%09$(element).observe('mousewheel', __onwheel);%0A%7D;
+%22extensions/events/mouse_wheel%22%0A//= require %3Cvendor/dragdrop%3E
 %0A%0ACD
@@ -1483,20 +1483,8 @@
 l%0A%09%09
-Event.wheel(
 this
@@ -1493,16 +1493,38 @@
 ontainer
+.observe('mouse:wheel'
 , this.t
@@ -1540,34 +1540,32 @@
 Wheel.bind(this)
-);
 %0A%09%09%0A%09%09// check i
@@ -2423,34 +2423,14 @@
 ion(
-delta)%7B%0A%09%09if (delta != 0) 
+e)%7B%0A%09%09
 this
@@ -2439,16 +2439,23 @@
 crollBy(
+e.memo.
 delta %3E 

use the custom mouse:wheel for CD3.Scroller