

/**********
     TITLE: Music Object
   VERSION: 3.2.1
      TYPE: Object Definition
    AUTHOR: Chris van Rensburg
 COPYRIGHT: 1996-1999 Beatnik, Inc. All Rights Reserved
**********/

/*** Music Object Component - Basic - 3.2.1 ***/

window.onerror = null;

function mo_indexOf (sourceStr,searchStr,startPos) {
	var result = sourceStr.indexOf (searchStr,startPos);
	return (result != -1) ? result : sourceStr.length;
}

function mo_null () {}

function mo_on () {return this.ready && Music.enabled && !this.locked}

function mo_addEventHandler (windowHandle,objectID,eventType,handler) {
	var storedHandlerStr = '';
	if (typeof (objectID [eventType]) == 'function') {
		if (typeof (windowHandle.mo_storedHandlers) == 'undefined') windowHandle.mo_storedHandlers = 0;
		windowHandle.mo_storedHandlers++;
		var storedHandler = 'mo_storedEventHandler' + mo_storedHandlers;
		windowHandle [storedHandler] = objectID [eventType];
		storedHandlerStr = '; return ' + storedHandler + ' (event)';
	}
	objectID [eventType] = windowHandle.eval ('new Function (\'event\',\'' + handler + storedHandlerStr + '\')');
}

function mo_play (p1,p2) {
	with (this) {
		if (on ()) {
			endVolumeFade ();
			if (typeof (p2) == 'string') {
				if (p2 != '' && p2.indexOf ('.') == -1 && p2.indexOf ('groovoid://') != 0) p2 = 'groovoid://' + p2;
				if (typeof (p1) == 'string') p1 = (p1 == 'auto') ? (p2.indexOf ('groovoid://Background-') == 0) : (p1 == 'yes');
				playerID.play (p1,p2);
			} else if (typeof (p1) == 'boolean' || typeof (p1) == 'number') {
				playerID.play (p1);
			} else if (typeof (p1) == 'string') {
				play ('auto',p1);
			} else {
				if (!playerID.IsPlaying ()) playerID.play ();
			}
		}
	}
}

function mo_stop (fade) {
	with (this) {
		if (on ()) {
			if (typeof (fade) == 'undefined' || !Music.canFade || playerID.IsPaused ()) {
				endVolumeFade ();
				playerID.stop ();
			} else {
				fadeVolume (null,0,fade,objectName + '.stop ()');
			}
		}
	}
}

function mo_pause (fade) {
	with (this) {
		if (on ()) {
			endVolumeFade ();
			if (playerID.IsPaused ()) {
				playerID.pause ();
				if (typeof (fade) != 'undefined' && Music.canFade) fadeVolume (0,100,fade);
			} else {
				(typeof (fade) == 'undefined' || !Music.canFade) ? playerID.pause () : fadeVolume (null,0,fade,objectName + '.pause ()');
			}
		}
	}
}

function mo_enable () {
	with (this) {
		if (typeof (window [playerName]) == 'object') {
			playerID = window [playerName];
		} else if (typeof (document [playerName]) == 'object') {
			playerID = document [playerName];
		} else {
			for (var formNo = 0; formNo < document.forms.length; formNo++) {
				formHandle = document.forms [formNo];
				if (typeof (formHandle [playerName]) == 'object') {
					playerID = formHandle [playerName];
					break;
				}
			}
		}
		if (playerID != null) {
			if (Music.playerVersion == '') Music.playerVersion = mo_retrieveVersion (playerID.getVersion () + '');
			if (typeof (this.onMetaEventHandler) == 'function') playerID.enableMetaEvents (true);
			Music.hasCallbackIssue ? playerID.enableCallbacks (true) : execOnReady ();
		} else {
			setTimeout (objectName + '.enable ()',500);
		}
	}
}

function mo_execOnReady () {
	with (this) {
		if (ready) {
			if (Music.playerType == 'ActiveX') playerID.receivedReady (true);
		} else {
			ready = playerID != null;
			if (ready) {
				if (Music.playerType == 'ActiveX') playerID.receivedReady (true);
				if (delayAutostart) {
					playerID.setAutostart (true);
					play ();
				}
				execCallback ('onReady');
			} else {
				enable ();
			}
		}
		if (ready) {
			Music.global = playerID;
			execCallback ('onLoad');
		}
	}
}

function mo_execOnPlay () {
	with (this) {
		setVolume (VOLUME);
		execCallback ('onPlay');
	}
}

function mo_setVolume (_volume) {
	with (this) {
		VOLUME = _volume;
		if (on ()) playerID.setVolume (VOLUME);
	}
}

function mo_parseAttributes (attrList,attribs) {
	var
		endFound = false,
		attrStartPos = 0
	;
	while (!endFound && attrStartPos < attrList.length) {
		var attrFound = false;
		while (!attrFound && attrStartPos < attrList.length) {
			attrFound = attrList.charAt (attrStartPos) != ' ';
			if (!attrFound) attrStartPos++;
		}
		if (attrFound) {
			var
				equalPos = mo_indexOf (attrList,'=',attrStartPos),
				spacePos = mo_indexOf (attrList,' ',attrStartPos),
				closePos = mo_indexOf (attrList,'>',attrStartPos),
				attrNameEndPos = Math.min (Math.min (spacePos,equalPos),closePos),
				hasValue = attrNameEndPos != spacePos && attrNameEndPos != closePos,
				attrName = attrList.substring (attrStartPos,attrNameEndPos).toUpperCase (),
				attrValueEndPos = attrNameEndPos,
				attrValue = ''
			;
			endFound = closePos == attrNameEndPos;
			if (hasValue) {
				var
					attrValuePos = attrNameEndPos + 1,
					quoteChar = attrList.charAt (attrValuePos)
				;
				if (quoteChar == '"' || quoteChar == "'") {
					attrValuePos++;
					attrValueEndPos = attrValuePos;
					var attrValueEndFound = false;
					while (!attrValueEndFound && attrValueEndPos < attrList.length - 1) {
						attrValueEndPos = mo_indexOf (attrList,quoteChar,attrValueEndPos + 1);
						attrValueEndFound = true;
						var
							checkingEscape = true,
							charPos = attrValueEndPos
						;
						while (checkingEscape) {
							charPos--;
							checkingEscape = attrList.charAt (charPos) == '\\';
							if (checkingEscape) attrValueEndFound = !attrValueEndFound;
						}
					}
				} else {
					attrValueEndPos = Math.min (mo_indexOf (attrList,' ',attrValuePos),mo_indexOf (attrList,'>',attrValuePos));
				}
				attrValue = attrList.substring (attrValuePos,attrValueEndPos);
			}
			attrStartPos = attrValueEndPos + 1;
			attribs [attrName] = attrValue;
		}
	}
}

