dom = {
	CLASSSEPERATOR :    '(?:^|$|[^A-Za-z0-9_\\-])',
	getClass : function(node){
		return node ? node.className || node.getAttribute("class") || '' : null;
	},
	getClasses : function(node, seperator){
		var
			classStr = dom.getClass(node)
		;
		return (
			classStr ? classStr.split(seperator || dom.CLASSSEPERATOR) : classStr
		);
	},
	getElementsByClass : function(nodes, classPattern){
		var
			i,
			elements = []
		;
		classPattern = dom.getClassRegExp(classPattern);
		for(i = nodes.length -1; i >= 0; i--){
			if(nodes[i].nodeType == 1 && classPattern.test(dom.getClass(nodes[i]))){
				elements.push(nodes[i]);
			}
		}
		return elements;
	},
	getClassRegExp : function(className, seperator){
		seperator = seperator || dom.CLASSSEPERATOR;
		return (
			className && className.constructor == RegExp
			? className
			: new RegExp(seperator + className + seperator)
		);
	},
	getComputedStyle : function(node, prop) {
		var
			style = "",
			win = this.getDefaultView(node)
		;
		if (win.getComputedStyle) {
			style = win.getComputedStyle(node, '')
				.getPropertyValue(prop.replace(/([A-Z])/g, "-$1").toLowerCase())
			;
		} else if(node.currentStyle) {
			style = node.currentStyle[prop];
		}
		return style;
	},
	getDefaultView : function (obj){ // node or document or window 
		var doc = obj.nodeType == 9 ? obj : obj.ownerDocument;
		return doc ? doc.defaultView || doc.parentWindow : obj;
	},
  getPageY : function(evt){
    var y = 0;
    if(typeof evt.pageY == "number") {
      y = evt.pageY;
    } else if(typeof evt.clientY == "number"){
      y = evt.clientY;
    }
    return y;
  },
	cancelEvent : function (event){
		/*
		event.preventDefault();
	  event.preventBubble();
	  event.preventCapture();
		*/
		if(typeof event.stopPropagation != "undefined") {
			event.stopPropagation();
		} else event.canelBubble = true;
	}
};

