window.scrollers={pixelsPerStep:20};
window.scrollers.activeScroller=0;
window.scrollers.init=function(ids,width,height) {
	if($(ids+'_scroller')==null) {
		if(!window.scrollers[ids]) window.scrollers[ids]={numtries:0};
		window.scrollers[ids].numtries+=1;
		if(window.scrollers[ids].numtries>10) {
//			alert("error adding scroller '"+ids+"'");
		} else {
			setTimeout(function() { window.scrollers.init(ids, width,height); }, 500);			
		}
		return;
	}

	if(!window.scrollers[ids]) window.scrollers[ids]={};
	var scrl=window.scrollers[ids];
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	
	
	if(!( sr && sh && sc && sa)) return;

  scrl.controlWidth=width;
	scrl.controlHeight=height;
	scrl.scrollWidth=sr.getWidth();
	
//	scrl.changed=window.scrollers.resizefunction.bindAsEventListener(scrl,ids);
//	sc.observe('DOMSubtreeModified',scrl.changed);
//	scrl.changed2=window.scrollers.resizefunction.bindAsEventListener(scrl,ids);
//	sa.observe('DOMAttrModified',scrl.changed2);
	scrl.refresher=setInterval(function() { window.scrollers.resizefunction({},ids); },1500);
	
	scrl.mousedown=window.scrollers.pressfunction.bindAsEventListener(scrl,ids);
	sr.observe('mousedown',scrl.mousedown);
	
	scrl.scup=window.scrollers.scrollfunction.bindAsEventListener(scrl,ids,-1);
	$(ids+'_scrollup').observe('mousedown',scrl.scup);

	scrl.scdown=window.scrollers.scrollfunction.bindAsEventListener(scrl,ids,1);
	$(ids+'_scrolldown').observe('mousedown',scrl.scdown);
	scrl.scwheel=window.scrollers.wheelfunction.bindAsEventListener(scrl,ids);
	$(ids+'_scrollarea').observe('DOMMouseScroll',scrl.scwheel);
	$(ids+'_scroller').observe('DOMMouseScroll',scrl.scwheel);

	if((window.attachEvent && !window.opera)) {
			sh.ondragstart=function() {
				return false;
			}
	}

	scrl.contentHeight=sc.getHeight();
	scrl.areaHeight=sa.getHeight()
  if(scrl.contentHeight==0) scrl.contentHeight=1;
	var len=1.0*scrl.areaHeight/scrl.contentHeight;
	scrl.len=len;
	scrl.scrollHeight=sr.getHeight()-sh.getHeight();
  if(scrl.scrollHeight==0) scrl.scrollHeight=1;
	var pos=0.0;
	
	if(len>=1) {
		sc.style.top='0px';
		sh.style.top='0px';
		scrl.top=0;
		scrl.pos=0;
		if(scrl.hideStyle=='visibility') $(ids+'_scrollercontainer').style.visibility='hidden';
		else $(ids+'_scrollercontainer').style.display='none';
		$(ids+'_scrollarea').style.width=(scrl.controlWidth)+'px';
	} else {
	  sh.style.height='20px';
		//sh.style.height=(len*sr.getHeight())+'px';
		scrl.pos=pos;
		sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
		sh.style.top=(pos*(scrl.areaHeight-sh.getHeight()))+'px';
		if(scrl.hideStyle=='visibility') $(ids+'_scrollercontainer').style.visibility='visible';
		else $(ids+'_scrollercontainer').style.display='';
		scrl.scrollWidth=sr.getWidth();
		$(ids+'_scrollarea').style.width=(scrl.controlWidth-scrl.scrollWidth)+'px';
	}
}

window.scrollers.wheelfunction=function(ev,ids){
	var delta = 0;
	if (!ev) ev = window.event;
	if (ev.wheelDelta) {
		delta = ev.wheelDelta/120;
		if (window.opera) delta = -delta;
	} else if (ev.detail) {
		delta = -ev.detail/3;
	}
	if (delta) {
		window.scrollers.scrollfunction(ev,ids,-delta);
		window.scrollers.stopscrollfunction(ev,ids);
	}
	if (ev.preventDefault) ev.preventDefault();
	ev.returnValue = false;
}

