function ScrollManager()
{
	var targets 	= {};
	var current		= null;
	var selfRef		= this;
	var wheelTarget	= null;
	
	this.init	= function()
	{
		var sizeof = arguments.length;
		for(var counter = 0;counter < sizeof;counter++)
		{
			targets[arguments[counter]] = new Scroller(arguments[counter]);
			
			targets[arguments[counter]].getComponents().mainBox.wheelEnabled = true;
			EventUtils.addListener(targets[arguments[counter]].getComponents().mainBox, 'mouseover', selfRef.setWheelTarget);
			EventUtils.addListener(targets[arguments[counter]].getComponents().mainBox, 'mousewheel', selfRef.mouseWheel);
		}
	}
	
	this.reset	= function(elementID)
	{
		selfRef.release(null);
		current	= null;
		
		if(targets[elementID] != null)
			targets[elementID].finishListeners();

		targets[elementID]	= null;	
		targets[elementID]	= new Scroller(elementID);
		
		var components						= targets[elementID].getComponents();
		components.button_track.Controller	= targets[elementID];
	}
	
	this.getCurrent 	= function(){return current;}
	this.getTargets		= function(){return targets;}
	this.getTarget		= function(n){return targets[n] != null ? targets[n] : null;}
	
	this.setWheelTarget	= function(evt)
	{
		var target = evt.target != null ? evt.target : evt.srcElement;
		while(target != null && target.parentNode != null){if(target.wheelEnabled != null)break;target = target.parentNode;}
		if(target.wheelEnabled != null)wheelTarget = target;
	}
	
	this.setCurrent		= function(evt, target)
	{
		selfRef.release(evt);
		current = targets[target.getControlID()];
		current.setScrolling(true);
		this.startListener(evt);
	}
	
	this.mouseMove	= function(evt)
	{
		if(current == null || !current.isEnableBar()){selfRef.release(evt);return;}
			
		var offsetY		= current.getProperty('offsetY');
		if(offsetY == null)offsetY = 0;
		
		var components	= current.getComponents();
		var trackMin	= current.getProperty('trackMin');
		var trackMax	= current.getProperty('trackMax');
		
		var status		= '';
		
		var y			= (evt.clientY + trackMin) - offsetY;
		
		if(y < trackMin)y = trackMin;
		else if(y > trackMax)y = trackMax;
		
		components.button_track.style.top	= y + 'px';		
		selfRef.move(y);		
	}
	
	this.mouseUp	= function(evt){selfRef.release(evt);}	
	this.mouseOut	= function(evt)
	{
		var target = evt.target != null ? evt.target : evt.srcElement;
		if(target == document.body)selfRef.release(evt);
	}
	
	this.mouseWheel	= function(evt)
	{		
        var delta = 0;
		
        if(evt.wheelDelta)delta		= evt.wheelDelta / 120;
        else if(evt.detail)delta	= -evt.detail / 3;	
		
		if(wheelTarget == null)return;
		current						= targets[wheelTarget.id];
		
		if(current == null || !current.isEnableBar())return;
		
		var cont_height				= current.getComponents().content.measures.height;
		var bar_height				= current.getComponents().button_track.measures.height;		
		var base					= Math.round(7 * (bar_height / cont_height));
		
		if(base <= 2.5)base = 3;
		if(base >= 5)base = 5;
		
		var ratio = (base * -delta);
		selfRef.moveBy(current, ratio);
		
		current = null;
		
        if(evt.preventDefault)evt.preventDefault();
        evt.returnValue = false;
        return false;
	}
	
	this.click		= function(evt, mode)
	{	
		if(current != null && current.isScrolling())return;		
		current = targets[wheelTarget.id];
		
		var cont_height				= current.getComponents().content.measures.height;
		var bar_height				= current.getComponents().button_track.measures.height;		
		var base					= Math.round(7 * (bar_height / cont_height));
		
		if(base <= 2.5)base = 2.5;
		if(base >= 5)base = 5;
		
		var ratio = 0;
		if(mode == 'up')ratio = -base;
		else ratio = base;
		selfRef.moveBy(current, ratio);
		
		current.timeout = window.setTimeout('scrollManager.click(null,"' + mode + '")', 60);
		return false;
	}
	
	this.releaseClick	= function(evt)
	{
		if(current != null && current.timeout != null)window.clearTimeout(current.timeout);
		current = null;
	}
	
	this.moveBy = function(target, ratio)
	{
		var trackMin	= parseInt(target.getProperty('trackMin'));
		var trackMax	= parseInt(target.getProperty('trackMax'));
		var offsetY 	= parseInt(target.getProperty('offsetY'));
		var top			= parseInt(target.getComponents().button_track.style.top);
		
		if(isNaN(offsetY))offsetY = 0;
		if(isNaN(top))top = 0;
		
		top += ratio;
		
		if(top <= trackMin)top		= trackMin;
		else if(top >= trackMax)top = trackMax;		
		
		
		target.getComponents().button_track.style.top = Math.round(top) + 'px';			
		selfRef.move(top);
		
		if(target.getComponents().button_up != null)
			top -= target.getComponents().button_up.measures.height;
		
		target.setProperty('offsetY',top);
	}
	
	this.startListener = function(evt)
	{
		var source		= evt.target != null ? evt.target : evt.srcElement;
		source			= source.Controller;
		
		var currentY= parseInt(source.getProperty('offsetY'));
		if(isNaN(currentY))currentY = 0;
		
		source.setProperty('offsetY', evt.clientY - currentY);
		
		EventUtils.addListener(document, 'mousemove', scrollManager.mouseMove);
		EventUtils.addListener(document, 'mouseup', scrollManager.mouseUp);
		EventUtils.addListener(document.body, 'mouseout', scrollManager.mouseOut);
	}
	
	this.release	= function(evt)
	{
		if(current != null && evt != null)
		{			
			var pos		= parseInt(current.getComponents().button_track.style.top);
			if(isNaN(pos))pos = 0;			
			var currentY= isNaN(current.getProperty('offsetY')) ? 0 : parseInt(current.getProperty('offsetY'));
			current.setProperty('offsetY', evt.clientY - currentY);
			current.setScrolling(false);
		}
		
		current		= null;
		EventUtils.removeListener(document, 'mousemove', scrollManager.mouseMove);
		EventUtils.removeListener(document, 'mouseup', scrollManager.mouseUp);
		EventUtils.removeListener(document.body, 'mouseout', scrollManager.mouseOut);
	}
	
	this.move		= function(pos)
	{
		var selectObj	= null;
		var trackMin	=	current.getProperty('trackMin') * 1;
		var trackMax	=	current.getProperty('trackMax') * 1;
		
		pos 			-=	trackMin;		
		var components	=	selfRef.getCurrent().getComponents();		
		var up_measures =	components.button_up != null ? components.button_up.measures : {'height': 0};
		var el_pos		=	Math.round(pos * selfRef.getCurrent().getProperty('ratio'));
		el_pos 			*=	-1;
		
		if (window.getSelection)selectObj = window.getSelection();
		else if (document.getSelection)selectObj = document.getSelection();
		else if (document.selection)selectObj = document.selection;
		
		if(selectObj != null && selectObj.empty)selectObj.empty();
		else if(selectObj != null && selectObj.removeAllRanges)selectObj.removeAllRanges();
		components.content.style.top = el_pos + 'px';
	}
}