function $(id) { return document.getElementById(id); }

// from mootools 1.0
	if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
	else if (document.childNodes && !document.all && !navigator.taintEnabled) window.khtml = true;
	else if (document.getBoxObjectFor != null) window.gecko = true;
	//enables background image cache for internet explorer 6
	if (window.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch (e){};
	
function EventAdd(obj, type, fn) {
	if (obj.addEventListener){
		obj.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false);
	} else {
		obj.attachEvent('on'+type, fn);
	}
}

// from quirksmode.org
function getBodyScrollTop() {
	var pos = 0;
	if (window.innerHeight) {
		pos = window.pageYOffset
	} else if (document.documentElement && document.documentElement.scrollTop) {
		pos = document.documentElement.scrollTop
	} else if (document.body) {
		pos = document.body.scrollTop
	}
	return pos;
}

// from: http://www.codingforums.com/showthread.php?p=414276
function entity(str, mode) {
	var str = (str) ? str : "";
	var mode = (mode) ? mode : "string";

	var e = document.createElement("div");
	e.innerHTML = str;

	if (mode == "numeric") {
		return "&#" + e.innerHTML.charCodeAt(0) + ";";
	}
	else if (mode == "utf16") {
		var un = e.innerHTML.charCodeAt(0).toString(16);
		while (un.length < 4) un = "0" + un;
		return "\\u" + un;
	}
	else return e.innerHTML;
}

function scroll_left() {
	var scroller = $('scroller-left');
	if (scroller.timer) {
		clearTimeout(scroller.timer);
	}

	var obj = $('scroll-me');
	obj.scrolledby += 20;

	if (obj.scrolledby > scroller.offsetWidth) {
		obj.scrolledby -= 20;
		obj.style.left = obj.scrolledby + 'px';
		scroller.className = '';
		return;
	}

	$('scroller-right').className = 'enabled';
	obj.style.marginLeft = obj.scrolledby + 'px';
	scroller.timer = setTimeout('scroll_left();', 50);
}

function scroll_right() {
	var scroller = $('scroller-right');
	if (scroller.timer) {
		clearTimeout(scroller.timer);
	}

	var obj = $('scroll-me');
	obj.scrolledby -= 20;

	if ((obj.scrolledby * -1) > obj.scrollmax - obj.parentNode.offsetWidth) {
		obj.scrolledby += 20;
		obj.style.left = obj.scrolledby + 'px';
		scroller.className = '';
		return;
	}

	$('scroller-left').className = 'enabled';
	obj.style.marginLeft = obj.scrolledby + 'px';
	scroller.timer = setTimeout('scroll_right();', 50);
}

function stop_scrolling() {
	if (this.timer) {
		clearTimeout(this.timer);
		this.timer = null;
	}
}

function fade_out(name) {
	var obj = $(name);
	if (obj) {
		if (obj.fade_out_timer) {
			clearTimeout(obj.fade_out_timer);
			obj.fade_out_timer = null;
		}
		if (!obj.fade_out_set) {
			obj.onmouseover = function() {
				clearTimeout(this.fade_out_timer);
				this.style.opacity = '0.5';
				if (window.ie) {
					obj.style.filter = 'alpha(opacity=50)';
				}
				this.style.backgroundColor = '#000';
			}
			obj.onmouseout = function () {
				fade_out(this.id);
			}
			obj.style.opacity = '0.5';
			if (window.ie) {
				obj.style.filter = 'alpha(opacity=50)';
			}
			obj.fade_out_set = true;
			obj.fade_out_timer = setTimeout("fade_out('"+name+"');", 2000);
			return;
		}
		var opacity = parseFloat(obj.style.opacity) - 0.1;
		if (opacity > 0.0) {
			obj.style.opacity = opacity.toString().substr(0, 3);
			if (window.ie) {
				obj.style.filter = 'alpha(opacity='+(100*opacity)+')';
			}
			obj.fade_out_timer = setTimeout("fade_out('"+name+"');", 100);
		} else {
			obj.style.backgroundColor = 'transparent';
		}
	}
}


