function setupCreaturesPage() {

	// define constants
	var iconsPerPage = 8;

	Array.prototype.firstVisible = function() {
		// returns the first element in an array for which element.visible() is defined and returns true
		return this.find(function(elem) { return elem.visible && elem.visible(); });
	};
	
	function getCurrentSeason() {
		return $$('.season').firstVisible();
	}
	
	function getCurrentCreature() {
		return getCurrentSeason().select('.creature-content').firstVisible();
	}

	function creatureHasBeenLoaded(name) {
		return $$('.creature-content.' + name).length > 0;
	}
	
	function showCreature(name) {
		var currentSeason = getCurrentSeason();
		var allCreatures = currentSeason.select('.creature-content');
		var selectedCreature = currentSeason.select('.creature-content.' + name)[0];
		allCreatures.each(function(c) { c.hide(); });
		selectedCreature.show();
	}
	
	function showFullsize(e) {
		var img = this.down();
		var fullsizeUrl = img.readAttribute('fullsize');
		var fullsize = getCurrentCreature().select('.fullsize')[0];
		fullsize.src = fullsizeUrl;
		Event.stop(e);
	}

	function makeCreature(html) {
		return new Element('div').update(html).select('.creature-content')[0];
	}

	function loadCreature(name) {
		new Ajax.Request('/media/primeval/' + name + '.html', {
			method: 'GET',
			onSuccess: function(xhr) {
				// hide all the existing creatures
				var container = getCurrentSeason().select('.creature-content-container')[0];
				var oldCreatures = container.select('.creature-content');
				oldCreatures.each(function(c) { c.hide(); });
				
				// create a new creature (from HTML we just fetched) and add to the container
				var newCreature = makeCreature(xhr.responseText);
				container.insert(newCreature);
				
				// set up click events for the new creature's thumbnails
				var thumbnails = newCreature.select('img.thumbnail');
				thumbnails.each(function(img) {
					img.up().observe('click', showFullsize);
				});
			}
		});
	}
	
	// define click handler for season tabs
	$$('.creature-season-nav li a').each(function(tab) {
		tab.observe('click', function(e) {
			// activate clicked tab (deactivate other tabs)
			var thisLink = this;
			var otherLinks = thisLink.up().up().select('a');
			otherLinks.each(function (a) { a.removeClassName('active'); });
			thisLink.addClassName('active');
			
			// show content container for activated tab (hide other containers)
			var season = thisLink.up().id;
			var thisContainer = $$('.' + season + '-creatures')[0];
			var allContainers = $$('.season');
			allContainers.each(function(c) { c.hide(); });
			thisContainer.show();			

			// blur link (to remove dotted border) and stop click event
			thisLink.blur();
			Event.stop(e);
		});
	});
	
	// define click handlers for scroll controls (for the horizontal list of creature icons)
	var scrollInProgress = false;
	$$('.creature-nav-prev, .creature-nav-next').each(function(link) {
		link.observe('click', function(e) {
			// cancel default link behavior
			Event.stop(e);
			
			// cancel if a scroll animation is already in progress
			if (scrollInProgress) return;
			
			var wrapper = getCurrentSeason().select('.creatures-list')[0];
			var list = wrapper.select('ul')[0];
			
			var numIcons = list.childElements().length;
			if (numIcons <= iconsPerPage) return;

			var numPages = Math.ceil(numIcons / iconsPerPage);
			var pageWidth = wrapper.getWidth();
			var currentX = list.positionedOffset().left;
			
			var isPrev = $(this).hasClassName('creature-nav-prev');
			if (isPrev && currentX == 0) return;
			if (!isPrev && currentX <= -(pageWidth * (numPages-1))) return;
			
			// determine the new X coordinate of the list
			// previous: move list left by the width of the wrapper (the visible portion)
			// next: move list right by the same amount
			var newX = isPrev ? pageWidth : -pageWidth;
			
			// start an animation that scrolls the list to its new X coordinate
			scrollInProgress = true; 
			new Effect.Move(list, { 
				x: newX,
				afterFinish: function() { scrollInProgress = false; }
			});
		});
	});
	
	// define click handler for each season's horizontal list of creature icons
	$$('.creature-link').each(function(link) {
		var name = link.getAttribute('creature');
		link.observe('click', function(e) {
			if (creatureHasBeenLoaded(name)) {
				showCreature(name);
			} else {
				loadCreature(name);
			}
			Event.stop(e);
		});
	});

	// define click handlers for the creature thumbnails that already exist
	$$('.thumbnail').each(function(img) {
		img.up().observe('click', showFullsize);
	});

	// add CSS class "last" to 8th creature icon in each season's list
	$$('.creatures-list ul').each(function(list) {
		list.select('li').each(function(li, i) {
			if (i == iconsPerPage-1) li.addClassName('last');
		})
	});
	
}