function mo_tagAttr (attribs,attrName) {
	return (attribs [attrName] != null) ? (' ' + attrName + ((attribs [attrName] != '') ? ('="' + attribs [attrName] + '"') : '')) : '';
}

function mo_magicEmbed (attrList) {
	if (typeof (Music.playerCompatible) != 'boolean') mo_isPlayerCompatible ();
	var
		instance = typeof (this.playerID) != 'undefined',
		attribs = instance ? this : Music,
		attrNames = new Array ('SRC','WIDTH','HEIGHT','AUTOSTART','LOOP','VOLUME','ALIGN','HSPACE','VSPACE','BGCOLOR','HIDDEN','DISPLAY','MODE','GROOVOID','ONREADY','ONPLAY','ONPAUSE','ONSTOP','ONMETAEVENT','CALLBACKS','METAEVENTS')
	;
	if (typeof (this.playerName) != 'string' || !instance) {
		for (var attrNo = 0; attrNo < attrNames.length; attrNo++) attribs [attrNames [attrNo]] = null;
		with (this) {
			attribs.AUTOSTART = 'TRUE';
			attribs.WIDTH = '144';
			attribs.HEIGHT = '60';
			attribs.HSPACE = attribs.VSPACE = '0';
			attribs.BGCOLOR = document.bgColor;
			attribs.VOLUME = '100';
			mo_parseAttributes (attrList,attribs);
			if (attribs.HIDDEN == '') attribs.HIDDEN = 'TRUE';
			with (document) {
				var
					panelW = attribs.WIDTH - 0,
					panelH = attribs.HEIGHT - 0,
					embedOutput = ''
				;
				if (Music.enabled && Music.clientSupported && Music.hasPlayer && (Music.playerCompatible || !Music.silentIfInadequate)) {
					if (instance) {
						this.playerName = objectName + 'Player';
						var prefix = Music.framePrefix + objectName + '.execOn';
						attribs.ONREADY = prefix + 'Ready()';
						attribs.ONPLAY = prefix + 'Play()';
						attribs.ONPAUSE = prefix + 'Pause()';
						attribs.ONSTOP = prefix + 'Stop()';
						attribs.ONMETAEVENT = prefix + 'MetaEvent()';
						attribs.METAEVENTS = 'FALSE';
						if (Music.hasCallbackIssue) {
							attribs.CALLBACKS = 'FALSE';
							delayAutostart = attribs.AUTOSTART.toUpperCase () == 'TRUE';
							attribs.AUTOSTART = 'FALSE';
							if (!Music.bodyEventsAdded) {
								Music.windowOnloadStr = '';
								Music.bodyEventsAdded = true;
								if (Music.playerType == 'ActiveX') mo_addEventHandler (window,window,'onunload','for (var instanceNo = Music.instances.length - 1; instanceNo >= 0; instanceNo--) Music.instances [instanceNo].playerID = null; Music.global = null');
								mo_addEventHandler (window,window,'onload','eval (Music.windowOnloadStr)');
							}
							Music.windowOnloadStr += objectName + '.enable ();';
						}
					}
					if (Music.playerType == 'Plug-in') {
						embedOutput = '<EMBED TYPE="audio/rmf" PLUGINSPAGE="http://www.beatnik.com/to/?player"' + (instance ? (' NAME="' + playerName + '"') : '');
						for (var attrNo = 0; attrNo < attrNames.length; attrNo++)
							embedOutput += mo_tagAttr (attribs,attrNames [attrNo])
						;
						embedOutput += '>';
						if (instance) requireJava ();
					} else if (Music.playerType == 'ActiveX') {
						if (instance) {
							var callbacks = new Array ('OnReady','OnPlay','OnPause','OnStop','OnMetaEvent');
							for (var callbackNo = 0; callbackNo < callbacks.length; callbackNo++) {
								var
									callbackParams = '(' + (callbacks [callbackNo] == 'OnMetaEvent' ? 'eventType,eventValue' : '') + ')',
									callbackHandler = attribs [callbacks [callbackNo].toUpperCase ()]
								;
								embedOutput += '<SCRIPT LANGUAGE=JavaScript FOR="' + playerName + '" EVENT="' + callbacks [callbackNo] + callbackParams + '">' + callbackHandler.substring (0,callbackHandler.indexOf ('(')) + callbackParams + '</SCRIPT>\n';
							}
						}
						embedOutput += '<OBJECT' + (instance ? (' ID="' + playerName + '"') : '') + ' WIDTH=' + panelW + ' HEIGHT=' + panelH + ' CLASSID="CLSID:B384F118-18EE-11D1-95C8-00A024330339" CODEBASE="http://download.beatnik.com/beatnik-player/beatnik-player.cab">\n';
						for (var attrNo = 0; attrNo < attrNames.length; attrNo++) {
							if (attribs [attrNames [attrNo]] != null)
								embedOutput += '<PARAM NAME="' + attrNames [attrNo] + '" VALUE="' + attribs [attrNames [attrNo]] + '">\n'
							;
						}
						embedOutput += '</OBJECT>';
					}
				} else {
					embedOutput = mo_playerSubstitute (attribs);
				}
				writeln (embedOutput);
			}
		}
		attribs.VOLUME = attribs.VOLUME - 0;
	}
}

