function mm_audio_player() {

	var me = this;

	me.inlineAudioPlayer = null;
	
	me.minWMPVersion = '5,1,52,701';
	me.minSWFVersion = '8,0,0,0';

	me.wmpSupported = null;
	me.swfSupported = null;

	me.swfInjected = false;
	me.wmpInjected = false;

	me.inlineAudioPlayerWMP = null;
	me.inlineAudioPlayerSWF = null;

	me.swfLoadingTimeoutID = 0;
	me.swfLoadedAfterTimeout = false;
	
	// these paths need to be generated using the static templatetag
	me.swfPath = '/assets/gusto/c/js/inlineAudioPlayer.swf';
    me.wmpScriptPath = '/assets/gusto/c/js/playerStateChange.js';
    
	me.currentEpisodeId = 0;
	me.previousEpisodeId = -1;

	me.mediaDuration = 0;

	me.playState = 1; // 1 = Stopped

	me.updateProgressIntervalID = 0;
	me.updateProgressIntervalMilliseconds = 200;

	this.stopSwfLoadingTimeout = function() {
		if (me.swfLoadingTimeoutID !== 0) {
			clearTimeout(me.swfLoadingTimeoutID);
		}
	};

	this.startSwfLoadingTimeout = function(delayedFunction) {
		// Delay ExternalInterface Callback until SWF is ready.
		var swfLoadTime = 1500;
		if (me.swfLoadedAfterTimeout) {
			swfLoadTime = 50;
		}
		me.stopSwfLoadingTimeout();
		me.swfLoadingTimeoutID = setTimeout(delayedFunction, swfLoadTime);
		me.swfLoadedAfterTimeout = true;
	};

	this.isClientIE = function() {
		if (navigator.appName.indexOf("Microsoft") != -1) {
			return true;
		}
		else {
			return false;
		}
	};

	this.isClientOSWindows = function() {
		if (navigator.appVersion.indexOf("Windows") != -1) {
			return true;
		}
		else {
			return false;
		}
	};

	this.isWMPInstalled = function() {
		var wmpInstalled = false;
		try
		{
			if (navigator.plugins && navigator.plugins.length) {
				for (var i=0; i < navigator.plugins.length; i++) {
					var plugin = navigator.plugins[i];
					if (plugin.name.indexOf("Windows Media Player") > -1) {
						wmpInstalled = true;
					}
				}
			}
			else {
				wmpObj = false;
				execScript('Option Explicit: On Error Resume Next: wmpObj = IsObject(CreateObject("MediaPlayer.MediaPlayer.1"))', 'VBScript');
				wmpInstalled = wmpObj;
			}
		}
		catch(err){
		}
		return wmpInstalled;
	};

	this.isWMPSupported = function() {
		if (me.isClientIE() && me.isClientOSWindows()) {
			if (me.isWMPInstalled()) {
				return true;
			}
			return false;
		}
		return false;
	};

	this.getFlashMovie = function(movieName) {
		var isIE = me.isClientIE();
		return (isIE) ? document.getElementById(movieName) : document[movieName];
	};

	this.injectWmpHTML = function() {
		if (!me.wmpInjected) {
			me.inlineAudioPlayer.innerHTML += '<object id="inlineAudioPlayerWMP" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=' + me.minWMPVersion + '" type="application/x-oleobject" width="1" height="1"><param name="uiMode" value="invisible" valuetype="data" /><param name="ShowDisplay" value="false" valuetype="data" /><param name="ShowControls" value="false" valuetype="data" /><param name="ShowStatusBar" value="false" valuetype="data" /><param name="AutoStart" value="false" valuetype="data" /><param name="PlayCount" value="1" valuetype="data" /></object><script type="text/javascript" for="inlineAudioPlayerWMP" event="playStateChange(NewState)" src="' + me.wmpScriptPath + '"></script>';
			me.inlineAudioPlayerWMP = document.getElementById('inlineAudioPlayerWMP');
			me.wmpInjected = true;
		}
	};

	this.isSWFSupported = function() {
		return swfDetectFlashVer(8, 0, 0);
	};

	this.injectSwfHTML = function() {
		if (!me.swfInjected) {
			me.inlineAudioPlayer.innerHTML += '<object id="inlineAudioPlayerSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + me.minSWFersion +'" width="1" height="1"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="' + me.swfPath + '" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed name="inlineAudioPlayerSWF" src="' + me.swfPath + '" quality="high" bgcolor="#ffffff" width="1" height="1" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /></object>';
			me.inlineAudioPlayerSWF = me.getFlashMovie("inlineAudioPlayerSWF");
			me.swfInjected = true;
		}
	};

	this.playMonitor = function(position, duration) {
		// This function can be overridden for UI development in playerUI.js.
	};

	this.swfUpdateProgress = function(position, duration) {
		// ExternalInterface call
		me.playMonitor(position, duration);
	};

	this.updatePlayStateWMP = function(stateNum) {
		if (stateNum != me.playState) {
			me.playState = stateNum;
			//me.playStateChange();
		}
	};

	this.playStateChangeCheckWMP = function(stateNum) {
		switch (stateNum) {
			case 1: // Stopped
				me.wmpStopUpdatingProgress(stateNum);
				me.updatePlayStateWMP(stateNum);
				break;
			case 3: // Playing
				me.wmpStartUpdatingProgress();
				me.updatePlayStateWMP(stateNum);
				break;
			case 8: // MediaEnded
				me.wmpStopUpdatingProgress(stateNum);
				me.updatePlayStateWMP(stateNum);
				break;
			default:
				me.wmpStopUpdatingProgress(stateNum);
				break;
		}
	};

	this.getProgressIntervalMilliseconds = function(mediaDuration) {
		if (mediaDuration < 25) {
			return 80;
		}
		else if (mediaDuration < 40) {
			return 150;
		}
		else if (mediaDuration < 80) {
			return 200;
		}
		else if (mediaDuration > 160) {
			return 350;
		}
		else if (mediaDuration > 400) {
			return 900;
		}
		else {
			return 200;
		}
	};

	this.wmpStopUpdatingProgress = function(stateNum) {
		if ((stateNum == 1) || (stateNum == 8)) {
			me.onStop();
		}
		if (me.updateProgressIntervalID !== 0) {
			clearInterval(me.updateProgressIntervalID);
		}
	};

	this.wmpMediaPosition = function() {
		if (me.inlineAudioPlayerWMP.controls.currentPosition !== 0) {
			var wmpPosition = me.inlineAudioPlayerWMP.controls.currentPosition * 1000; // convert seconds to millseconds
			var wmpDuration = me.inlineAudioPlayerWMP.currentMedia.duration * 1000;
			me.playMonitor(wmpPosition, wmpDuration);
		}
	};

	this.wmpStartUpdatingProgress = function() {
		// Called by WMP PlayStateChange events.
		me.wmpStopUpdatingProgress();
		me.mediaDuration = me.inlineAudioPlayerWMP.currentMedia.duration;
		me.updateProgressIntervalID = setInterval('mm_audio.wmpMediaPosition()', me.getProgressIntervalMilliseconds(me.mediaDuration));
	};

	this.wmpLoadMedia = function(episodeId) {
		var mediaURL = 'http://mediaweb.musicradio.com/show.asx?episode=' + episodeId + '&cap=2';
		me.inlineAudioPlayerWMP.URL = mediaURL;
	};

	this.onBuffer = function() {
		// This function can be overridden for UI development in playerUI.js.
	};

	this.onPlay = function() {
		// This function can be overridden for UI development in playerUI.js.
	};

	this.onPause = function() {
		// This function can be overridden for UI development in playerUI.js.
	};

	this.onStop = function () {
		// This function can be overridden for UI development in playerUI.js.
	};

	this.wmpPlayMedia = function() {
		me.inlineAudioPlayerWMP.controls.play();
		me.onPlay();
	};

	this.wmpPauseMedia = function() {
		me.inlineAudioPlayerWMP.controls.pause();
		me.onPause();
	};

	this.wmpTogglePause = function() {
		switch(me.inlineAudioPlayerWMP.playState) {
		case 0: // Undefined
			me.onBuffer();
			me.wmpLoadMedia(me.currentEpisodeId);
			me.wmpPlayMedia();
			break;
		case 2: // Paused
			me.wmpPlayMedia();
			break;
		case 3: // Playing
			me.wmpPauseMedia();
			break;
		case 10: // Ready
			me.wmpPlayMedia();
			break;
		default:
			break;
		}
	};

	this.playWMP = function(episodeId) {
		if (me.inlineAudioPlayerWMP) {
			if (episodeId != me.currentEpisodeId) {
				// When a new episode is clicked, always play it and clean-up any previous one.
				me.onBuffer();
				me.wmpLoadMedia(episodeId);
				me.previousEpisodeId = me.currentEpisodeId;
				me.currentEpisodeId = episodeId;
				me.wmpPlayMedia();
			}
			else {
				// When the same episode is clicked, toggle pause/play.
				me.wmpTogglePause();
			}
		}
	};

	this.onStopSWF = function() {
		me.playState = 0;
		me.onStop();
	};

	this.swfTogglePause = function() {
		if (me.playState == 2) {
			me.playState = 3;
			me.onPause();
		}
		else {
			me.playState = 2;
			me.onPlay();
		}
	};

	this.playSWF = function(episodeId) {
		if (me.inlineAudioPlayerSWF) {

			// When a new episode is clicked, always play it and clean-up any previous one.
			if (episodeId != me.currentEpisodeId) {
				me.previousEpisodeId = me.currentEpisodeId;
				me.currentEpisodeId = episodeId;
				me.onBuffer();
				me.playState = 2;
				me.onPlay();
			}
			else
			{
				// When clicking on the same episode, just toggle pause/play as normal.
				me.swfTogglePause();
			}
			// ExternalInterface Callback
			me.inlineAudioPlayerSWF.episodeClick(episodeId);
		}
	};

	this.play = function(episodeId) {
		if (me.wmpSupported) {
			me.playWMP(episodeId);
			return false;
		}
		else {
			if (me.swfSupported) {
				me.playSWF(episodeId);
				return false;
			}
		}
		return true;
	};

	this.initInlineAudioPlayer = function() {
	    me.inlineAudioPlayer = document.getElementById('inlineAudioPlayer');
	    if (me.inlineAudioPlayer) {
	        me.wmpSupported = me.isWMPSupported();
	        if (me.wmpSupported) {
	            me.injectWmpHTML();
	        }
	        else {
	            me.swfSupported = me.isSWFSupported();
	            if (me.swfSupported) {
	                me.injectSwfHTML();
	            }
	        }
	    }
	};

}

