load_soundscape();
// --- USAGE --- 
/*
 <head>
 	<script type="text/javascript" src="soundscape.js"></script>
 </head>
 <body>
	<script type="text/javascript">soundscape.writeflashtag()</script>
 </body>
*/
// ---

// TODO:
// When last song finishes loading, message appears (no such track)
// When last song finishes playing, message appears (no such track)
// Click one song, then click another, they both play

function load_soundscape() {

	if (typeof soundscape != "undefined") return;

	soundscape = new (function(){ 
		this.soundengine =	"not yet loaded";
		this.soundenginepath = getscriptdir()+"soundengine.swf"
		// this.engineLoaded = false;
	 	this.isEngineLoaded = function() { 
			if ( this.soundengine.isEngineLoaded ) { 
				return this.soundengine.isEngineLoaded(); 
			} else { 
				return false; 
			}
		}
		this.registerSound = function( path ) { this.soundengine.registerSound( path ); } 
		this.preloadSound = function( path ) { this.soundengine.preloadSound( path ); } 
		this.startSound = function( path ) { this.soundengine.startSound( path ); } 
		this.playSound = function( path ) { this.soundengine.playSound( path ); } 
		this.pauseSound = function( path ) { this.soundengine.pauseSound( path ); }
		this.resetSound = function( path ) { this.soundengine.resetSound( path ); } 
		this.stopSound = function( path ) { this.soundengine.stopSound( path ); }
		this.stopAllSounds = function() { this.soundengine.stopAllSounds(); }
		this.isSoundLoading = function( path ) { return this.soundengine.isSoundLoading( path ); }
		this.isSoundReadyToPlay = function( path ) { return this.soundengine.isSoundReadyToPlay( path ); }
		this.isSoundWaitingToPlay = function( path ) { return this.soundengine. isSoundWaitingToPlay( path ); }
		this.isSoundStarted = function( path ) { return this.soundengine.isSoundStarted( path ); }
		this.isSoundPlaying = function( path ) { return this.soundengine.isSoundPlaying( path ); }
		this.isSoundFullyLoaded = function( path ) { return this.soundengine.isSoundFullyLoaded( path ); }
		this.isSoundPaused = function( path ) { return this.soundengine.isSoundPaused( path ); }
		this.isSoundStopped = function( path ) { return this.soundengine.isSoundStopped( path ); }
		this.isSoundFinished = function( path ) { return this.soundengine.isSoundFinished( path ); }
		this.getSoundBytesLoaded = function( path ) { return this.soundengine.getSoundBytesLoaded( path ); }
		this.getSoundBytesTotal = function( path ) { return this.soundengine.getSoundBytesTotal( path ); }
		this.getSoundSecondsLoaded = function( path ) { return this.soundengine.getSoundSecondsLoaded( path ); }
		this.getSoundSecondsTotal = function( path ) { return this.soundengine.getSoundSecondsTotal( path ); }
		this.getSoundSecondsPlayed = function( path ) { return this.soundengine.getSoundSecondsPlayed( path ); }
		this.getSoundSecondsRemaining = function( path ) { return this.soundengine.getSoundSecondsRemaining( path ); }
		this.getSoundPercentLoaded = function( path ) { return this.soundengine.getSoundPercentLoaded( path ); }
		this.getSoundPercentPlayed = function( path ) { return this.soundengine.getSoundPercentPlayed( path ); }
		this.getSoundLoadStartTime = function( path ) { return this.soundengine.getSoundLoadStartTime( path ); }
		this.getSoundLoadEndTime = function( path ) { return this.soundengine.getSoundLoadEndTime( path ); }
		this.getSoundLoadSecondsEllapsed = function( path ) { return this.soundengine.getSoundLoadSecondsEllapsed( path ); }
		this.getSoundLoadSecondsRemaining = function( path ) { return this.soundengine.getSoundLoadSecondsRemaining( path ); }
	})();
	soundscape.protected = new (function() { 
		this.soundscape = soundscape;
		this.engineLoadedEventListeners = [
			function() {
				// This function gets called *FROM FLASH* after all ExternalInterface methods
				// have been defined. Ideally, we would call this function at body onload - 
				// but we cant because, while we can create a pointer to the flash tag, we 
				// cannot check to see whether functions have been defined on OBJECT or EMBED
				// tag. Firefox uses EMBED, IE and Safari use OBJECT. I much prefer object detection
				// to browser detection, and so we will wait for the flash interface so we can
				// detect which tag has the interface functions on it.

				// check which object has the isEngineLoaded funciton defined on it
				if (document.getElementById('soundengine_object').isEngineLoaded) { soundscape.soundengine = document.getElementById('soundengine_object'); }
				else if (document.getElementById('soundengine_embed').isEngineLoaded) { soundscape.soundengine = document.getElementById('soundengine_embed'); }
				if (soundscape.isEngineLoaded()) soundscape.soundengine.tracebox('-+ soundspace.js  0.18 +-');
				if (!soundscape.isEngineLoaded()) alert('Soundscape could not load soundengine.');	
			}
		];
		this.engineMessageEventListeners = [
			function( msg ) { alert(msg); }
		];
		this.soundRegisteredEventListeners = [
			//function( path ) { alert("Registered "+path); }
		];
		this.soundLoadStartEventListeners = [
			//function( path ) { alert("Load Start "+path); }
		];
		this.soundReadyToPlayEventListeners = [
			//function( path ) { alert("Ready to Play "+path); }
		];
		this.soundStartEventListeners = [
			//function( path ) { alert("Start "+path); } 
		];
		this.soundFullyLoadedEventListeners = [
			//function( path ) { alert("Fully Loaded "+path); }
		];
		this.soundPauseEventListeners = [
			//function( path ) { alert("Pause "+path); }
		];
		this.soundUnpauseEventListeners = [
			//function( path ) { alert("Unpause "+path); }
		];
		this.soundStopEventListeners = [
			//function( path ) { alert("Stop "+path); }
		];
		this.soundFinishedEventListeners = [
			//function( path ) { alert("Finish "+path); }
		];
		this.triggerEngineLoadedEvent = function() { for(index in this.engineLoadedEventListeners) this.engineLoadedEventListeners[index](); }
		this.triggerEngineMessageEvent = function( msg ) { for(index in this.engineMessageEventListeners) this.engineMessageEventListeners[index]( msg ); }
		this.triggerSoundRegisteredEvent = function( path ) { for(index in this.soundRegisteredEventListeners) this.soundRegisteredEventListeners[index]( path ); }
		this.triggerSoundLoadStartEvent = function( path ) { for(index in this.soundLoadStartEventListeners) this.soundLoadStartEventListeners[index]( path ); }
		this.triggerSoundReadyToPlayEvent = function( path ) { for(index in this.soundReadyToPlayEventListeners) this.soundReadyToPlayEventListeners[index]( path ); }
		this.triggerSoundStartEvent = function( path ) { 
			for(index in soundscape.protected.soundStartEventListeners) 
				soundscape.protected.soundStartEventListeners[index]( path ); 
		}
		this.triggerSoundFullyLoadedEvent = function( path ) { for(index in this.soundFullyLoadedEventListeners) this.soundFullyLoadedEventListeners[index]( path ); }
		this.triggerSoundPauseEvent = function( path ) { for(index in this.soundPauseEventListeners) this.soundPauseEventListeners[index]( path ); }
		this.triggerSoundUnpauseEvent = function( path ) { for(index in this.soundUnpauseEventListeners) this.soundUnpauseEventListeners[index]( path ); }
		this.triggerSoundStopEvent = function( path ) { for(index in this.soundStopEventListeners) this.soundStopEventListeners[index]( path ); }
		this.triggerSoundFinishedEvent = function( path ) { for(index in this.soundFinishedEventListeners) this.soundFinishedEventListeners[index]( path ); }
	})();
	soundscape.playlist = new (function() {
		this.soundscape = soundscape;
		this.tracklist = [];
		this.currentrackid = null;
		this.currentrackpath = null;
		this.currentrack = null;
		this.loopPlaylist = false;
		this.autoPlayNextTrack = true;
		this.autoPreloadNextTrack = true;
		this.setTrackList = function( tracks ) { 
			this.tracklist = tracks; 
			if (soundscape.isEngineLoaded()) { this.registerTracks(); }
			else { 
				this.soundscape.protected.engineLoadedEventListeners.push( function() {
					soundscape.playlist.registerTracks();
				});
			}
		}
		this.setCurrentTrack = function( selector ) { 
			if (this.currenttrack) this.stopTrack();
			this.currenttrackid = this.getTrackId(selector);
			this.currenttrackpath = this.tracklist[this.currenttrackid].path;
			this.currenttrack = this.tracklist[this.currenttrackid];
			this.registerTrack( selector );
		}
		this.getTrackId = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			if (!selector) return this.currenttrackid;
			for (trackid in this.tracklist) {
				var track = this.tracklist[trackid];
				for(selectindex in selector) { skip=false; if (track[selectindex]!=selector[selectindex]) { skip=true; break; } }
				if (skip) { continue; }
				return trackid;
			}
			return null;
		}
		this.getTrackPath = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			if (!selector) return this.currenttrackpath;
			for (trackid in this.tracklist) {
				var track = this.tracklist[trackid];
				for(selectindex in selector) { skip=false; if (track[selectindex]!=selector[selectindex]) { skip=true; break; } }
				if (skip) { continue; }
				return track.path;
			}
			return null;
		}
		this.getTrack = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			if (!selector) return this.currenttrack;
			for (trackid in this.tracklist) {
				var track = this.tracklist[trackid];
				for(selectindex in selector) { skip=false; if (track[selectindex]!=selector[selectindex]) { skip=true; break; } }
				if (skip) { continue; }
				return track;
			}
			return null;
		}
		this.getNextTrackId = function () {
			//if (!this.currenttrack) { alert("getNextTrackId: No current track"); return; }
			if (this.currenttrackid==null) { var nexttrackid = 0; }
			else { var nexttrackid = parseInt(this.currenttrackid)+1; }
			var loop = (nexttrackid>=this.tracklist.length);
			if (!loop) return nexttrackid;
			if (loop && this.loopPlaylist) return nexttrackid%this.tracklist.length;
			return null;
		}
		this.getNextTrackPath = function () {
			if (!this.currenttrack) { alert("No current track"); return; }
			if (this.currenttrackid==null) { var nexttrackid = 0; }
			else { var nexttrackid = parseInt(this.currenttrackid)+1; }
			var loop = (nexttrackid>=this.tracklist.length);
			if (!loop) return this.tracklist[nexttrackid].path;
			if (loop && this.loopPlaylist) return this.tracklist[nexttrackid%this.tracklist.length].path;
			return null;
		}
		this.getNextTrack = function () {
			//if (!this.currenttrack) { alert("getNextTrack: No current track"); return; }
			if (this.currenttrackid==null) { var nexttrackid = 0; }
			else { var nexttrackid = parseInt(this.currenttrackid)+1; }
			var loop = (nexttrackid>=this.tracklist.length);
			if (!loop) return this.tracklist[nexttrackid];
			if (loop && this.loopPlaylist) return this.tracklist[nexttrackid%this.tracklist.length];
			return null;
		}
		this.getPrevTrackId = function () {
			//if (!this.currenttrack) { alert("getPrevTrackId: No current track"); return; }
			if (this.currenttrackid==null) { var prevtrackid = this.tracklist.length-1; }
			else { var prevtrackid = parseInt(this.currenttrackid)-1; }
			var loop = (prevtrackid<0);
			if (!loop) return prevtrackid;
			if (loop && this.loopPlaylist) return prevtrackid%this.tracklist.length;
			return null;
		}
		this.getPrevTrackPath = function () {
			if (!this.currenttrack) { alert("No current track"); return; }
			if (this.currenttrackid==null) { var prevtrackid = this.tracklist.length-1; }
			else { var prevtrackid = parseInt(this.currenttrackid)-1; }
			var loop = (prevtrackid<0);
			if (!loop) return this.tracklist[prevtrackid].path;
			if (loop && this.loopPlaylist) return this.tracklist[prevtrackid%this.tracklist.length].path;
			return null;
		}
		this.getPrevTrack = function () {
			if (!this.currenttrack) { alert("getPrevTrack: No current track"); return; }
			if (this.currenttrackid==null) { var prevtrackid = this.tracklist.length-1; }
			else { var prevtrackid = parseInt(this.currenttrackid)-1; }
			var loop = (prevtrackid<0);
			if (!loop) return this.tracklist[prevtrackid];
			if (loop && this.loopPlaylist) return this.tracklist[prevtrackid%this.tracklist.length];
			return null;
		}
		this.registerTracks = function( tracks ) { 
			if (!tracks) tracks = this.tracklist; 
			if (!tracks) return;
			for(index in tracks) this.soundscape.registerSound(tracks[index].path);
		}
		this.registerTrack = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			var trackid = this.getTrackId(selector); 
			if (trackid==null) { alert("No such track."); return; }
			this.soundscape.registerSound(this.tracklist[trackid].path);
		}
		this.preloadTrack = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			var trackid = this.getTrackId(selector); 
			if (trackid==null) { alert("No such track."); return; }
			this.soundscape.preloadSound(this.tracklist[trackid].path);
		}
		this.preloadNextTrack = function() {
			if (!this.currenttrack) { alert("No current track"); return; }		
			var nexttrackid = this.getNextTrackId(); 
			if (nexttrackid==null) { return; }
			this.soundscape.preloadSound(this.tracklist[nexttrackid].path);
		}
		this.startTrack = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			var trackid = this.getTrackId(selector); 
			if (trackid==null) { alert("No such track."); return; }
			if (this.currenttrack) this.soundscape.stopSound(this.currenttrackpath);
			this.currenttrackid = trackid;
			this.currenttrackpath = this.tracklist[trackid].path;
			this.currenttrack = this.tracklist[trackid];
			this.soundscape.startSound(this.currenttrackpath);
		}
		this.playTrack = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			var trackid = this.getTrackId(selector); 
			if (trackid==null) { alert("No such track."); return; }
			if (this.currenttrack) this.soundscape.stopSound(this.currenttrackpath);
			this.currenttrackid = trackid;
			this.currenttrackpath = this.tracklist[trackid].path;
			this.currenttrack = this.tracklist[trackid];
			this.soundscape.playSound(this.currenttrackpath);
		}
		this.playPauseTrack = function() {
			if (!this.currenttrack) { 
				this.playTrack(this.tracklist[0]); 
			}
			else if (this.isTrackPlaying()) { this.pauseTrack(); }
			else if (this.isTrackPaused()) { this.playTrack(); } 
		}
		this.playNextTrack = function() {
			// if (!this.currenttrack) { alert("No current track"); return; }
			var nexttrackid = this.getNextTrackId(); 
			if (nexttrackid==null) { return; }
			if (this.currenttrack) { this.soundscape.stopSound(this.currenttrackpath); }
			this.currenttrackid = nexttrackid;
			this.currenttrackpath = this.tracklist[nexttrackid].path;
			this.currenttrack = this.tracklist[nexttrackid];
			this.soundscape.playSound(this.currenttrackpath);
		}
		this.playPrevTrack = function() {
			//if (!this.currenttrack) { alert("No current track"); return; }
			var prevtrackid = this.getPrevTrackId(); 
			if (prevtrackid==null) { return; }
			if (this.currenttrack) this.soundscape.stopSound(this.currenttrackpath);
			this.currenttrackid = prevtrackid;
			this.currenttrackpath = this.tracklist[prevtrackid].path;
			this.currenttrack = this.tracklist[prevtrackid];
			this.soundscape.playSound(this.currenttrackpath);
		}
	 	this.pauseTrack = function() {
			if (!this.currenttrack) { alert("No current track"); return; }
			if (this.currenttrackid==null) return;
			var trackid = this.currenttrackid; 
			if (trackid==null) { alert("No such track."); return; }
			this.soundscape.pauseSound(this.currenttrackpath);
		}
	 	this.resetTrack = function() {
			if (!this.currenttrack) { alert("No current track"); return; }
			if (this.currenttrackid==null) return;
			var trackid = this.currenttrackid; 
			if (trackid==null) { alert("No such track."); return; }
			this.soundscape.resetSound(this.currenttrackpath);
		}
		this.stopTrack = function() {
			if (!this.currenttrack) { alert("No current track"); return; }
			if (this.currenttrackid==null) return;		
			var trackid = this.currenttrackid; 
			if (trackid==null) { alert("No such track."); return; }
			this.soundscape.stopSound(this.currenttrackpath);
		}
		this.isTrackLoading = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundLoading( path ); 
		}
		this.isTrackReadyToPlay = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundReadyToPlay( path ); 
		}
		this.isTrackWaitingToPlay = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundWaitingToPlay( path ); 
		}
		this.isTrackStarted = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundStarted( path ); 
		}
		this.isTrackPlaying = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundPlaying( path ); 
		}
		this.isTrackFullyLoaded = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 	
			//alert(path);	
			//result = this.soundscape.isSoundPaused( path );
			//alert('abc');
			return this.soundscape.isSoundFullyLoaded( path ); 
			//return false;
		}
		this.isTrackPaused = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundPaused( path ); 
		}
		this.isTrackStopped = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundStopped( path ); 
		}
		this.isTrackFinished = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.isSoundFinished( path ); 
		}
		this.getTrackBytesLoaded = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundBytesLoaded( path ); 
		}
		this.getTrackBytesTotal = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundBytesTotal( path ); 
		}
		this.getTrackSecondsLoaded = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundSecondsLoaded( path ); 
		}
		this.getTrackSecondsTotal = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundSecondsTotal( path ); 
		}
		this.getTrackSecondsPlayed = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundSecondsPlayed( path ); 
		}
		this.getTrackSecondsRemaining = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundSecondsRemaining( path ); 
		}
		this.getTrackPercentLoaded = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundPercentLoaded( path ); 
		}
		this.getTrackPercentPlayed = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundPercentPlayed( path ); 
		}
		this.getTrackLoadStartTime = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundLoadStartTime( path ); 
		}
		this.getTrackLoadEndTime = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundLoadEndTime( path ); 
		}
		this.getTrackLoadSecondsEllapsed = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundLoadSecondsEllapsed( path ); 
		}
		this.getTrackLoadSecondsRemaining = function( selector ) {
			if (!selector && !this.currenttrack) { alert("No current track"); return; }
			path = selector ? this.getTrackPath( selector ) : this.currenttrackpath; 
			if (!path) return null; 		
			return this.soundscape.getSoundLoadSecondsRemaining( path ); 
		}
		// playlist events
		this.soundscape.protected.soundStartEventListeners.push(		
			function( path ) { 

				// Workaround - Bug found in FF2 PC - No other browsers tested.
				// We are using the timeout function to make this event fire after all the
				// others. I am not exactly sure how this works, but it seems that without
				// it, any events handlers that follow this one will not fire unless the
				// song that is starting has not yet been preloaded. It's seems any call
				// to the soundengine stops the execution on any subsequent code. 

				timeout(function() {
					if (soundscape.playlist.autoPreloadNextTrack) {
						if (soundscape.playlist.isTrackFullyLoaded()) {
							soundscape.playlist.preloadNextTrack(); 
						}
					}	
				},1);
			}
		);
		this.soundscape.protected.soundFullyLoadedEventListeners.push(
			function( path ) { 
				if (soundscape.playlist.autoPreloadNextTrack) {
					if (path==soundscape.playlist.currenttrackpath) {
						soundscape.playlist.preloadNextTrack(); 
					}
				}
			}
		);
		this.soundscape.protected.soundFinishedEventListeners.push(
			function( path ) { 
				if (soundscape.playlist.autoPlayNextTrack) 
					timeout(function() { soundscape.playlist.playNextTrack(); }, 1);
			}
		);

	})();

	soundscape.writeflashtag = function(visible)
	{
		if (typeof soundscape.writeflashtag.written != "undefined") return;
		soundscape.writeflashtag.written = true;
		
		if (visible==null) { visible=false; }
	
		// This function attaches a hidden flash object to the document.
		// The flash object will play sound in the background. What and when
		// to play will be controlled by javascript. This function must be 
		// called using a script tag inside the body of the document.
		var heightwidth = visible ? "500px" : "0px" ;
		var flashtag =
			'<object id="soundengine_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="'+heightwidth+'" height="'+heightwidth+'" >'+
			'	<param name="movie" value="'	+soundscape.soundenginepath+	'" />'+
			'	<param name="allowScriptAccess" value="sameDomain" />'+
			'	<embed src="'	+soundscape.soundenginepath+	'" id="soundengine_embed" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="'+heightwidth+'" height="'+heightwidth+'"/>'+
			'</object>'+
			'</div>'
		;
		// the goal here is to make the flash player invisible so that it can play sound
		// in the background. All control of the sound is done through javacript. There are 
		// four methods that can be used for truly hiding something:
		// (1) style="display:none;"
		// (2) style="visibility:hidden;position:absolute;"
		// (3) style="height:0px;width:0px;overflow:hidden;"
		// (4) style="height:1px;width:1px;overflow:hidden;" (plus an inner div with style="margin:1px")
		// IEpc wont load a flash object if it hidden with methods (1) or (2) - (3) works sometimes - (4) always works.
		// FIREFOXpx and SAFARI won't truly hide a flash object when using method (3) or (4). So, we're stuck
		// with browser checking. 
		if (navigator.userAgent.toLowerCase().indexOf('msie')!=-1) // if IE
		{
			// method (4) above - and were going to use position:absolute anyway
			var hiddenflashtag = '<div style="position:absolute;top:0;left:0;height:1px;width:1px;overflow:hidden;"><div style="margin:1px">'+flashtag+'</div></div>';
		}
		else // if not IE 
		{
			// method (2) above
			var hiddenflashtag = '<div style="position:absolute;top:0;left:0;visibility:hidden;">'+flashtag+'</div>';		
		}
		// ideally, i would like to be able to attach this tag to the document
		// transparently. ie - attach a function on body onload that adds this tag
		// to document.body using appendChild. Unfortuantely, IE6 doesn't load
		// a flash object's external interface unless this tag is written to the 
		// document using document.write - so that's what were going to do. This 
		// function must be called using a script tag inside the body
		// of the document.	
	 	if (!visible) { document.write( hiddenflashtag ); }
		else { document.write( flashtag );  }
	}

	// --- THIS FUNCITON GETS CALLED FROM FLASH ---
	function onengineloaded()
	{
		// this function gets called *FROM FLASH* after all ExternalInterface methods
		// have been defined. Ideally, we would call this function at body onload - 
		// but we cant because, while we can create a pointer to the flash tag, we 
		// cannot check to see whether functions have been defined on OBJECT or EMBED
		// tag. Firefox uses EMBED, IE and Safari use OBJECT. I much prefer object detection
		// to browser detection, and so we will wait for the flash interface so we can
		// detect which tag has the interface functions on it.
		soundscape.soundengine = document.getElementById('soundengine_object');
		if (!soundscape.soundengine.SystemCapabilities) { soundscape.soundengine = document.getElementById('soundengine_embed'); }
		if (!soundscape.soundengine.SystemCapabilities) { alert('could not load soundengine'); }
		//alert("soundengine: "+soundscape.soundengine); 
	}
}