window.scrollers.resizefunction=function(ev,ids) {
	var targ;
	var scrl=window.scrollers[ids];

/*	if (ev.target) targ=ev.target;
	else if (ev.srcElement) targ=ev.srcElement;
	if (targ.nodeType==3) targ = targ.parentNode;
*/
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	if(sc==null || sa==null) return;
	
	if(scrl.contentHeight==sc.getHeight() && scrl.areaHeight==sa.getHeight()) {
		scrl.lastsah=sa.getHeight();
		if(!scrl.refreshes) scrl.refreshes=0;
		scrl.refreshes=scrl.refreshes+1;
		return;
	}
	$(ids+'_scrollercontainer').style.display='';
	scrl.contentHeight=sc.getHeight();
	scrl.areaHeight=sa.getHeight();
    if(scrl.contentHeight==0) scrl.contentHeight=1;
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	
	var len=1.0*scrl.areaHeight/scrl.contentHeight;
	scrl.scrollHeight=sr.getHeight()-sh.getHeight();
    if(scrl.scrollHeight==0) scrl.scrollHeight=1;
	scrl.len=len;
	if(len>=1) {
		sc.style.top='0px';
		sh.style.top='0px';
		scrl.top=0;
		scrl.pos=0;
		if(scrl.hideStyle=='visibility') $(ids+'_scrollercontainer').style.visibility='hidden';
		else $(ids+'_scrollercontainer').style.display='none';
		$(ids+'_scrollarea').style.width=(scrl.controlWidth)+'px';
	} else {
		var pos=1.0*parseInt(sh.style.top)/(scrl.scrollHeight);
		if(pos>1) {
			pos=1.0;
		}
		scrl.pos=pos;
		sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
		sh.style.top=(pos*scrl.scrollHeight)+'px';
		if(scrl.hideStyle=='visibility') $(ids+'_scrollercontainer').style.visibility='visible';
		else $(ids+'_scrollercontainer').style.display='';
		scrl.scrollWidth=sr.getWidth();
		$(ids+'_scrollarea').style.width=(scrl.controlWidth-scrl.scrollWidth)+'px';
	}
}
window.scrollers.pressfunction=function(ev,ids) {
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	

	var px=Event.pointerX(ev);
	var py=Event.pointerY(ev);

//	$('debug').innerHTML+='pressfunction x:'+px+',y:'+py+'<br>';
	if(sh.cumulativeOffset().top>py) {
		var pos=scrl.pos-scrl.len;
		if(pos<0.0) {
			pos=0.0;
		}
		sc.style.top=(-pos*(1-scrl.len)*scrl.contentHeight)+'px';
		sh.style.top=(pos*scrl.scrollHeight)+'px';		
		scrl.pos=pos;
	}
	else if(sh.cumulativeOffset().top+sh.getHeight()<py) {
		pos=scrl.pos+scrl.len;
		if(pos>1.0) {
			pos=1.0;
		}
		sc.style.top=(-pos*(1-scrl.len)*scrl.contentHeight)+'px';
		sh.style.top=(pos*scrl.scrollHeight)+'px';		
		scrl.pos=pos;
	} else {
	
		scrl.startpos=scrl.pos;
		scrl.scrollerpos=sr.cumulativeOffset();
		scrl.startx=Event.pointerX(ev);
		scrl.starty=Event.pointerY(ev);
		
		if((window.attachEvent && !window.opera)){
			
			window.scrollers.activeScroller=ids;
			document.body.onmousemove=window.scrollers.msiedragfunction;
			//document.getElementById(ids+'_scrollhandle').onmouseup=window.scrollers.msiereleasefunction;
//			document.getElementById(ids+'_scrollarea').onmouseout=window.scrollers.msiereleasefunction;
			document.body.onmouseup=window.scrollers.msiereleasefunction;
		}
		else{
			
			scrl.mousemove=window.scrollers.dragfunction.bindAsEventListener(scrl,ids);
			document.body.observe('mousemove',scrl.mousemove);
			scrl.mouseup=window.scrollers.releasefunction.bindAsEventListener(scrl,ids);
			document.body.observe('mouseup',scrl.mouseup);
			
		}
	}
	ev.stop();
}
window.scrollers.releasefunction=function(ev,ids) {
	var scrl=window.scrollers[ids];
//	$('debug').innerHTML+='releasefunction<br>';
	
	Event.stopObserving(document.body,'mousemove',scrl.dragfunction);
	Event.stopObserving(document.body,'mouseup',scrl.mouseup);
}
window.scrollers.msiedragfunction=function(ev) {
	var ids=window.scrollers.activeScroller;
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	
	var len=scrl.len;
	var px=event.clientX;
	var py=event.clientY;
	
	var dy=(py-scrl.starty)/scrl.scrollHeight;
	
	scrl.pos=scrl.startpos+1.0*dy;
	if(scrl.pos<0.0) scrl.pos=0.0;
	if(scrl.pos>1.0) scrl.pos=1.0;
	var pos=scrl.pos;
	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
}

