/*
Contains routines for playing audio and video, using either QuickTime or Flash.
Works in both IE and non-IE.
Works around any popups to enable plugins.

The public methods here are:
  qtvideo_embed(params, minversion)
  flash_video(params, minversion)
  flash_audio(params, minversion)

You should also consider using SWFObject and QTObject insted of this library.
SWFObject supports flash "express install", and it deals with a subtle problem
with IE6 and Flash Player 9:
  http://blog.deconcept.com/2006/05/18/flash-player-bug-streaming-content-innerhtml-ie/
We differ in a number of ways; for example, classid is not actually necessary for Flash,
and our API is a bit more convenient (passing in an associative array).

To provide playing controls for Flash audio/video, several solutions can be used:

  FlowPlayer http://flowplayer.sourceforge.net/ 
  Flash MP3 Player http://www.jeroenwijering.com
  afAMP http://pyg.keonox.com/flashmp3player/
  Streaming MP3 Player http://www.sonify.org/home/feature/remixology/026_mp3player/

Example calls:

<script type="text/javascript">
  qtvideo_embed({src: 'http://uhurumovement.org/dummy.mov', qtsrc: 'rtsp://uhurumovement.org:554/SierraLeone1.mp4', width: '480', height: '390', autoplay: 'false'})
</script>

<script type="text/javascript">
  flash_video({movie: 'http://uhurumovement.org/flash/FlowPlayer/FlowPlayer.swf', width: 320, height: 263, allowScriptAccess: 'sameDomain',
  quality: 'high', scale: 'noScale', wmode: 'transparent',
  flashvars: {
    baseURL: 'http://uhurumovement.org/movies', videoFile: 'SierraLeone1.mp4.200.flv', autoPlay: 'false',
  bufferLength: 5, loop: 'false', autoBuffering: 'false'
  }})
</script>

<script type="text/javascript">
  flash_audio({movie: '/flash/flash_mp3_player/mp3player.swf?file=/public_mp3s/news-of-the-week-2006-09-30.mp3', width: 250: height: 20,
  flashvars: {autostart: 'true'},
});
*/

var MDA_AV_DBG = false;

// whether this browser supports ActiveX.
// it is quick to check whether we are on Windows, and whether window.ActiveXObject exists.
// (This will rule out IE/Mac where 'ActiveXObject' exists, but it isn't Windows).
// Unfortunately some versions of FireFox and Opera on Windows have a defined ActiveXObject.
// This is because they hard-code support for special cases like new ActiveXObject("MSXML2.XMLHTTP")
function has_activex() {
    return ((typeof 'ActiveXObject' != 'undefined') && (navigator.userAgent.indexOf('Win') != -1)
	    && (!navigator.plugins || navigator.plugins.length == 0)
	    );
} 

function convert_quicktime_version(ver) {
    if (!ver) return '';
    var nver = ver.toString(16);
    nver = nver.substring(0,1) + '.' + nver.substring(1,2) + '.' + nver.substring(2,3);
    return nver;
}

// return any string of digits and periods in name or description,
// or the string 'unknown'.
function plugin_version(plugin) {
    var matches = /[\d\.]+/.exec(plugin.name);
    if (matches) {
	// alert("got " + matches[0] + " from " + plugin.name); 
	return matches[0];
    }
    matches = /[\d\.]+/.exec(plugin.description);
    return matches ? matches[0] : 'unknown';
}

// see http://www.adobe.com/products/flashplayer/download/detection_kit/
var FLASHVERSION;

function get_flash_version() {
    if (typeof FLASHVERSION != 'undefined') return FLASHVERSION;
    FLASHVERSION = '';
    if (has_activex()) {
	for (var i=7;i >= 4; i--) {
	    try {
		var fl = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i);
		// a string like "WIN 8,0,24,0"
		FLASHVERSION = i == 7 ?  fl.GetVariable("$version").split(" ")[1].split(",")[0] : i;
		// it is unsafe to use GetVariable in some versions of Flash 6
		return FLASHVERSION;
	    }
	    catch(e) {
		//alert("unable to create QuickTime ActiveX: " + e);
	    }
	}
	// fall through
    }

    if (! FLASHVERSION)  {
	// var mt = navigator.mimeTypes['application/x-shockwave-flash'];
	// var plugin = mt ? mt.enabledPlugin : '';
	var plugin = navigator.plugins["Shockwave Flash"];
	// a string like "4.0 r47"
	// could parse as x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
	if (plugin) FLASHVERSION = plugin_version(plugin);
	// else alert("no plugin for quicktime mime type");
    }
    return FLASHVERSION;
}