function mo_addInstanceMethods () {
	var args = mo_addInstanceMethods.arguments;
	for (var argNo = 0; argNo < args.length; argNo++)
		Music.instanceMethods [Music.instanceMethods.length] = args [argNo]
	;
}

/*** Music Object Constructor ***/

function Music (objectName) {
	this.objectName = this.alias = (typeof (objectName) == 'string') ? objectName : ('mo_GIN' + Music.GINs++);

	/*** Instance Properties ***/
	this.delayAutostart = this.ready = this.locked = false;
	this.playerID = null;

	/*** Initialisation ***/
	for (var methodNo = 0; methodNo < Music.instanceMethods.length; methodNo++) {
		var method = Music.instanceMethods [methodNo];
		this [method] = (typeof (window ['mo_' + method]) != 'function') ? mo_null : window ['mo_' + method];
	}
	this.extend ();
	window [this.objectName] = Music.instances [Music.instances.length] = this;
}

/*** Private Properties ***/

Music.bodyEventsAdded = false;
Music.canFade = false;
Music.framePrefix = '';
Music.hasCallbackIssue = navigator.userAgent.indexOf ('WebTV') == -1;
Music.instances = new Array ();
Music.instanceMethods = new Array ();
Music.storedHandlers = 0;
Music.GINs = 0;

/*** Instance Methods ***/

mo_addInstanceMethods ('enable','endVolumeFade','execCallback','execOnPause','execOnPlay','execOnReady','execOnStop','extend','magicEmbed','on','pause','play','requireJava','setVolume','stop');

/*** Static Methods ***/

Music.magicEmbed = mo_magicEmbed;

/*** Static Properties ***/

Music.enabled = true;

/*** Static Read-only Properties ***/

Music.clientSupported = true;
Music.hasPlayer = true;
Music.playerCompatible = true;
Music.playerType = (navigator.appName == 'Microsoft Internet Explorer') ? 'ActiveX' : 'Plug-in';
Music.playerVersion = '[unknown]';

/*** Music Object Component - Advanced - 3.2.1 ***/

function mo_extend () {
	for (var extenderNo = 0; extenderNo < Music.extenders.length; extenderNo++)
		Music.extenders [extenderNo] (this);
	;
}

function mo_addStaticMethods () {
	var args = mo_addStaticMethods.arguments;
	for (var argNo = 0; argNo < args.length; argNo++)
		Music [args [argNo]] = window ['mo_' + args [argNo]]
	;
}

function mo_addExtender (extender) {
	Music.extenders [Music.extenders.length] = extender;
}

function mo_execHandler (handler) {
	if (typeof (handler) == 'string') eval (handler);
		else if (typeof (handler) == 'function') handler ();
}

function mo_execCallback (callbackType) {
	if (typeof (this [callbackType + 'Handler']) != 'undefined')
		mo_execHandler (this [callbackType + 'Handler'])
	;
	this.execHandlers (callbackType);
}

function mo_execOnPause () {
	with (this) {
		endVolumeFade ();
		execCallback ('onPause');
	}
}

function mo_execOnStop () {
	with (this) {
		endVolumeFade ();
		execCallback ('onStop');
	}
}

function mo_stopAll () {
	for (var instanceNo = 0; instanceNo < Music.instances.length; instanceNo++)
		Music.instances [instanceNo].stop ()
	;
}

function mo_endVolumeFade () {
	with (this) {
		if (volFade_inProgress) {
			volFade_inProgress = false;
			mo_execHandler (volFade_endCallback);
			if (volFade_restoreVolume) setVolume (volFade_fromVolume);
		}
	}
}

function mo_execVolumeFade () {
	with (this) {
		if (volFade_inProgress) {
			volFade_volume += volFade_step;
			setVolume (Math.round (volFade_volume));
			volFade_timeElapsed += volFade_interval;
			mo_execHandler (volFade_advanceCallback);
			if (volFade_timeElapsed >= volFade_time) {
				setVolume (volFade_toVolume);
				endVolumeFade ();
			} else {
				setTimeout (objectName + '.execVolumeFade ()',volFade_interval);
			}
		}
	}
}

function mo_fadeVolume (fromVolume,toVolume,fadeTime,fadeEndCallback,fadeAdvanceCallback) {
	with (this) {
		if (on ()) {
			if (typeof (fromVolume) != 'number') fromVolume = VOLUME;
			if (typeof (toVolume) != 'number') toVolume = 0;
			if (typeof (fadeTime) == 'boolean') fadeTime = fadeTime ? 1000:0;
			if (typeof (fadeTime) != 'number') fadeTime = 1000;
			if (
				volFade_inProgress &&
				toVolume == volFade_toVolume &&
				fadeTime == volFade_time
			) {
				volFade_endCallback = fadeEndCallback;
				volFade_advanceCallback = fadeAdvanceCallback;
			} else {
				volFade_restoreVolume = typeof (fadeEndCallback) == 'string' && (fadeEndCallback.indexOf ('.stop ()') != -1 || fadeEndCallback.indexOf ('.pause ()') != -1);
				endVolumeFade ();
				if (fadeTime != 0 && fadeTime < Music.minFadeInterval)
					fadeTime = Math.round (fadeTime / Music.minFadeInterval) * Music.minFadeInterval
				;
				if (fadeTime == 0 || toVolume == fromVolume) {
					if (!volFade_restoreVolume)	setVolume (toVolume);
					mo_execHandler (fadeEndCallback);
				} else {
					volFade_fromVolume = fromVolume;
					volFade_toVolume = toVolume;
					volFade_time = fadeTime;
					volFade_endCallback = fadeEndCallback;
					volFade_advanceCallback = fadeAdvanceCallback;
					volFade_timeElapsed = 0;
					volFade_volume = fromVolume;
					volFade_inProgress = true;
					volFade_interval = Math.max (Math.ceil (volFade_time / Math.abs (toVolume - fromVolume)),Music.minFadeInterval);
					volFade_step = (toVolume - fromVolume) / (volFade_time / volFade_interval);
					setVolume (fromVolume);
					setTimeout (objectName + '.execVolumeFade ()',volFade_interval);
				}
			}
		}
	}
}

