DD.ImageGallery = function(node, e) {
	var self = this;
	this.create = function(node, e) {
		DD.event.prevent(e);
		this.gallery = document.createElement('div');
		if (this.gallery.addEventListener) {
			this.gallery.addEventListener('DOMMouseScroll', this.chooseSibling, false); // Mozilla mousewheel
		}
		this.gallery.onmousewheel = this.chooseSibling; // Opera and IE mousewheel
		this.gallery.className = 'DD_ImageGallery';
		DD.modal.create(this.gallery);
		this.modal = DD.modal.get();
		this.max = {width:0, height:0};
		this.thumbs = DD.dom.ancestor(node, {nodeName: 'UL'}).getElementsByTagName('img');
		this.thumbList = document.createElement('div');
		this.gallery.appendChild(this.thumbList);
		this.thumbList.className = 'thumbs';
		this.dummy = document.createElement('img');
		this.pictureFrame = document.createElement('div');
		this.pictureFrame.className = 'pictureFrame';
		this.pictureFrame.innerHTML = '<span>.</span>';
		this.bigPicture = document.createElement('img');
		this.bigPicture.className = 'bigPicture';
		this.pictureFrame.appendChild(this.bigPicture);
		var moreSpan = document.createElement('span');
		moreSpan.innerHTML = '.';
		this.pictureFrame.appendChild(moreSpan);
		this.gallery.appendChild(this.pictureFrame);
		DD.event.add(this.dummy, 'load', this.showImage);
		for (var n=0; n<this.thumbs.length; n++) {
			this.max.width = (this.thumbs[n].width > this.max.width)? this.thumbs[n].width : this.max.width;
			this.max.height = (this.thumbs[n].height > this.max.height)? this.thumbs[n].height : this.max.height;
			var newImg = this.thumbs[n].cloneNode(true);
			newImg.id = 'thumb_' + this.thumbs[n].src;
			this.thumbList.appendChild(newImg);
		}
		this.max.WIDTH = this.max.width/.15;
		this.max.HEIGHT = this.max.height/.15;
		this.modal.style.width = this.max.WIDTH + 12 + 'px';
		this.modal.style.height = this.max.HEIGHT + this.thumbList.offsetHeight + 8 + 'px';
		this.pictureFrame.style.height = this.max.HEIGHT + 10 + 'px';
		this.pictureFrame.style.lineHeight = this.max.HEIGHT + 10 + 'px';
		DD.modal.position();
		this.choose(node, e);
	};
	this.choose = function(node, e) {
		node.nodeName == 'A'? node.blur() : null; /* Konqueror didn't like trying to blur an image element */
		DD.event.prevent(e);
		try {
			self.selectImage(node);
		}
		catch (err) {
			self.create(node, e);
		}
	};
	this.chooseSibling = function(e) {
		e = e? e : window.event;
		if (DD.modal.get()) {
			DD.event.prevent(e);
		}
		var sibling = (e.keyCode? ((e.keyCode==34 || e.keyCode==39 || e.keyCode==40 || (e.keyCode==9 && !DD.key.depressed[16]))? 'next' : 'previous') : ((!DD.event.mouseWheel(e))? 'next' : 'previous')) + 'Sibling';
		if (e.keyCode==33 || e.keyCode ==34) {
			var start = self.shown;
			for (var i=0; i<5; i++) {
				start = start[sibling] || start;
			}
			self.selectImage(start);
		}
		else if (!self.shown[sibling] || e.keyCode==35 || e.keyCode ==36) {
			self.selectImage(self.thumbList.childNodes[(sibling=='nextSibling' || e.keyCode==36)? 0 : self.thumbList.childNodes.length-1], 1000, 'quadInOut');
		}
		else {
			self.selectImage(self.shown[sibling]);
		}
	};
	this.determineThumbnail = function(node) {
		if (node) {
			return DD.dom.id('thumb_' + (node.src || node.getElementsByTagName('img')[0].src));
		}
	};
	this.requestedAlready = {};
	this.leftOffsetKnownAlready = {};
	this.selectImage = function(node, time, ease) {
		if (node) {
			var thumb = this.determineThumbnail(node);
			var bigSrc = thumb.src.replace('/small', '');
			this.dummy.src = bigSrc;
			this.bigPicture.style.visibility = (this.requestedAlready[bigSrc])? 'visible' : 'hidden';
			window.location.hash = this.dummy.src.substring(this.dummy.src.lastIndexOf('/')+1);
			if (this.shown) {
				this.shown.className = '';
			}
			this.shown = thumb;
			this.shown.className = 'active';
			var nodeLeft = this.leftOffsetKnownAlready[this.dummy.src] || thumb.offsetLeft;
			var startLeft = this.thumbList.offsetLeft;
			var finishLeft = -nodeLeft-(node.offsetWidth/2)+(this.gallery.offsetWidth/2);
			if (this.inProgress) {
				DD.animate.stop(this.inProgress);
			}
			time = time || 400;
			ease = ease || 'quadOut';
			this.inProgress = DD.animate.go(thumb, time, 20, true, function(obj, tween) {
				tween = DD.animate.ease(ease, tween);
				self.thumbList.style.left = startLeft-(startLeft-finishLeft)*tween + 'px';
			});
		}
	};
	this.showImage = function() {
		self.bigPicture.style.visibility = 'visible';
		self.bigPicture.src = this.src;
		if (!self.requestedAlready[this.src]) {
			self.requestedAlready[this.src] = true;
			self.leftOffsetKnownAlready[this.src] = this.offsetLeft;
		}
	};
	return this;
};

var gallery = new DD.ImageGallery;
DD.event.delegate('DIV#doc UL LI A', 'click', function(node, e) {
	gallery.create(node, e);
});
DD.event.delegate('DIV.DD_ImageGallery .thumbs IMG', 'click', gallery.choose);

DD.key.action = {
	9: gallery.chooseSibling, // Tab
	27: DD.modal.destroy, // Escape
	33: gallery.chooseSibling, // Page Up
	34: gallery.chooseSibling, // Page Down
	35: gallery.chooseSibling, // End
	36: gallery.chooseSibling, // Home
	37: gallery.chooseSibling, // Left
	38: gallery.chooseSibling, // Up
	39: gallery.chooseSibling, // Right
	40: gallery.chooseSibling // Down
};

DD.event.delegate('#doc', 'mouseup', function(node, e) {
	DD.modal.destroy();
});
DD.event.add(window, 'scroll', DD.modal.position);
DD.event.add(window, 'resize', DD.modal.position);

DD.event.domReady(function() {
	var previousState = '';
	setInterval(function() {
		var hash = window.location.hash.substring(1);
		var thisState = hash;
		var state = DD.dom.id('_' + hash);
		if (thisState != '') {
			if (thisState != previousState && state) {
				gallery.choose(state);
				previousState = thisState;
			}
		}
		else {
			DD.modal.destroy();
			previousState = thisState;
		}
	}, 10);
});