var QTVERSION;
 
function get_quicktime_version() {
    if (typeof QTVERSION != 'undefined') return QTVERSION;
    QTVERSION = '';
    if (has_activex()) {
	try {
	    var qt = new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1");
	    QTVERSION = convert_quicktime_version(qt.QuickTimeVersion);
	}
	catch(e) {
	    //alert("unable to create QuickTime ActiveX: " + e);
	}
	// fall through
    }

    if (! QTVERSION)  {
	// Won't work on Opera 7 because it doesn't index by mime type; Opera 9 does
	var mt = navigator.mimeTypes['image/x-quicktime'];
	var plugin = mt ? mt.enabledPlugin : '';
	if (plugin) QTVERSION = plugin_version(plugin);
	// else alert("no plugin for quicktime mime type");
    }
    return QTVERSION;
}

// Safari ignores param children of embed/object until 1.3.
// Also Safari 1.0 has no support for wmode=transparent, and Safari of any
// version with Flash 6 won't do it either.
// After 1.1, it still doesn't do transparency for dynamic content (js or css hover). 
// The only workaround is to dynamically replace the flash with a static image when needed.
function _is_safari_1() {
    // alert('reporting safari 1'); return 1;
    return (navigator.userAgent.indexOf('Safari/1') != -1);
}

function _tagname() {
    return 'object';
    //return (_is_safari_1() ? 'embed' : 'object');
}

function _opentag(type) {
    return '<' + _tagname() + ' type="' + type + '"';
}

function _closetag() {
  return "</" + _tagname() + ">\n";
}

var ATT_PARAMS = ['width', 'height', 'data', 'id', 'style', 'class'];

function _hash_to_qs(obj) {
    var nv = '';
    for (var fv in obj) {
	if (nv) nv += "&"; // "amp;"; //"\n    &amp;";
	nv += fv + '=' + obj[fv];
    }
    return nv;
}

// The "data" attribute seems required for Firefox (vs. quicktime "src" or flash "movie"), 
// though it works either way with Safari and Opera.
function _object_html(params, lastchild) {
    var html = '';

    // serialize flashvars
    var fv = params['flashvars'];
    if (fv && (typeof fv != 'string')) {
	params['flashvars'] = _hash_to_qs(fv);
    }

    // params which are legal and appropriate as attributes
    for (var i in ATT_PARAMS) {
	var p = ATT_PARAMS[i];
	if (params[p]) html += " " + p + '="' + params[p] + '"';
	delete params[p];
    }

    // Safari 1 has to do everything as attributes, sigh.
    if (_is_safari_1()) {
	for (var p in params) {
	    var v = params[p];
	    html += " " + p + '="' + params[p] + '"';
	}
	html += ">\n";
    }
    else {
	html += ">\n";
	for (var p in params) {
	    var v = params[p];
	    html += "  <param name='" + p + "' value='" + v + "' />\n";
	}
    }
    if (lastchild) html += "  " + lastchild + "\n";
    // alert("made html: " + html);
    return html;
}

/*
Expected params include:
  width
  height
  src
  qtsrc
  autoplay
  controller
It is up to the caller to provide a dummy src for rtsp.
*/

/*
codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"

See also QTObject:
   http://blog.deconcept.com/2005/01/26/web-standards-compliant-javascript-quicktime-detect-and-embed/
and
  http://realdev1.realise.com/rossa/rendertest/quicktime.html

For Windows IE, a qtsrc without a src is ok, because the object is specified anyway
by classid.
For non-IE, a src without a qtsrc is ok?

For some plugins, you can avoid the classid in IE if you know a mime type that is sure to 
bring up what you want. For example, 
   <object type="video/x-ms-wmv" data="foo.wmv"><param name="src" value="foo.wmv"/>...</object>
instead of classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"
According to
  http://alistapart.com/articles/byebyeembed 
the "src" param is needed in IE and Safari (it may have been necessary for Safari 1.0
because it ignores all params but it is not necessary for Safari 2.x).

According to the same article, type="video/quicktime" and type="application/x-quicktime"
are *not* sufficient for IE, and their only proposal is IE conditional comments
(without using javascript).

There is allegedly a problem that QuickTime won't always do progressive download
with some despite preparation for streaming [with what browser, what quicktime versions,
and what file types?]:
  http://www.networkworld.com/columnists/2006/030606internet.html
  http://lists.apple.com/archives/quicktime-users/2003/Jun/msg00241.html
This perhaps can be addressed by setting QTSRCDONTUSEBROWSER=true.
It defaults to false. When true, the browser won't be doing the downloading (which
means no browser caching, but possibly no problems with lack of progressive download
either). 



 */