function mo_fadeTo (toValue,fadeTime,fadeEndCallback,fadeAdvanceCallback) {
	this.fadeVolume (null,toValue,fadeTime,fadeEndCallback,fadeAdvanceCallback);
}

function mo_setMonophonic (channelNo,state) {
	if (channelNo == 0)
		for (var channelCount = 1; channelCount < 17; channelCount++) this ['mono' + channelCount] = state;
		else this ['mono' + channelNo] = state;
}

function mo_getMonophonic (channelNo) {return this ['mono' + channelNo]}

function mo_noteOn (_channelNo,p2,p3,p4,p5,p6) {
	with (this) {
		if (on ()) {
			var voiceNo;
			if (mo_noteOn.arguments.length >= 5) {
				if (this ['mono' + _channelNo]) noteOff (_channelNo);
				if (typeof (p4) == 'string') p4 = mo_getNoteNumber (p4);
				with (Music.newVoice) {
					musicID = this;
					timeStamp = ++Music.globalNoteNo;
					channelNo = _channelNo;
					noteNo = p4;
				}
				var assignToVoiceNo = -1;
				for (voiceNo = 0; voiceNo < Music.polyphony; voiceNo++) {
					with (Music.voices [voiceNo]) {
						if (channelNo == 0) {
							assignToVoiceNo = voiceNo;
							break;
						}
					}
				}
				if (assignToVoiceNo == -1) {
					assignToVoiceNo = 0;
					for (voiceNo = 0; voiceNo < Music.polyphony; voiceNo++) {
						if (Music.voices [voiceNo].timeStamp < Music.voices [assignToVoiceNo].timeStamp)
							assignToVoiceNo = voiceNo
						;
					}
				}
				with (Music.voices [assignToVoiceNo]) {
					musicID = Music.newVoice.musicID;
					timeStamp = Music.newVoice.timeStamp;
					channelNo = Music.newVoice.channelNo;
					noteNo = Music.newVoice.noteNo;
					(p2 >= 0 && p3 >= 0) ? playerID.noteOn (channelNo,p2,p3,p4,p5) : playerID.noteOn (channelNo,p4,p5);
					if (typeof (p6) == 'number') noteOffTimeout = setTimeout ('Music.voices [' + assignToVoiceNo + '].free ()',p6);
				}
			} else {
				noteOn (_channelNo,-1,-1,p2,p3,(typeof (p4) != 'number') ? null : p4);
			}
		}
	}
}

function mo_noteOff (_channelNo,_noteNo) {
	with (this) {
		if (on ()) {
			if (typeof (_noteNo) == 'undefined') {
				for (var voiceNo = 0; voiceNo < Music.polyphony; voiceNo++) {
					with (Music.voices [voiceNo])
						if (musicID == this && channelNo == _channelNo) free ()
					;
				}
			} else {
				if (typeof (_noteNo) == 'string') _noteNo = mo_getNoteNumber (_noteNo);
				for (var voiceNo = 0; voiceNo < Music.polyphony; voiceNo++) {
					with (Music.voices [voiceNo]) {
						if (musicID == this && channelNo == _channelNo && noteNo == _noteNo) {
							free ();
							break;
						}
					}
				}
			}
		}
	}
}

function mo_setProgram (channelNo,p2,p3) {
	if (this.on ()) {
		(typeof (p3) == 'number') ? this.playerID.setProgram (channelNo,p2,p3) : this.playerID.setProgram (channelNo,p2);
	}
}

function mo_execOnMetaEvent (eventType,eventValue) {
	if (typeof (this.onMetaEventHandler) == 'function') this.onMetaEventHandler (eventType,eventValue,this);
	this.execHandlers ('onMetaEvent');
}

function mo_onLoad (onLoadHandler) {this.onLoadHandler = onLoadHandler}
function mo_onPause (onPauseHandler) {this.onPauseHandler = onPauseHandler}
function mo_onPlay (onPlayHandler) {this.onPlayHandler = onPlayHandler}
function mo_onReady (onReadyHandler) {this.onReadyHandler = onReadyHandler}
function mo_onStop (onStopHandler) {this.onStopHandler = onStopHandler}

function mo_onMetaEvent (_onMetaEventHandler) {
	with (this) {
		onMetaEventHandler = _onMetaEventHandler;
		if (ready) playerID.enableMetaEvents (typeof (onMetaEventHandler) == 'function');
	}
}

function mo_getVolume () {return this.VOLUME}
function mo_isPaused () {return this.ready ? this.playerID.IsPaused () : false}
function mo_isPlaying () {return this.ready ? this.playerID.IsPlaying () : false}

function mo_stubEmbed (stubURL) {
	this.magicEmbed (((typeof (stubURL) != 'string') ? '' : ('SRC="' + stubURL + '" ')) + 'WIDTH=0 HEIGHT=0 HIDDEN LOOP=TRUE');
}