// --- HELPER FUNCTIONS ---
// --- GET THE DIRECTORY THAT THIS SCRIPT IS IN ---
function getscriptdir()
{
	// this function finds the name of the current script and then
	// returns the directory it's in. it's useful if you want to load
	// several scripts or objects - you can instruct the user to 
	// put them all of them in the same directory. then, so long as 
	// they are named appropriately - you can load them dynamically.

	// the method commented out below is the simplest way to get the 
	// the src attribute for this script tag. unfortanuately, firefox
	// behaves a bit weirdly when you try to access the elements of a
	// list before the page has finished loading (it will work once,
	// but then will break if you try it again from another script). 
	// we are going to use another method.
	//
	//		// wonky in firefox
	//		var scripts = document.getElementsByTagName('script'); // all script tags loaded so far
	//		var scriptsrc = scripts[scripts.length-1].src; // src for last loaded script tag (this one)
	//
	// Usually, the current script tag is the last loaded element in the DOM
	// so we could get the last loaded element using the code below. Unfortunately, 
	// this code will break when for a script tag that has been added to the DOM
	// using appendChild(). So we are going to use yet another method.
	//
	//		// wonky for dynamically loaded script tags.
	//		var element = document.lastChild;
	//		while (element.childNodes.length>0) { element = element.lastChild; }
	//
	// The method we are using walks through every element that has already been 
	// attached to the DOM and stores the last SCRIPT tag that has a non-empty
	// value for its src attribute. This still won't work if the script is loaded 
	// after the page has been loaded (say, if you click a button that attaches a
	// script) but its the best we've got so far.

	// best we've got so far
	var lastscriptwithsrc = null;
	var checkforscriptwithsrc = function(obj)
	{
		if (typeof(obj.tagName)!="undefined") {
		if (obj.tagName=="SCRIPT") { 
		if (obj.src!="")
		{
			lastscriptwithsrc = obj;
		}}}
	}
	foreachelement(checkforscriptwithsrc,document);
	var element = lastscriptwithsrc;
	if (!element.src) { alert('script tag not found'); return ""; } // it should be a script tag

	// get the source of this script and determine its parent directory
	var scriptsrc = element.src;
	var scriptdir = (scriptsrc.lastIndexOf('/') != -1) ? scriptsrc.substr(0,scriptsrc.lastIndexOf('/')+1) : '';

	// return the parent directory of this script
	//alert("scriptsrc: "+scriptsrc);
	return scriptdir;	
}
function foreachelement(func, root)
{
    if (typeof(root)=="undefined") { root=document.body; }
    var walkelements = function(ele, elefunc)
    {
        elefunc(ele);
        if (ele.childNodes)
        {
            for(var index=0;index<ele.childNodes.length;index++)
            {                
                walkelements(ele.childNodes[index], elefunc);
            }
        }
    }
    walkelements(root,func);
}
/*function timeout(func,delay) {
	// init
	if (typeof _timeout == "undefined") _timeout = {};		
	if (typeof _timeout.count == "undefined") _timeout.count = 0; 	
	if (typeof _timeout.funcs == "undefined") _timeout.funcs = new Array(); 
	// set timeout
	if (typeof func =='string') return setTimeout(func, delay); 
	if (typeof func =='function') {
		_timeout.count++;
		_timeout.funcs[_timeout.count] = func;
		return setTimeout("_timeout.funcs['"+_timeout.count+"']();", delay);
	}
} */
