function PanoViewer(id, rating, cells, panos) {
	this.viewer_id = id;
	this.total_cells = cells;
	this.pano_db = panos;

	this.first_displayed_pano = 0;
	this.selected_pano = 0;
	this.default_rating = rating;

	/* Sync the pano viewer with its internal state */
	this.update = function() {
		this.clear();

		for (var i = 0; i < this.total_cells; ++i) {
			if (i + this.first_displayed_pano < this.pano_db.length) {
				document.getElementById(this.viewer_id + '_' + i).innerHTML =
					"<img style=\"border-width: 0px;\" src=\"" + this.pano_db[i + this.first_displayed_pano][1] + "\" alt=\"preview\" width=\"100\" height=\"50\"/>";
			}
		}

		this.showRating(this.default_rating)
	}

	/* If there are fewer panoramas than cells, blank out the unused cells */
	this.clear = function(start_cell) {
		/* Blank all cells */
		for (var i = 0; i < this.total_cells; ++i) {
			document.getElementById(this.viewer_id + '_' + i).style.backgroundImage = "";
		}
	}

	/* Go forward in the panorama sequence */
	this.forward = function() {
		if (this.first_displayed_pano + this.total_cells < this.pano_db.length) {
			++this.first_displayed_pano;
		}

		this.update();
	}

	/* Go backward in the panorama sequence */
	this.backward = function() {
		if (this.first_displayed_pano > 0) {
			--this.first_displayed_pano;
		}

		this.update();
	}

	/* Load an SWF file into the panorama viewer and update the high quality link */
	this.loadSWF = function(cell_index) {
		this.selected_pano = this.first_displayed_pano + cell_index;
		
		// Load the SWF preview
		// Check to see if the version meets the requirements for playback
		if (DetectFlashVer(9,0,0)) {
			var content = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'
				+ '  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"'
				+ '  width="' + 550 + 'px" height="' + 335 + 'px" >'
				+ '  <param name="movie" value="' + this.pano_db[this.selected_pano][0] + '"/>'
				+ '  <param name="play" value="true"/>'
				+ '  <param name="cache" value="true"/>'
				+ '  <param name="allowFullScreen" value="false"/>'
				+ '  <param name="autoplay" value="true"/>'
				+ '<embed '
				+ '     width="' + 550 + 'px" height="' + 335 + 'px"'
				+ '	pluginspage="http://www.macromedia.com/go/getflashplayer"'
				+ '	type="application/x-shockwave-flash"'
				+ '	src="' + this.pano_db[this.selected_pano][0] + '"'
				+ '     play="true"'
				+ '     cache="true"'
				+ '     allowFullScreen="false"'
				+ '     autoplay="true"/>'
			        + '</object>';
			document.getElementById(this.viewer_id).innerHTML = content;
		} else { // flash is too old or we can't detect the plugin
			var alternateContent = '<b>This content requires the Adobe Flash Player Version 9 or higher. '
				+ '<a href="http://www.adobe.com/go/getflash/>Get Flash</a></b>';
			document.getElementById(this.viewer_id).innerHTML = alternateContent; // insert non-flash content
		}
		/*if (navigator.appName.search("Internet Explorer") > -1) {
			document.getElementById(this.viewer_id).innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="550" height="330"><param name="movie" value="' + this.pano_db[this.selected_pano][0] + '" /></object>';
		} else {
			document.getElementById(this.viewer_id).innerHTML = '<object type="application/x-shockwave-flash" data="' + this.pano_db[this.selected_pano][0] + '" width="550px" height="330"> </object>';
		}*/

		/* Update the high quality link */
		document.getElementById(this.viewer_id + "_hq").innerHTML = '<a href="' + this.pano_db[this.selected_pano][2] + '">High Quality</a></span>';
	}

	/* Load a SWF file with a particular name */
	this.find = function(file) {
		/* TODO: implement this function */
	}

	/* Set the background color for a particular rating */
	this.showRating = function(rating) {
		/* Reset the rating colors */
		document.getElementById("rating_" + this.viewer_id + "_5").style.backgroundColor = "#444444";
		document.getElementById("rating_" + this.viewer_id + "_4").style.backgroundColor = "#444444";
		document.getElementById("rating_" + this.viewer_id + "_3").style.backgroundColor = "#444444";
		document.getElementById("rating_" + this.viewer_id + "_2").style.backgroundColor = "#444444";
		document.getElementById("rating_" + this.viewer_id + "_1").style.backgroundColor = "#444444";

		/* Use the default rating if the argument is 0 */
		if (rating == 0) {
			rating = this.default_rating;
		}

		switch (rating) {
			case 5:
				document.getElementById("rating_" + this.viewer_id + "_5").style.backgroundColor = "#428eff";
			case 4:
				document.getElementById("rating_" + this.viewer_id + "_4").style.backgroundColor = "#428eff";
			case 3:
				document.getElementById("rating_" + this.viewer_id + "_3").style.backgroundColor = "#428eff";
			case 2:
				document.getElementById("rating_" + this.viewer_id + "_2").style.backgroundColor = "#428eff";
			case 1:
				document.getElementById("rating_" + this.viewer_id + "_1").style.backgroundColor = "#428eff";
				break;
			default:
				break;
		}
	}

	/* Set the default rating */
	this.setRating = function(rating) {
		this.default_rating = rating;

		this.showRating(0);
	}

	/* Animate the background color of a controller */
	this.animateColor = function(id, duration, start_color, end_color) {
		var obj = document.getElementById(id);
	}

	/* Helper function for animateColor */
	this.animationHelper = function(step, start_color, end_color) {
		var curr_color = start_color + step;
		if (curr_color >= end_color) {
			
		}
	}

	/* Perform the initial sync */
	this.update();

	/* Load the first SWF file in the list */
	this.loadSWF(0);
}