function mo_preloadEmbed (fileURL,extraAttr) {
	this.magicEmbed ('SRC="' + fileURL + '" WIDTH=0 HEIGHT=0 HIDDEN AUTOSTART=FALSE LOOP=FALSE ' + ((typeof (extraAttr) == 'string') ? extraAttr : ''));
}

function mo_getNoteName (noteNumber) {
	var noteNames = new Array ('C','C#','D','D#','E','F','F#','G','G#','A','A#','B');
	return noteNames [noteNumber % 12] + (Math.floor (noteNumber / 12) - 1) + '';
}

function mo_getNoteNumber (noteName) {
	if (typeof (noteName) == 'number') return noteName;
	var
		noteOffset = 'c-d-ef-g-a-b'.indexOf (noteName.charAt (0).toLowerCase ()),
		result = 0,
		sharpFlatOffset = 0
	;
	if (noteOffset != -1) {
		var sharpFlatPos = noteName.indexOf ('b',1);
		if (sharpFlatPos == -1) {
			sharpFlatPos = noteName.indexOf ('#',1);
			if (sharpFlatPos == -1) sharpFlatPos = 0; else sharpFlatOffset = 1;
		} else {
			sharpFlatOffset = -1;
		}
		var octaveNo = noteName.substring (sharpFlatPos + 1) - 0;
		result =  12 + octaveNo * 12 + noteOffset + sharpFlatOffset;
	}
	return Math.floor (result);
}

function mo_Voice_free () {
	with (this) {
		clearTimeout (noteOffTimeout);
		musicID.playerID.noteOff (channelNo,noteNo,127);
		channelNo = 0;
	}
}

function mo_Voice (musicID,channelNo,noteNo) {
	/*** Constructor Properties ***/
	this.musicID = musicID;
	this.channelNo = channelNo;
	this.noteNo = noteNo;

	/*** Instance State Properties ***/
	this.timeStamp = 0;
	this.noteOffTimeout = setTimeout ('',0);

	/*** Exposed Methods ***/
	this.free = mo_Voice_free;
}

function mo_kill () {
	mo_stopAll ();
	Music.enabled = false;
}

function mo_globalThru () {return Music.enabled && Music.global != null}
function mo_getReverbType () {return mo_globalThru () ? Music.global.getReverbType () : null}
function mo_setGlobalMute (muteState) {if (mo_globalThru ()) Music.global.setGlobalMute (muteState)}
function mo_setReverbType (reverbType) {if (mo_globalThru ()) Music.global.setReverbType (reverbType)}
function mo_engageAudio (audioState) {if (mo_globalThru ()) Music.global.engageAudio (audioState)}

function mo_doMenuItem (menuItemName) {if (this.on ()) this.playerID.doMenuItem (menuItemName)}
function mo_getAutostart () {return this.ready ? this.playerID.getAutostart () : null}
function mo_getChannelMute (channelNo) {return this.ready ? this.playerID.getChannelMute (channelNo) : null}
function mo_getChannelSolo (channelNo) {return this.ready ? this.playerID.getChannelSolo (channelNo) : null}
function mo_getController (channelNo,controllerNo) {return this.ready ? this.playerID.getController (channelNo,controllerNo) : null}
function mo_getFileSize () {return this.ready ? this.playerID.getFileSize () : null}
function mo_getInfo (infoField) {return this.ready ? this.playerID.getInfo (infoField) : null}
function mo_getLoop () {return this.ready ? this.playerID.getLoop () : null}
function mo_getPanelDisplay () {return this.ready ? this.playerID.getPanelDisplay () : null}
function mo_getPanelMode () {return this.ready ? this.playerID.getPanelMode () : null}
function mo_getPlayLength () {return this.ready ? this.playerID.getPlayLength () : null}
function mo_getPosition () {return this.ready ? this.playerID.getPosition () : null}
function mo_getProgram (channelNo) {return this.ready ? this.playerID.getProgram (channelNo) : null}
function mo_getTempo () {return this.ready ? this.playerID.getTempo () : null}
function mo_getTrackMute (trackNo) {return this.ready ? this.playerID.getTrackMute (trackNo) : null}
function mo_getTrackSolo (trackNo) {return this.ready ? this.playerID.getTrackSolo (trackNo) : null}
function mo_getTranspose () {return this.ready ? this.playerID.getTranspose () : null}
function mo_getTransposable (channelNo) {return this.ready ? this.playerID.getTransposable (channelNo) : null}
function mo_setAutostart (state) {if (this.on ()) this.playerID.setAutostart (state)}
function mo_setChannelMute (channelNo,state) {if (this.on ()) this.playerID.setChannelMute (channelNo,state)}
function mo_setChannelSolo (channelNo,state) {if (this.on ()) this.playerID.setChannelSolo (channelNo,state)}
function mo_setController (channelNo,controllerNo,controllerValue) {if (this.on ()) this.playerID.setController (channelNo,controllerNo,controllerValue)}
function mo_setEndTime (endTime) {if (this.on ()) this.playerID.setEndTime (endTime)}
function mo_setLoop (state) {if (this.on ()) this.playerID.setLoop (state)}
function mo_setPanelDisplay (displayType) {if (this.on ()) this.playerID.setPanelDisplay (displayType)}
function mo_setPanelMode (panelMode) {if (this.on ()) this.playerID.setPanelMode (panelMode)}
function mo_setPosition (position) {if (this.on ()) this.playerID.setPosition (position)}
function mo_setStartTime (startTime) {if (this.on ()) this.playerID.setStartTime (startTime)}
function mo_setTempo (tempo) {if (this.on ()) this.playerID.setTempo (tempo)}
function mo_setTrackMute (trackNo,state) {if (this.on ()) this.playerID.setTrackMute (trackNo,state)}
function mo_setTrackSolo (trackNo,state) {if (this.on ()) this.playerID.setTrackSolo (trackNo,state)}
function mo_setTranspose (transpose) {if (this.on ()) this.playerID.setTranspose (transpose)}
function mo_setTransposable (channelNo,state) {if (this.on ()) this.playerID.setTransposable (channelNo,state)}

