
img_sc_wheel_speed = 1;
img_sc_button_speed = 1;

function img_makeScrollArea() {
	var sa = document.createElement('div');
	sa.inner = document.createElement('div');
	sa.appendChild(sa.inner);
	
	sa.className = 'scrollArea';
	sa.inner.className = 'scrollAreaInner';
	
	img_init_rect(sa);
	img_init_rect(sa.inner);
	
	sa.setScrollPx = function(px) {
		if(isNaN(px)) px = 0;
		sa.inner.style.top = -px+'px';
		sa.sa_scroll = px;
	};
	sa.getScrollPx = function() {
		return sa.sa_scroll;
	};
	sa.getInnerSize = function() {
		return sa.inn_size;
	};
	sa.getOuterSize = function() {
		return sa.out_size;
	};
	sa.getMaxScroll = function() {
		return Math.max(0, sa.getInnerSize() - sa.getOuterSize());
	};
	sa.getScrollPerc = function() {
		return sa.getScrollPx() / sa.getMaxScroll();
	};
	sa.setScrollPerc = function(perc) {
		sa.setScrollPx(perc * sa.getMaxScroll());
	}; 
	
	sa.updateDim = function() {
		sa.out_size = sa.getRect().h;
		sa.inn_size = sa.inner.getRect().h;
	};
	
	sa.sa_scroll = 0;
	
	return sa;
}

function img_makeScroller() {
	var sc = document.createElement('div');
	sc.inner = document.createElement('div');

	sc.inner.box = document.createElement('div');
	sc.appendChild(sc.inner);
	sc.inner.appendChild(sc.inner.box);
	sc.className = 'scroller';
	sc.inner.className = 'scrollerBarOuter';
	sc.inner.box.className = 'scrollerBar';
	
	img_init_rect(sc);
	img_init_rect(sc.inner);
	
	sc.last_mouse = null;
	sc.startDrag = function(ev) {
		sc.last_mouse = img_getMousePos(ev);
		sc.inner.className = 'scrollerBarOuter scrollerBarOuterClicked';
		img_registerEvent(document, 'mousemove', sc.mouseMove);
		img_registerEvent(document, 'mouseup', sc.endDrag);
		document.onmousedown = function() {return false;} /* This is used to prevent selection dragging bugs (found somewhere and it works) */
		return false;
	};
	sc.mouseMove = function(ev) {
		if(!sc.last_mouse) return;
		var mouse = img_getMousePos(ev);
		var diff = img_subVector(mouse, sc.last_mouse);
				
		var ov = sc.getMaxScroll() - (sc.getScrollPx() + diff.y);
		if(ov < 0) {
			mouse.y += ov;
			diff.y += ov;
		}
		var ov2 = sc.getScrollPx() + diff.y;
		if(ov2 < 0) {
			mouse.y -= ov2;
			diff.y -= ov2;
		}
		sc.last_mouse = mouse;
		sc.diffScroll(diff.y);
		return false;
	};
	sc.endDrag = function() {
		sc.last_mouse = null;
		sc.inner.className = 'scrollerBarOuter';
		img_unregisterEvent(document, 'mousemove', sc.mouseMove);
		img_unregisterEvent(document, 'mouseup', sc.endDrag);
		document.onmousedown = null;
		return false;
	};
	sc.inner.onmousedown = function(ev) {
		sc.startDrag(ev);
	}
	sc.onclick = function(ev) {
		/* Make the bar jump to clicked position on the scroller */
		var pos = img_getMousePos(ev).y;
		pos -= sc.getRect().y; // make it relative to the bar
		
		if(pos >= sc.sc_scroll && pos <= sc.sc_scroll+sc.getInnerSize()) {
			/* A click within the bar -> cancel */
			return;
		}
		
		var bar_pos = pos - (sc.getInnerSize()/2);
		if(bar_pos < 0) bar_pos = 0;
		if(bar_pos > sc.getMaxScroll()) bar_pos = sc.getMaxScroll();
		
		sc.setScrollPx(bar_pos);
		if(sc.onScrollMove) sc.onScrollMove(sc.getScrollPerc());
	};
	
	sc.diffScroll = function(px) {
		sc.setScrollPx(sc.getScrollPx() + px);
		if(sc.onScrollMove) sc.onScrollMove(sc.getScrollPerc());
	};
	sc.getScrollPx = function() {
		return sc.sc_scroll;
	};
	sc.setScrollPx = function(px) {
		px = Math.min(sc.getMaxScroll(), Math.max(0, px));
		if(!isNaN(px)) sc.inner.style.top = px+'px';
		sc.sc_scroll = px;
	};
	sc.getInnerSize = function() {
		return sc.inn_size;
	};
	sc.getOuterSize = function() {
		return sc.out_size;
	};
	sc.getMaxScroll = function() {
		return Math.max(0, sc.getOuterSize() - sc.getInnerSize());
	};
	sc.getScrollPerc = function() {
		if(sc.getMaxScroll() == 0) return 1;
		return Math.max(0, Math.min(1, sc.getScrollPx() / sc.getMaxScroll()));
	};
	sc.setScrollPerc = function(perc) {
		sc.setScrollPx(perc * sc.getMaxScroll());
	};
	sc.diffScrollPerc = function(perc) {
		sc.setScrollPerc(sc.getScrollPerc() + perc);
		if(sc.onScrollMove) sc.onScrollMove(sc.getScrollPerc());
	};
	sc.updateDim = function() {
		sc.out_size = sc.getRect().h;
		sc.inn_size = sc.inner.getRect().h;
	};
	
	sc.setInnerSize = function(px) {
		var perc = sc.getScrollPerc();
		if(px < 0) px = 0;
		if(!isNaN(px)) sc.inner.style.height = px+'px';
		sc.updateDim();
		sc.setScrollPerc(perc);
	};
	
	sc.setupFrom = function(sa) {
		var inner_size = sc.getOuterSize() * sa.getOuterSize() / sa.getInnerSize();
		inner_size = Math.max(10, Math.min(sc.getOuterSize(), inner_size));
		inner_size = Math.min(inner_size, sc.getOuterSize());
		
		sc.setInnerSize(inner_size);
		sc.setScrollPerc(sa.getScrollPerc());
	};
	
	sc.sc_scroll = 0;
	
	return sc;
}