window.scrollers.msiereleasefunction=function(ev) {
	var ids=window.scrollers.activeScroller;
	document.body.onmousemove="";
	//document.getElementById(ids+'_scrollhandle').onmouseup="";
	//document.getElementById(ids+'_scrollarea').onmouseout="";
	document.body.onmouseup="";
}
window.scrollers.dragfunction=function(ev,ids) {
	
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	
	var len=scrl.len;
	
	var px=Event.pointerX(ev);
	var py=Event.pointerY(ev);
	var dy=(py-scrl.starty)/scrl.scrollHeight;

	scrl.pos=scrl.startpos+1.0*dy;
	if(scrl.pos<0.0) scrl.pos=0.0;
	if(scrl.pos>1.0) scrl.pos=1.0;
	var pos=scrl.pos;

//	$('debug').innerHTML+='dragfunction x:'+px+',y:'+py+',pos:'+pos+'<br>';

	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
}
window.scrollers.scrollfunction=function(ev,ids,dir) {

	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');	

	scrl.pos+=dir*1.0*window.scrollers.pixelsPerStep/scrl.contentHeight;
	if(scrl.pos<0.0) scrl.pos=0.0;
	if(scrl.pos>1.0) scrl.pos=1.0;
	var len=scrl.len;
	var pos=scrl.pos;

	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
	if(!scrl.timer) {
		scrl.scstop=window.scrollers.stopscrollfunction.bindAsEventListener(scrl,ids);
		document.body.observe('mouseup',scrl.scstop);
	}
	if(!((scrl.pos==1.0 && dir==1)||(scrl.pos==0.0 && dir==-1))) scrl.timer=setTimeout(function() { window.scrollers.scrollfunction(null,ids,dir); }, 100 ); 
	else window.scrollers[ids].timer=null;
}
window.scrollers.stopscrollfunction=function(ev,ids) {

	if(window.scrollers[ids].timer) {
		clearTimeout(window.scrollers[ids].timer);
		window.scrollers[ids].timer=null;
		Event.stopObserving(document.body,'mouseup',window.scrollers[ids].scstop);
	}
}
window.scrollers.scrollToPos=function(ids,pos) { //0..1
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');
	var len=scrl.len;

	if(pos<0.0) pos=0.0;
	if(pos>1.0) pos=1.0;
	scrl.pos=pos;

	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
}
window.scrollers.scrollToPx=function(ids,pos) {//0..<content height>
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');
	var len=scrl.len;

	if(pos<0.0) pos=0.0;
	if(pos>scrl.contentHeight) pos=scrl.contentHeight;
	pos/=scrl.contentHeight;
	scrl.pos=pos;

	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
}
window.scrollers.scrollToElement=function(ids,element) {//element should be inside scroll content
	var scrl=window.scrollers[ids];
	if(scrl.len>1.0) return;
	var sc=$(ids+'_scrollcontent');
	var sa=$(ids+'_scrollarea');
	var sh=$(ids+'_scrollhandle');
	var sr=$(ids+'_scroller');
	var len=scrl.len;
	if(!$(element).descendantOf(sc)) return;

	var pos=$(element).cumulativeOffset().top-sc.cumulativeOffset().top;
	pos+=sa.getHeight()*(pos/scrl.contentHeight);
	
	if(pos<0.0) pos=0.0;
	if(pos>scrl.contentHeight) pos=scrl.contentHeight;
	pos/=scrl.contentHeight;
	scrl.pos=pos;

	sc.style.top=(-pos*(1-len)*scrl.contentHeight)+'px';
	sh.style.top=(pos*scrl.scrollHeight)+'px';
}

var Browser = Class.create({
	  initialize: function() {
	    var userAgent = navigator.userAgent.toLowerCase();
	    this.version = (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1];
	    this.safari = /webkit/.test( userAgent );
	    this.opera = /opera/.test( userAgent );
	    this.msie = /msie/.test( userAgent ) && !/opera/.test( userAgent );
	    this.mozilla = /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent );
	  }
	});