/*** Private Properties ***/

Music.global = null;
Music.extenders = new Array ();
Music.canFade = true;
Music.globalNoteNo = 0;
Music.minFadeInterval = 100;
Music.polyphony = 32;
Music.voices = new Array ();
Music.newVoice = new mo_Voice (null,0,0);

for (mo_voiceNo = 0; mo_voiceNo < Music.polyphony; mo_voiceNo++)
	Music.voices [mo_voiceNo] = new mo_Voice (null,0,0)
;

/*** Instance Methods ***/

mo_playNote = mo_noteOn;
mo_addInstanceMethods ('doMenuItem','execHandlers','execOnMetaEvent','execVolumeFade','fadeTo','fadeVolume','getAutostart','getChannelMute','getChannelSolo','getController','getFileSize','getInfo','getLoop','getMonophonic','getPanelDisplay','getPanelMode','getPlayLength','getPosition','getProgram','getTempo','getTrackMute','getTrackSolo','getTransposable','getTranspose','getVolume','isPaused','isPlaying','noteOff','noteOn','onLoad','onMetaEvent','onPause','onPlay','onReady','onStop','playNote','preloadEmbed','setAutostart','setChannelMute','setChannelSolo','setController','setEndTime','setLoop','setMonophonic','setPanelDisplay','setPanelMode','setPosition','setProgram','setStartTime','setTempo','setTrackMute','setTrackSolo','setTransposable','setTranspose','stubEmbed');

/*** Instance Properties ***/

function mo_addAdvancedProperties (ID) {
	ID.volFade_step = ID.volFade_time = ID.volFade_timeElapsed = ID.volFade_interval = ID.volFade_fromVolume = ID.volFade_volume = ID.volFade_toVolume = 0;
	ID.volFade_endCallback = null;
	ID.volFade_inProgress = false;
	ID.volFade_restoreVolume = false;
	for (var channelNo = 1; channelNo < 17; channelNo++) ID ['mono' + channelNo] = false;
}

mo_addExtender (mo_addAdvancedProperties);

/*** Static Methods ***/

mo_addStaticMethods ('engageAudio','getNoteName','getNoteNumber','getReverbType','setGlobalMute','setReverbType','stopAll');

/*** Music Object Component - Compatibility - 3.2.1 ***/

function mo_stringHasAny (sourceStr) {
	var args = mo_stringHasAny.arguments;
	for (var argNo = 1; argNo < args.length; argNo++) {
		if (sourceStr.indexOf (args [argNo]) != -1) return true;
	}
	return false;
}

function mo_openWindow (_URL,_name,_width,_height,showStatus,properties) {
	if (typeof (properties) != 'string') properties = '';
	var positionStr = '';
	if (typeof (screen) != 'undefined') {
		var
			xpos = Math.max (Math.floor ((screen.width - _width - 10) / 2),0),
			ypos = Math.max (Math.floor ((screen.height - _height - 40) / 2),0)
		;
		positionStr = 'screenx=' + xpos + ',screeny=' + ypos + ',left=' + xpos + ',top=' + ypos + ',';
	}
	return window.open (_URL,_name,properties + ',toolbar=no,location=no,directories=no,status=' + ((typeof (showStatus) == 'boolean' && showStatus) ? 'yes' : 'no') + ',menubar=no,scrollbars=no,resizable=yes,' + positionStr + 'width=' + _width + ',height=' + _height + ',' + properties);
}

function mo_promptClose () {
	if (Music.promptWindow != null) {
		Music.promptWindow.close ();
		Music.promptWindow = null;
		window.focus ();
	}
}

function mo_promptUser (heading,message,okText,okAction,cancelText,cancelAction,showStatus) {
	Music.promptWindow = mo_openWindow ('','mo_promptWindow',500,295,showStatus);
	if (typeof (okAction) != 'string' || okAction == '') okAction = 'mo_promptClose ()';
	if (typeof (cancelAction) != 'string' || cancelAction == '') cancelAction = 'mo_promptClose ()';
	if (typeof (heading) != 'string') heading = '';
	with (Music.promptWindow.document) {
		open ('text/html');
		writeln (
			'<HTML><HEAD><TITLE>' + heading + '</TITLE></HEAD><BODY TEXT=000000 TOPMARGIN=0 LEFTMARGIN=0 MARGINWIDTH=0 MARGINHEIGHT=0>' +
			'<FORM><TABLE WIDTH=100% HEIGHT=100% BORDER=0 CELLSPACING=0 CELLPADDING=6 BGCOLOR=CCCCCC>' +
			((heading != '') ? ('<TR><TD VALIGN=TOP><TABLE WIDTH=100% BORDER=1 CELLSPACING=0 CELLPADDING=2 BGCOLOR=AAAAAA><TR><TD ALIGN=CENTER><FONT FACE=ARIAL,HELVETICA,VERDANA SIZE=5>' + heading + '</FONT></U><BR></TD></TR></TABLE></TD></TR>') : '') +
			'<TR><TD VALIGN=CENTER><FONT FACE=ARIAL,HELVETICA,VERDANA SIZE=3>' + message + '</FONT>' +
			'</TD></TR><TR><TD VALIGN=BOTTOM>' +
			'<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=0><TR><TD COLSPAN=2><HR></TD></TR><TR><TD>' +
			((typeof (cancelText) == 'string' && cancelText != '') ? ('<INPUT TYPE=button VALUE="' + cancelText + '" ONCLICK="with (window.opener) {' + cancelAction + '}">') : '') +
			'</TD><TD ALIGN=RIGHT>' +
			((typeof (okText) == 'string' && okText != '') ? ('<INPUT TYPE=button VALUE="' + okText + '" ONCLICK="with (window.opener) {' + okAction + '}">') : '') +
			'</TD></TR></TABLE></TD></TR></TABLE></FORM></BODY></HTML>'
		);
		close ();
		if (typeof (Event) != 'undefined') {
			Music.promptWindow.captureEvents (Event.KEYUP);
			Music.promptWindow.onKeyUp = new Function ('event','if (event.which == 13) {' + okAction + '} else if (event.which == 27) {' + cancelAction + '}; return false');
		}
	}
	Music.promptWindow.focus ();
}