function img_makeScrollButton(button_class) {
	var but = document.createElement('div');
	but.inner = document.createElement('div');
	but.appendChild(but.inner);
	
	img_init_rect(but);
	
	but.className = 'scrollButton '+button_class;
	but.inner.className = 'scrollButtonInner';
	
	but.clicked = false;
	
	but.onmousedown = function() {
		if(but.clicked) return;
		but.clicked = true;
		but.className = 'scrollButton scrollButtonClicked '+button_class;
		
		img_interpol().loop(function(time) {
			
			if(but.call) but.call(time);
			
			if(but.clicked) {
				return true;
			} else {
				return false;
			}
		});
	};
	but.onmouseup = function() {
		but.clicked = false;
		but.className = 'scrollButton '+button_class;
	};
	but.onmouseout = function() {
		but.clicked = false;
		but.className = 'scrollButton '+button_class;
	};
	
	return but;
}

function img_makeScrollSide() {
	var ss = document.createElement('div');
	ss.scroller = img_makeScroller();
	ss.up = img_makeScrollButton('up');
	ss.down = img_makeScrollButton('down');
	
	ss.appendChild(ss.up);
	ss.appendChild(ss.scroller);
	ss.appendChild(ss.down);
	
	ss.className = 'scrollSide';
	
	ss.up.call = function(time) {
		ss.scroller.diffScrollPerc(-img_sc_button_speed*time);
	};
	ss.down.call = function(time) {
		ss.scroller.diffScrollPerc(img_sc_button_speed*time);
	};
	
	ss.setHeight = function(px) {
		var uh = ss.up.getRect().h;
		var dh = ss.down.getRect().h;

		var h = Math.max(0, px-uh-dh);
		if(!isNaN(h)) ss.scroller.style.height = h+'px';
		
		ss.scroller.updateDim();
	};
	
	return ss;
}

function img_makeScrollable() {
	var sl = document.createElement('div');
	sl.sarea = img_makeScrollArea();
	sl.sside = img_makeScrollSide();
	sl.appendChild(sl.sside);
	sl.appendChild(sl.sarea);
	
	sl.className = 'scrollable';
	
	img_init_rect(sl);
	
	sl.updateDim = function() {
		sl.sside.setHeight(sl.getRect().h);
		sl.sarea.updateDim();
		sl.sside.scroller.setupFrom(sl.sarea);
	};
	
	sl.getInner = function() {
		return sl.sarea.inner;
	};
	
	sl.sside.scroller.onScrollMove = function(perc) {
		sl.sarea.setScrollPerc(perc);
	};
	
	sl.dispatchScroll = function(ev) {
		if (!ev) ev = window.event;
		
		var delta = 0;
		if(ev.wheelDelta) {
			delta = ev.wheelDelta/120;
		} else if(ev.detail) {
			delta = -ev.detail/3;
		}
		if(delta) sl.handleScroll(delta);
		
		/* Spent muuch time looking for this lil stupid method... */
		if(ev.preventDefault) ev.preventDefault();
		
		return false;
	};
	sl.handleScroll = function(delta) {
		var perc = sl.sarea.getOuterSize() / sl.sarea.getInnerSize() * img_sc_wheel_speed;
		
		if(delta < 0) {
			sl.sside.scroller.diffScrollPerc(perc);
		} else {
			sl.sside.scroller.diffScrollPerc(-perc);
		}	
	};
	
	if(sl.addEventListener) sl.addEventListener('DOMMouseScroll', sl.dispatchScroll, false);
	sl.onmousewheel = sl.dispatchScroll;

	sl.updateDim();
	
	return sl;
}

function img_init_scrollable(el) {
	var par = el.parentNode;
	var sl = img_makeScrollable();
	par.insertBefore(sl, el);
	par.removeChild(el);
	sl.getInner().appendChild(el);
	return sl;
}


if (typeof(Sys) == 'undefined') 
    Sys.Application.notifyScriptLoaded();  