ScrollBox = function(scrollBarV, contentBox, scrollPosHash) {
	var scrollBox = this; // for all closures ...
	var subEls = scrollBarV.getElementsByTagName("*");
	this.contentBox = contentBox;
	this.scrollBarV = scrollBarV;
	this.upButton = dom.getElementsByClass(subEls, "up")[0];
	this.downButton = dom.getElementsByClass(subEls, "down")[0];
	this.slider = dom.getElementsByClass(subEls, "slider")[0];
	this.sliderTop = dom.getElementsByClass(this.slider.childNodes, "top")[0];
	this.sliderBottom = dom.getElementsByClass(this.slider.childNodes, "bottom")[0];
	this.SCROLLSTEPSIZE = 1;
	this.SLIDERSIZEMIN = 8;
	this.currentScrollSize = 0;
	this.dragSession = {
		active : false,
		startY : 0,
		sliderTop : 0
	};
	
	this.getSliderSize = function() {
		return parseInt(
			dom.getComputedStyle(this.sliderBottom, "marginTop")
		);
	};
	this.getSliderTop = function() {
		return parseInt(
			dom.getComputedStyle(this.slider, "top")
		);
	};
	this.getVisiblePartHeight = function() {
		return this.scrollBarV.offsetHeight() / this.contentBox.offsetHeight;
	};
	
	this.slider.onmousedown = function (evt) {
		evt = evt || window.event;
		if(evt.button == 0 || evt.button == 1) {
			scrollBox.dragSession.active = true;
			scrollBox.dragSession.startY = dom.getPageY(evt);
			scrollBox.dragSession.sliderTop = scrollBox.getSliderTop();
			dom.cancelEvent(evt);
			evt.preventDefault();
		};
	};
	this.upButton.onmousedown = this.downButton.onmousedown = function (evt) {
		evt = evt || window.event;
		if(evt.button == 0 || evt.button == 1) {
			scrollBox.currentScrollSize
				= scrollBox.SCROLLSTEPSIZE
				* (this === scrollBox.upButton? -1 : 1)
			;
			scrollBox.scrollInterval(true);
			dom.cancelEvent(evt);
		};
	};
	
	this.scrollBarV.onmousedown = function (evt) {
		evt = evt || window.event;
		if(
			evt.button == 0 || evt.button == 1
			&&
			(evt.target || evt.srcElement) === scrollBox.scrollBarV
		) {
			var
				pos = typeof evt.layerY != "undefined"
					? evt.layerY
					: evt.offsetY
				,
				dir
					= pos - scrollBox.upButton.offsetHeight
					< Math.abs(scrollBox.getSliderTop() - scrollBox.sliderTopMin)
					? -1
					:1
			;
			scrollBox.currentScrollSize = scrollBox.getSliderSize() * dir;
			scrollBox.scrollInterval(true);
			dom.cancelEvent(evt);
		}
	};
	
	this.scrollInterval = function(first) {
		if (this.currentScrollSize != 0) {
			scrollBox.moveSliderBy(this.currentScrollSize);
			setTimeout(function(){scrollBox.scrollInterval()}, first ? 500 : 50);
		}
	}
	
	this.moveSliderBy = function(distance) {
		this.moveSliderTo(scrollBox.getSliderTop() + distance);
	}
	
	this.scrollBarV.onmouseup
		= this.upButton.onmouseup
		= this.downButton.onmouseup
		= this.scrollBarV.onmouseout
		= this.upButton.onmouseout
		= this.downButton.onmouseout = function() {
		scrollBox.currentScrollSize = 0;
	};
	
	document.onmousemove = function(evt) {
		evt = evt || window.event;
		if(scrollBox.dragSession.active) {
			scrollBox.moveSliderTo(
				scrollBox.dragSession.sliderTop
				- scrollBox.dragSession.startY
				+ dom.getPageY(evt)
			);
		};
	};
	
	this.moveSliderTo = function(top) {
		if(top <  scrollBox.sliderTopMin) {
			top = scrollBox.sliderTopMin;
		} else if(top >  scrollBox.sliderTopMax) {
			top = scrollBox.sliderTopMax;
		}
		scrollBox.slider.style.top = top + "px";
		scrollBox.scrollContentBox(scrollBox.getSliderPos());
		return top;
	};

	document.onmouseup = function(evt) {
		scrollBox.dragSession.active = false; 
	};
	
	document.onmousedown = function(evt) {
		evt = evt || window.event;
		if (typeof evt.preventDefault != 'undefined') {
			evt.preventDefault();
		};
	};
	document.onselectstart = function() {
		return false;
	};
	
	this.getSliderPos = function() {
		pos = 0;
		if(this.sliderSize < this.sliderSizeMax) { 
			pos = 
				Math.abs(this.sliderTopMin - parseInt(dom.getComputedStyle(this.slider, "top")))
				/
				(this.sliderSizeMax - this.sliderSize)
			;
		};
		return pos;
	};
	
	this.setSliderSize = function() {
		var size = Math.round(this.sliderSizeMax * this.sliderRatio);
		if (size <  this.SLIDERSIZEMIN) {
			size = this.SLIDERSIZEMIN;
		} else if (size > this.sliderSizeMax) {
			size = this.sliderSizeMax;
		} else if (this.sliderRatio < 1 && size == this.sliderSizeMax) {
			size = this.sliderSizeMax - 1;
		};
		this.sliderBottom.style.marginTop
			= size
			- this.sliderTop.offsetHeight
			- this.sliderBottom.offsetHeight
			+ "px"
		;
		return size;
	};

	this.scrollContentBox = function (pos) {
		var top = Math.round(
			(this.contentBox.offsetHeight - this.scrollBarV.offsetHeight) * -pos
		);
		scrollBox.contentBox.style.top = top + "px";
	};
	
	this.init = function(pageLoaded) {
		this.sliderSizeMax =
			this.scrollBarV.offsetHeight
			- this.upButton.offsetHeight
			- this.downButton.offsetHeight
		;
		this.sliderRatio = this.scrollBarV.offsetHeight / this.contentBox.offsetHeight;
		this.sliderSize = this.setSliderSize();
		this.sliderTopMin = 0 - scrollBox.downButton.offsetHeight;
		this.sliderTopMax =
			this.scrollBarV.offsetHeight
			- this.upButton.offsetHeight
			- this.downButton.offsetHeight * 2
			- this.slider.offsetHeight
		;
		if(scrollBox.contentBox.offsetHeight <= scrollBox.scrollBarV.offsetHeight) {
			scrollBox.slider.style.display = "none";
		} else {
			scrollBox.slider.style.display = "block";
		};
		if(String(scrollPosHash).match(/^\#[A-Za-z0-9]+$/)) {
			var
				initialScrollPos = parseInt(scrollPosHash.replace("#", ""), 32),
				ratio = 0
			;
			this.contentBox.style.top = "-" + initialScrollPos + "px";
			scrollBox.slider.style.top = 
				Math.round(
					initialScrollPos
					* (this.sliderSizeMax - this.sliderSize)
					/ (this.contentBox.offsetHeight - this.scrollBarV.offsetHeight)
					+ this.sliderTopMin 
				)
				+ "px"
			;
		};
		
		var links = document.getElementsByTagName("a")
		for(var i = 0; i < links.length; i++) {
			links[i].onfocus = function() {
				if(this.blur) this.blur();
			}
		}
		if(!pageLoaded) {
			this.initTimeout = setTimeout("scrollBox.init();", 333);
		} else {
			clearTimeout (this.initTimeout);
		}
	};
	this.init();
};

scrollBox = new ScrollBox(
	document.getElementById("scrollBarV"),
	document.getElementById("thumbnails"),
	document.location.hash
);

clickOnThumbnail = function(ev) {
	var
		pos = Math.abs(parseInt(
			dom.getComputedStyle(document.getElementById("thumbnails"), "top")
		))
	;
	if( pos != 0 ) {
		this.href += "#" + pos.toString(32);
	}
};

function prepareThumbnailLinks() {
	var
		links = document.getElementById("thumbnails").getElementsByTagName("a"),
		i
	;
	for( i = 0; i < links.length; i++) {
		links[i].onclick = clickOnThumbnail;
	};
};

prepareThumbnailLinks();
onload = function () {
	scrollBox.init(true);
};