function mo_installPlayer () {
	var optionsStr = '';
	for (var option in Music.installerOptions)
		optionsStr += ((optionsStr != '') ? '&' : '') + option + '=' + escape (Music.installerOptions [option])
	;
	Music.promptWindow = mo_openWindow ('http://www.beatnik.com/to/install-player.html?' + optionsStr,'mo_promptWindow',500,295,true);
}

function mo_retrieveVersion (appName) {
	var
		versionStr = '',
		numerals = '0123456789',
		charNo = appName.length - 1,
		currentChar,
		inVersion = false,
		parensLevel = 0
	;
	while (charNo >= 0) {
		currentChar = appName.charAt (charNo);
		if (currentChar == ')') {
			parensLevel++;
		} else if (currentChar == '(') {
			parensLevel--;
		} else if (parensLevel == 0) {
			if (inVersion || numerals.indexOf (currentChar) != -1) {
				inVersion = true;
				if (currentChar == ' ') charNo = 0;
					else if (currentChar == '.' || numerals.indexOf (currentChar) != -1) versionStr = currentChar + versionStr;
			}
		}
		charNo--;
	}
	return versionStr;
}

function mo_meetsMinVersion (versionToTest,minRequiredVersion) {
	var
		versionA = mo_retrieveVersion (versionToTest),
		versionB = mo_retrieveVersion (minRequiredVersion)
	;
	if (versionA.length < versionB.length) versionA += '.0.0.0.0.0.0.0.0.0.0.0.0'.substring (0,versionB.length - versionA.length);
	return versionA >= versionB;
}

function mo_hasMinVersion (minRequiredVersion) {
	return mo_meetsMinVersion (Music.playerVersion,minRequiredVersion);
}

function mo_isPlayerCompatible (minVersion,silentIfInadequate,showCompatibilityPrompt) {
	var result = false;
	if (Music.clientSupported) {
		if (typeof (minVersion) == 'string') Music.requiredMinVersion = minVersion;
		if (typeof (silentIfInadequate) == 'boolean') Music.silentIfInadequate = silentIfInadequate;
		if (typeof (showCompatibilityPrompt) == 'boolean') Music.showCompatibilityPrompt = showCompatibilityPrompt;
		if (Music.hasPlayer) {
			if (mo_hasMinVersion (Music.requiredMinVersion)) {
				result = true;
			} else {
				if (Music.client.upgradable && Music.showCompatibilityPrompt) mo_upgradePrompt ();
			}
		} else {
			if (Music.client.upgradable && Music.showCompatibilityPrompt) mo_installPrompt ();
		}
	}
	if (!result && Music.silentIfInadequate) mo_kill ();
	return Music.playerCompatible = result;
}

function mo_requireJava () {
	if (!Music.ignoreJavaDisabled) {
		Music.ignoreJavaDisabled = true;
		if (Music.clientSupported && Music.client.name == 'Netscape' && !navigator.javaEnabled ()) mo_enableJavaPrompt ();
	}
}

function mo_playerSubstitute (attribs) {
	var
		result = '',
		panelW = attribs.WIDTH - 0,
		panelH = attribs.HEIGHT - 0,
		tableDims = ' WIDTH=' + panelW + ' HEIGHT=' + panelH + ' HSPACE=' + attribs.HSPACE + ' VSPACE=' + attribs.VSPACE + ((attribs.ALIGN != null) ? (' ALIGN=' + attribs.ALIGN) : 'LEFT')
	;
	if (Music.enabled && Music.clientSupported && Music.client.upgradable && (attribs.HIDDEN == null || attribs.HIDDEN.toUpperCase () != 'TRUE')) {
		var
			getPlayerText = Music.hasPlayer ? Music.upgradePlayerText : Music.getPlayerText,
			getPlayerLink = '<A HREF="javascript://" ONCLICK="mo_installPlayer (); return false">'
		;
		if (typeof (Music.getPlayerImagesPath) == 'string' && panelW == 144 && (panelH == 60 || panelH == 45 || panelH == 15)) {
			result = getPlayerLink + '<IMG SRC="' + Music.getPlayerImagesPath + 'get-player-' + panelW + 'x' + panelH + '.gif"' + tableDims + ' ALT="' + getPlayerText + '" BORDER=0></A>';
		} else {
			if (panelW >= 90 && panelH >= 15) result = '<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 BGCOLOR=FFFFFF' + tableDims + '><TR ALIGN=CENTER VALIGN=CENTER><TD>' + getPlayerLink + '<FONT FACE="ARIAL,HELVETICA,VERDANA" COLOR=000000 SIZE=' + ((panelH >= 30) ? '3' : '1')  + '>' + getPlayerText + '</FONT></A></TD></TR></TABLE>';
		}
	}
	return ((result != '') ? result : ('<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0' + tableDims + '><TR><TD></TD></TR></TABLE>'));
}