function close_image() {
	var obj = $("image-viewer");
	var top = obj.previousScrollTop;
	document.body.removeChild(obj);
	if (getBodyScrollTop() != top)
		window.scroll(0,top);
}
function show_image() {
	var viewer = document.createElement('div');
	viewer.id = 'image-viewer';
	viewer.onclick = function() {
		// Opera (Ubuntu) has problems with redrawing fixed areas
		// so first hide it, and then remove it with timer
		this.style.display = 'none';
		setTimeout('close_image();', 10);
	}
	viewer.previousScrollTop = getBodyScrollTop();
	
	if (this.title) {
		var desc = document.createElement('div');
		desc.id = 'image-description';
		desc.appendChild(document.createTextNode(this.title));
		viewer.appendChild(desc);
	}

	var img = document.createElement('img');
	img.go_center = function() {
		var top = (this.parentNode.offsetHeight / 2) - (this.height / 2);
		top = Math.floor(top < 0 ? 0.0 : top);
		var left = (this.parentNode.offsetWidth / 2) - (this.width / 2);
		left = Math.floor(left < 0 ? 0.0 : left);
		this.style.top = top + 'px';
		this.style.left = left + 'px';
		this.style.visibility = 'visible';
		this.parentNode.style.backgroundImage = 'none';

		// Add scrolling functionality
		if (this.width > this.parentNode.offsetWidth ||
			this.height > this.parentNode.offsetHeight) {
			EventAdd(img, 'mousemove', img.move);
		}
	}
	img.move = function(e) {
		var e = e || window.event;
		if (e.pageX) {
			this.pos = {x:e.pageX, y:e.pageY};
		} else {
			this.pos = {x:e.clientX, y:e.clientY};
		}
		this.scroll();
	}
	
	img.scroll = function() {
		if (!this.prev_pos) {
			this.prev_pos = this.pos;
			this.movedBy = {x:0,y:0,ox:0,oy:0};
			this.movedBy.ox = this.style.left.replace(/px/,'');
			this.movedBy.oy = this.style.top.replace(/px/,'');
			return;
		}

		var changed = false;
		var x = (this.pos.x - this.prev_pos.x)/this.parentNode.offsetWidth;
		var y = (this.pos.y - this.prev_pos.y)/this.parentNode.offsetHeight;
		this.prev_pos = this.pos;

		if (y < 0 && this.movedBy.y < this.movedBy.oy) {
			this.movedBy.y -= Math.floor(this.height * y);
			if (this.movedBy.y > this.movedBy.oy)
				this.movedBy.y = this.movedBy.oy;
			changed = true;
		} else if (y > 0 && this.movedBy.y + this.height > this.parentNode.offsetHeight) {
			this.movedBy.y -= Math.floor(this.height * y);
			if (this.movedBy.y + this.height < this.parentNode.offsetHeight)
				this.movedBy.y = this.parentNode.offsetHeight - this.height;
			changed = true;
		}

		if (x < 0 && this.movedBy.x < this.movedBy.ox) {
			this.movedBy.x -= Math.floor(this.width * x);
			if (this.movedBy.x > this.movedBy.ox)
				this.movedBy.x = this.movedBy.ox;
			changed = true;
		} else if (x > 0 && this.movedBy.x + this.width > this.parentNode.offsetWidth) {
			this.movedBy.x -= Math.floor(this.width * x);
			if (this.movedBy.x + this.width < this.parentNode.offsetWidth)
				this.movedBy.x = this.parentNode.offsetWidth - this.width;
			changed = true;
		}
		if (changed) {
			this.style.top = this.movedBy.y + 'px';
			this.style.left = this.movedBy.x + 'px';
		}
	}
	img.setAttribute('id', 'image');
	img.setAttribute('alt', '');
	viewer.appendChild(img);
	
	document.body.insertBefore(viewer, document.body.firstChild);
	img.setAttribute('onload', 'this.go_center();fade_out("image-description");');
	img.onload = function() {
		this.go_center();
		fade_out("image-description");
	}
	img.setAttribute('src', this.image_url);
}

function boot() {
	var obj = $('package');
	if (obj) {
		// get height
		var endpoint = document.createElement('div');
		endpoint.style.position = 'fixed';
		endpoint.style.width = '1px';
		endpoint.style.height = '1px';
		endpoint.style.bottom = '0px';
		endpoint.style.right = '0px';
		document.body.appendChild(endpoint);
		var w = endpoint.offsetLeft;
		var h = endpoint.offsetTop;
		document.body.removeChild(endpoint);
		if (obj.offsetHeight < h) {
			obj.style.height = (h - 2) + 'px';
		}
	}

	obj = $('image-block');
	if (obj) {
		obj.style.overflow = 'hidden';
		var layer = obj.cloneNode(false);
		layer.id = 'scroll-me';
		layer.scrolledby = 0;

		var n = 0;
		while (obj.firstChild) {
			var temp = obj.removeChild(obj.firstChild);
			if (temp.nodeName.toLowerCase() == 'a' && temp.href.match(/\.(jpg|gif|bmp|png|jpeg|tif|tiff)$/)) {
				var img = temp.getElementsByTagName('img')[0];
				img.image_url = temp.href;
				img.title = temp.title;
				img.onclick = show_image;
				img.id = 'image' + (++n);
				temp = img;
				
				var links = document.getElementsByTagName('a');
				for (i=links.length-1;i>=0;i--) {
					if (links[i].href == temp.image_url) {
						links[i].setAttribute('href', 'javascript:$("'+img.id+'").onclick();');
					}
				}
			}
			layer.appendChild(temp);
		}
		obj.appendChild(layer);

		// get width
		endpoint = document.createElement('a');
		endpoint.appendChild(document.createTextNode('.'));
		layer.appendChild(endpoint);
		layer.scrollmax = endpoint.offsetLeft;
		layer.removeChild(endpoint);

		if (layer.scrollmax > obj.offsetWidth) {
			var scroller = document.createElement('div');
			scroller.style.height = obj.offsetHeight+'px';
			scroller.style.lineHeight = scroller.style.height;
			scroller.id = 'scroller-left';
			obj.insertBefore(scroller, obj.firstChild);
			var scroller2 = scroller.cloneNode(true);
			scroller2.id = 'scroller-right';
			scroller2.className = 'enabled';
			obj.insertBefore(scroller2, obj.firstChild);
		scroller.appendChild(document.createTextNode(entity('&#171;')));
		scroller2.appendChild(document.createTextNode(entity('&#187;')));
			EventAdd(scroller, 'mouseover', scroll_left);
			EventAdd(scroller, 'mouseout', stop_scrolling);
			EventAdd(scroller2, 'mouseover', scroll_right);
			EventAdd(scroller2, 'mouseout', stop_scrolling);
			layer.scrollmax += (scroller.offsetWidth*2);
		}
	}
}

EventAdd(window, 'load', boot);

window.onerror = function(msg, url, line) {
	document.body.innerHTML = 'Error occured on line: '+line+'<br />'+msg;
	return true;
}