data = {
	foreach : function (arr, lambda) {
		for (var i = 0; i < arr.length; i++) {
			lambda (arr[i]);
		}
	},

	addClass : function (elem, CSSClass) {
		if (!(elem.className.match('\\b' + CSSClass + '\\b'))) {
			elem.className += ' ' + CSSClass;
		}
	},

	removeClass : function (elem, CSSClass) {
		elem.className = elem.className.replace(CSSClass,'');
	},

	hasClass : function (elem, CSSClass) {
		if (elem.className.match('\\b' + CSSClass + '\\b')) {
			return true;
		}
	}
};

var currentNode = 0;

var galleryNodes = {
	items : [],
	body : null,
	image : null,
	lightbox : null,
	title : null,
	text : null,
	previous : null,
	next : null,
	current : null,
	count : null
};

function bindGalleryNodes(bodyNode, imageNode, lightboxNode, titleNode, textNode, lightboxCurrent, lightboxTotal) {
	galleryNodes.body = bodyNode;
	galleryNodes.image = imageNode;
	galleryNodes.lightbox = lightboxNode;
	galleryNodes.title = titleNode;
	galleryNodes.text = textNode;
	galleryNodes.current = lightboxCurrent;
	galleryNodes.count = lightboxTotal;
}

function drawCurrentGallery(purgeSplash) {
	var previousHidden = false
	   ,nextHidden = false;

	// short-circuit: galleryData is empty
	if (galleryData === null || galleryData.length === 0) { return false; }

	// cap current
	currentNode = Math.min(Math.max(0, currentNode), galleryData.length - 1);
	
	// display current
	galleryNodes.current.innerHTML = currentNode + 1;

	// make sure the splash screen is turned off first
	if (purgeSplash && data.hasClass(galleryNodes.body, "splash")) {
		data.removeClass(galleryNodes.body, "splash");
	}

	for (var i = 0; i < galleryNodes.items.length; i++) {
		if (i == currentNode) {
			data.addClass(galleryNodes.items[i], "current");
		} else if (data.hasClass(galleryNodes.items[i], "current")) {
			data.removeClass(galleryNodes.items[i], "current");
		}
	}

	if (currentNode > 0) {
		for (var p = 0; p < galleryNodes.previous.length; p++) {
			if (data.hasClass(galleryNodes.previous[p], "disabled")) {
				data.removeClass(galleryNodes.previous[p], "disabled");
			}
		}
	} else {
		for (var p = 0; p < galleryNodes.previous.length; p++) {
			galleryNodes.previous[p].className = "disabled";
		}
	}

	if (currentNode < galleryNodes.items.length - 1) {
		for (var n = 0; n < galleryNodes.next.length; n++) {
			if (data.hasClass(galleryNodes.next[n], "disabled")) {
				data.removeClass(galleryNodes.next[n], "disabled");
			}
		}
	} else {
		for (var n = 0; n < galleryNodes.next.length; n++) {
			galleryNodes.next[n].className = "disabled";
		}
	}

	if (galleryNodes.lightbox !== null) { galleryNodes.lightbox.src = galleryData[currentNode].largeImage; }
	if (galleryNodes.image !== null) { galleryNodes.image.src = galleryData[currentNode].mediumImage; }
	if (galleryNodes.title !== null) { galleryNodes.title.innerHTML = galleryData[currentNode].title; }
	if (galleryNodes.text !== null) { galleryNodes.text.innerHTML = galleryData[currentNode].description; }
}

function makeGallery(galleryNode, previousNodes, nextNodes) {
	var html = [];

	if (galleryData && galleryData.length > 0){
		galleryNodes.count.innerHTML = galleryData.length;

		for(var d = 0; d < galleryData.length; d++) {
			var data = galleryData[d];

			if (typeof (data) == "undefined" || data === null) continue;

			html.push('<li');
			if (d >= 5) {
				html.push(' class="hide"');
			}
			html.push('><a href="#" title="');
			html.push(data.title);
			html.push('"><img src="');
			html.push(data.smallImage);
			html.push('" alt="');
			html.push(data.title);
			html.push('" /></a></li>');
		}

		galleryNode.innerHTML = html.join("");
	}

	// pull down all the list items for iteration
	galleryNodes.items = galleryNode.getElementsByTagName("li");

	if (galleryNodes.items){
		// iterate all the list items
		for (var o = 0; o < galleryNodes.items.length; o++) {
			var aNodes = galleryNodes.items[o].getElementsByTagName("a");

			for (var i = 0; i < aNodes.length; i++) {
				aNodes[i].id = o;

				aNodes[i].onclick = function() {
					currentNode = this.id;
					drawCurrentGallery(true);
					return false;
				};
			}
		}
	}

	if (previousNodes && previousNodes.length > 0){
		galleryNodes.previous = previousNodes;
	
		for (var p = 0; p < previousNodes.length; p++){
			previousNodes[p].onclick = bindPrevious;
		}
	}

	if (nextNodes && nextNodes.length > 0){
		galleryNodes.next = nextNodes;

		for (var n = 0; n < nextNodes.length; n++){
			nextNodes[n].onclick = bindNext;
		}
	}
	
	drawCurrentGallery(false);
}

function bindPrevious() {
	var lastShown = null
	   ,nextCurrent = false;

	// short-circuit: can't do anything more; already at 0
	if (currentNode === 0) { return false; }

	// un-current the current node
	data.removeClass(galleryNodes.items[currentNode], "current");

	// decrement the current node
	currentNode--;

	data.addClass(galleryNodes.items[currentNode], "current");
	
	if (data.hasClass(galleryNodes.items[currentNode], "hide")) {
		data.addClass(galleryNodes.items[currentNode+5], "hide");
		data.removeClass(galleryNodes.items[currentNode], "hide");
	}

	drawCurrentGallery(true);

	return false;
}

function bindNext() {
	var firstShown = null
	   ,nextCurrent = false;

	// short-circuit: can't do anything more; already at maximum length
	if (currentNode === galleryNodes.items.length - 1) { return false; }

	// un-current the current node
	data.removeClass(galleryNodes.items[currentNode], "current");

	// increment the current node
	currentNode++;

	data.addClass(galleryNodes.items[currentNode], "current");
	
	if (data.hasClass(galleryNodes.items[currentNode], "hide")) {
		data.addClass(galleryNodes.items[currentNode-5], "hide");
		data.removeClass(galleryNodes.items[currentNode], "hide");
	}

	drawCurrentGallery(true);

	return false;
}