function qtvideo_embed_html(params, minversion) {

    var qtver = get_quicktime_version();
    var src = params['src'];
    var html;
    if (!qtver) {
	if (params['qtsrc']) src = params['qtsrc'];
	html = "<div>You seem not to have QuickTime installed. You can download it from <a href='http://www.apple.com/quicktime/download/'>www.apple.com/quicktime/download/</a>.</div>" +
		"You can try to get the content directly anyway if you want: <a href='" + src + "'>" + src + "</a>";
	return html;
    }
    if (minversion && qtver < minversion) {
	if (params['qtsrc']) src = params['qtsrc'];
	html = "<div>You have QuickTime version " + qtver + " while we require " + minversion + " . You can download it from <a href='http://www.apple.com/quicktime/download/'>www.apple.com/quicktime/download/</a>.</div>" +
	"You can try to get the content directly anyway if you want: <a href='" + src + "'>" + src + "</a>";
	return html;
    }
    var opentag;
    if (has_activex()) 
	opentag = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"';
    else {
	// pluginspage is only for embed:  pluginspage="http://www.apple.com/quicktime/download/"';
	opentag = _opentag('video/quicktime');
	params['data'] = src; delete params['src'];
    }
    var html = opentag + _object_html(params) + _closetag();
    if (MDA_AV_DBG) alert("inserting html: " + html);
    return html;
}

function qtvideo_embed(params, minversion) {
    var html = qtvideo_embed_html(params, minversion);
    document.write(html);
}

/*
see:
  http://www.alistapart.com/articles/flashsatay/
  http://flowplayer.sourceforge.net/
  http://www.bobbyvandersluis.com/ufo/
  http://blog.deconcept.com/swfobject/
  http://weblogs.macromedia.com/accessibility/archives/2005/08/in_search_of_a.cfm
  http://www.alleged.org.uk/pdc/2004/02/14.html

expected params:
  movie
  allowScriptAccess
  quality
  scale
  wmode
  flashvars

The flashvars value can be a string or a hash.
For FlowPlayer, the accepted flashvars are:
  baseURL
  videoFile
  autoPlay
  bufferLength
  loop
  autoBuffering
  splashImageFile

Note, the unused classid is:
   classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
The unused codebase can have an optional version fragment:
  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"

UFO, SWFObject, and the Macromedia Flash Detection Kit support "Express Install",
Note that "Express Install" only works if there is already at least version 6.0.65.
See here for more info: http://www.dncompute.com/blog/2006/02/19/flash-player-express-install.html 
I'm not sure of the relationship between "Express Install" and "Auto Update" which
uses: http://fpdownload.macromedia.com/pub/flashplayer/update/current/swf/autoUpdater.swf

You often want wmode: 'transparent' to prevent Flash going on top of all dhtml:
  http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_15523

Note that there are problems on Safari with it ignoring <param> under <object> prior to Safari 2.0:
  http://blog.deconcept.com/swfobject/

*/
function flash_video(params, minversion) {
    // alert("You have flash version: " + get_flash_version());
    var movie = params['movie'];
    params['data'] = movie;
    // or to http://www.adobe.com/go/getflashplayer ?

    var html = _opentag("application/x-shockwave-flash") + 
	_object_html(params, 
		     "<div>You seem not to have Flash; you can download it from <a href='http://www.macromedia.com/go/getflashplayer'>here</a>.</div>") +
	_closetag();
    // alert("inserting html: " + html);
    document.write(html);
}

/*
<object id="MediaPlayer" width=320 height=286 classid="CLSID:22D6f312-B0F6-11D0-94AB-0080C74C7E95" standby="Loading Windows Media Player components..." type="application/x-oleobject" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112">

<param name="filename" value="http://yourdomain/yourmovie.wmv">
<param name="Showcontrols" value="True">
<param name="autoStart" value="True">

<embed type="application/x-mplayer2" src="http://media.pmcmovies.com/SixtiesLove.wmv" name="MediaPlayer" width=320 height=240></embed>

</object>

 */

/*
flash music players
   http://blog.forret.com/2005/01/playing-mp3-with-an-embedded-flash-player/
*/

function flash_audio(params, minversion) {
    flash_video(params, minversion);
}