function mo_checkForPlayer () {
	if (Music.clientSupported) {
		if (Music.playerType == 'Plug-in') {
			with (navigator) {
				for (var pluginNo = 0; pluginNo < plugins.length; pluginNo++) {
					if (plugins [pluginNo].name.indexOf ('Beatnik') != -1 && plugins [pluginNo].name.indexOf ('Stub') == -1) {
						Music.playerVersion = mo_retrieveVersion (plugins [pluginNo].name);
						if (Music.playerVersion == '') {
							if (Music.platform == 'Mac') {
								Music.playerVersion = '1.1.7';
							} else if (Music.platform == 'WebTV') {
								Music.playerVersion = '0.9.0';
							}
						}
						Music.hasPlayer = true;
						break;
					}
				}
				Music.hasCallbackIssue = mo_hasMinVersion ('1.3') && navigator.javaEnabled ();
			}
		} else {
			document.writeln (
				'<OBJECT ID=mo_testInstance CLASSID="CLSID:B384F118-18EE-11D1-95C8-00A024330339" WIDTH=0 HEIGHT=0>' +
				'<PARAM NAME=WIDTH VALUE=0>' +
				'<PARAM NAME=HEIGHT VALUE=0>' +
				'<PARAM NAME=AUTOSTART VALUE=FALSE>' +
				'</OBJECT>'
			);
			Music.hasPlayer = typeof (document.mo_testInstance.getVersion) != 'undefined';
			if (Music.hasPlayer) Music.playerVersion = mo_retrieveVersion (document.mo_testInstance.getVersion ());
		}
	}
}

/*** Standalone Support ***/

if (typeof (Music) == 'undefined') {
	Music = new Object ();
	Music.playerType = (navigator.appName == 'Microsoft Internet Explorer') ? 'ActiveX' : 'Plug-in';
}

/*** English Language Module ***/

function mo_upgradePrompt () {
	mo_promptUser ('Please Upgrade Beatnik','This page has been optimized for the features of version <B>' + Music.requiredMinVersion + ' (or higher)</B> of the Beatnik Player. The currently installed version in your browser is ' + Music.playerVersion + '.<P>If you choose to IGNORE this message, the page will continue to load normally, but may not function properly as designed by the author.','UPGRADE BEATNIK >>>','mo_installPlayer ()','IGNORE','mo_promptClose ()');
}

function mo_installPrompt () {
	mo_promptUser ('Beatnik Enhanced Content !!','This page has been optimized for the audio features of the <B>Beatnik Player</B>. It appears you do not have the Beatnik Player installed.<P>If you choose to IGNORE this message, the page will continue to load normally, except there will be no Beatnik audio.','INSTALL BEATNIK >>>','mo_installPlayer ()','IGNORE','mo_promptClose ()');
}

function mo_enableJavaPrompt () {
	mo_promptUser ('Please Enable Java','This page makes use of the interactive audio features of the Beatnik Player. Java is currently not enabled in your browser. In order for the page to function correctly with Beatnik, <B>you must have Java enabled</B>.<P>This page will continue to load normally, but some interactive audio functionality may be absent.','    OK    ','mo_promptClose ()');
}

Music.upgradePlayerText = 'Upgrade Beatnik';
Music.getPlayerText = 'Get Beatnik';

/*** Static Methods ***/

Music.hasMinVersion = mo_hasMinVersion;
Music.installPlayer = mo_installPlayer;
Music.isPlayerCompatible = mo_isPlayerCompatible;
Music.promptClose = mo_promptClose;
Music.promptUser = mo_promptUser;
Music.installerOptions = new Array ();

/*** Static Properties ***/

Music.ignoreJavaDisabled = false;
Music.playerCompatible = null;
Music.requiredMinVersion = '';
Music.showCompatibilityPrompt = true;
Music.silentIfInadequate = false;

/*** Static Read-only Properties ***/

Music.hasPlayer = false;
Music.playerVersion = '';

/*** Private Properties ***/

Music.absMinVersion = '';
Music.promptWindow = null;
Music.supportedClients = new Array ();

function mo_addSupportedClient (_name,_platform,_minVersion,_upgradable) {
	var ref = Music.supportedClients [Music.supportedClients.length] = new Object ();
	ref.name = _name;
	ref.platform = _platform;
	ref.minVersion = _minVersion;
	ref.upgradable = _upgradable;
}

mo_addSupportedClient ('Netscape','Win32','3.01',true);
mo_addSupportedClient ('Netscape','MacPPC','3.01',true);
mo_addSupportedClient ('Microsoft Internet Explorer','Win32','4.0',true);
mo_addSupportedClient ('WebTV Plus Receiver','WebTV','3.0',false);
mo_addSupportedClient ('WebTV Satellite Receiver','WebTV','3.0',false);

with (navigator) {
	if (mo_stringHasAny (userAgent,'Win95','Windows 95','WinNT','Windows NT','Win98','Windows 98')) {
		Music.platform = 'Win32';
	} else if (userAgent.indexOf ('PPC') != -1) {
		Music.platform = 'MacPPC';
	} else if (userAgent.indexOf ('WebTV') != -1) {
		Music.platform = 'WebTV';
	} else {
		Music.platform = (typeof (platform) == 'undefined') ? 'Unknown' : platform;
	}
	Music.clientVersion = mo_retrieveVersion (appVersion);
	Music.clientSupported = false;
	for (mo_clientNo = 0; mo_clientNo < Music.supportedClients.length; mo_clientNo++) {
		Music.client = Music.supportedClients [mo_clientNo];
		if (Music.client.name == appName && Music.client.platform == Music.platform && mo_meetsMinVersion (Music.clientVersion,Music.client.minVersion)) {
			Music.clientSupported = true;
			break;
		}
	}
}

if (typeof (mo_delayPlayerCheck) == 'undefined') mo_checkForPlayer ();
