/**
 * (./) plugin.js v4.0 18/05/2006
 * (by) cousot stephane @ http://www.ubaa.net/
 * (cc) some right reserved
 *
 *
 * plug-in tool.
 * Search for a Plug-In configured to accept document with a specified extension, get the installed 
 * Plug-In/ActiveX version, write the XHTML object properly, error messages, embeded media, etc…
 * This script is preconfigured to include QuickTime, Flash and Director object tags in XHTML 
 * document. For other plugins, you write the entire object code by yourself.
 *
 *
 * usage :
 * -------
 *	  - pluginCheckVersion( ext ), returns the installed plugin version for the speified extension
 *	  - searchForMimeType( ext ), returns the MIME-type who support the specified extension
 *	  - extension( url ), retrieve th efile extension from an URL
 *	  - pluginUseQT( url ), attempts to find if the given URL is opened by QuickTime
 *	  - pluginName( url ), returns the plugin name corresponding to the given file address
 *	  - pluginGetHTML( src, attrs, params ), returns the complete object HTML 
 *	  - pluginWriteHTML( src, attrs, params ), directly write the HTML to the document
 *	  - pluginGetEmbedVideoHTML( id, host, clip, {options} ), returns the complete embed video HTML
 *	  - pluginWriteEmbedVideoHTML( id, host, clip, {options} ), write the complete embed video HTML
 *	  - pluginGetErrorMsg( ext|mime|name, version, lang ), return the appropriate error message 
 *	  - pluginWriteErrorMsg( ext|mime|name, version, lang ), write the appropriate error message
 *
 *
 *	additionnals embeded options :
 *  ------------------------------
 * 	
 *	commons:
 * 	   - id, the object element ID
 * 	   - width, the object element width
 *     - height, the object element height
 *	   - fullscreen, allow to play the video in fullscreen mode
 *	   - allowscript, allow to element to be called by scripting
 *
 *  vimeo:
 *	   - (boolean) title
 *	   - (boolean) byline
 *	   - (boolean) portrait
 *	   - (string) color
 *
 *  youtube:
 *	   - (string) language
 *	   - (boolean) border
 *	   - (boolean) links
 *	   - (array[2]) color
 *
 *  google:
 *	   - (string) language
 *
 *  dailymotion:
 *	   - (boolean) links
 *	   - (boolean) autoplay
 *	   - (object) colors { background, glow, special, foreground }
 *
 *
 *
 *
 *
 * !!! require JavaScript 1.5
 *
 * This script is released under a Creative Commons Licence BY-SA
 * --> http://creativecommons.org/licenses/by-sa/2.5/
 */
 
 
 
 
var _pluginSetting = {

	".*flash" : {
		player: "Flash",
		classid: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
		codebase: "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab",
		pluginspage: "http://get.adobe.com/flashplayer/"
	},
	
	".*director" : {
		player: "Director",
		classid: "clsid:166B1BCA-3F9C-11CF-8075-444553540000",
		codebase: "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab",
		pluginspage: "http://get.adobe.com/shockwave/"
	},
	
	"quicktime.*" : {
		player: "QuickTime",
		classid: "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",
		codebase: "http://www.apple.com/qtactivex/qtplugin.cab",
		pluginspage: "http://www.apple.com/quicktime/download/"
	}
	
};

var _forceQtFor = [ "mp3" ];

				
				

// Write VBScript for MSIE
// !! ONLY USE TO DETECT FLASH or DIRECTOR and QUICKTIME ACTIVEX OBJECT
var MSIE =	(navigator.appVersion.indexOf('MSIE')!=-1) && 
	 		(navigator.appVersion.toLowerCase().indexOf("win")!=-1) &&
	 		(navigator.userAgent.indexOf('Opera')==-1);
if ( MSIE ) {
	document.write(
			'<script language="VBScript" type="text/vbscript">\n'
			+ ' Function VBPluginCheckVersion( ext )\n'
			+ ' on error resume next\n'
			+ ' Dim obj, version\n'
			+ ' version = -1\n'
			+ ' if ( ext="swf" ) then\n'
			+ ' 	set obj = CreateObject("ShockwaveFlash.ShockwaveFlash")\n'
			+ '		if ( IsObject(obj) ) then\n'
			+ '			version = obj.GetVariable("$version")\n'
			+ '		end if\n'
			+ '	elseif ( ext="dcr" ) then\n'
			+ '		set obj = CreateObject("SWCtl.SWCtl")\n'
			+ '		if ( IsObject(obj) ) then\n'
			+ '			version = obj.ShockwaveVersion("")\n'
			+ '		end if\n'
			+ ' else\n'
			+ '		set obj = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")\n'
			+ '		if ( IsObject(obj) ) then\n'
			+ '			if ( obj.IsQuickTimeAvailable(0) ) then\n'
			+ '				version = CInt(Hex(obj.QuickTimeVersion)/1000000)\n'
			+ '			end if\n'
			+ '		end if\n'
			+ '	end if\n'
			+ '	VBPluginCheckVersion = version\n'
			+ '	End Function\n'
			+ '</script>'
		);
}




// add method in setting object to figure out the correct key name according to the given mime-type,
// name or file extension ( a '.' is required )
_pluginSetting.key = function( obj ) {
	
	var search;
	var ext = extension(obj);
	
	if ( navigator.mimeTypes[obj] ) search = navigator.mimeTypes[obj].enabledPlugin.name;
	else search = searchForMimeType(ext);
	if ( !search ) search = obj;
	
	for( pattern in this ) {
		var re = new RegExp( pattern, "i" );
		if ( pattern && pattern!='key' && re.exec(search) ) return pattern;
	}
}
	


/**
 * Returns the installed plugin/activeX version, or -1 if the required object could not be found.
 *
 * @param ext	the request MimeType (i.e. 'swf'=flash, 'dcr'=director, ect… )
 * @return 		int, float
 */
function pluginCheckVersion( ext ) {
	// to do: prefer use the 'new ActiveXObject(...)' method to get the 
	// available version (if possible) and forget the usage of VBScrit
	var version = MSIE ? VBPluginCheckVersion( ext ) : JSPluginCheckVersion( ext );
	
	if ( MSIE && version!=-1 ) {
		var desc = version.split(" ");
		for (var i=(desc.length-1); i>=0; --i) {
			var v = parseFloat(desc[i]);
			if ( !isNaN(v) ) return v;
		}
	}
	
	return version;
}


/**
 * Return the installed plugin version, or -1 if the required object could not 
 * be found. This method use Javascript and non-ActiveX browser, prefers use the 
 * pluginCheckVersion(ext) method instead.
 *
 * @param ext	the request MimeType
 * @return 		int, float
 */
function JSPluginCheckVersion( ext ) {

	var mimetype = null;
	var plugin	 = null;
	
	mimetype = searchForMimeType( ext );
	if ( mimetype ) {
		plugin = navigator.mimeTypes[mimetype].enabledPlugin;
		// notes: most of the time the plug-in version is store in the plug-in
		// description, but it could be founded in the plug-in name (i.e. QT)...
		// in addition, a 'v' character coul preceded the version number.
		var desc = plugin.description.split(" ").concat(plugin.name.split(" "));
		for (var i=(desc.length-1); i>=0; --i) {
			var v = parseFloat( desc[i].replace("v", "") );
			if ( !isNaN(v) ) return v;
		}
	}
	
	return -1;
}



/**
 * Search and returns the MIME-type who support the specified extension, or null otherwise.
 *
 * @param ext	the request extension
 * @return		string or null
 **/
function searchForMimeType( ext ) {
	for (var i=0; i<navigator.mimeTypes.length; i++)
		if ( navigator.mimeTypes[i].suffixes.indexOf(ext)!=-1 ) 
			return navigator.mimeTypes[i].type;
	return null;
}

/**
 * Attempts to find the file extension in the given URL.
 *
 * @param url	the file URL address
 * @return 		string
 */
function extension( url ) {
	if ( url ) {
		url = url.replace( /\?.*/, '' );
		return url.substring( url.lastIndexOf(".")+1, url.length );
	}
	return "";
}


/**
 * Attempts to find if the given file can be load with QuickTime, or not.
 *
 * @param url	the file URL address
 * @return 		boolean
 */
function pluginUseQT( url ) {
	try {
		
		// force QT
		var ext = extension( url ).toLowerCase();
		for( key in _forceQtFor ) {
			if ( _forceQtFor[key].toLowerCase()==ext ) return true;
		}
		
		// or search if the available plugin is QT
		return pluginName(url.toLowerCase()).toLowerCase().indexOf("quicktime")!=-1
	}
	catch(e) {}
	return false;
}

/**
 * Check if the current version of QuickTime installed plugin receive DOM events.
 *
 * @param url	the file URL address
 * @return 		boolean
 */
function pluginUseQTDomEvents() {
	try {
		var info = navigator.mimeTypes[ 'video/quicktime' ].enabledPlugin.name.split(" ");
		return ( info[2]=="7.2.1" || parseFloat(info[2])>=7.2 );
	}
	catch(e) {}
	return false;
}


/**
 * Attempts to find the plugin associate with the given fiel extension and return is full name.
 *
 * @param url	the file URL address
 * @return 		string
 */
function pluginName( url ) {
	
	var ext  = extension(url);
	var mime = searchForMimeType( ext );
	var name = undefined;
	
	try { name = navigator.mimeTypes[mime].enabledPlugin.name; }
	catch(e) {}
	
	return name;
	
}


/**
 * Search for a plugin configured to load the given document, and returns the object/embed XHTML tags 
 * with all appropriete parameters. 
 *
 * 	additionnals parameters syntax
 *  ------------------------------
 * 	var params = {
 *		autoplay: true,
 *		loop: false,
 *		…
 *	}
 *
 * @param src		the file URL address to be load/play
 * @param attrs		[ an object representing all element aatributs to be inserted ]
 * @param params	[ an object representing all additional parameters to be included ]
 */
function pluginGetHTML( src, attrs, params ) {
	
	
	
	// define element minimum attributs
	if ( !attrs ) attrs = {};
	if ( !attrs.width ) attrs.width = "100%";
	if ( !attrs.height && attrs.height!=0 ) attrs.height = "100%";
	
	
	// check for embeded video
	// -> return pluginGetEmbedVideoHTML()
	// -> exit
	var matched = /http:\/\/(w{3}|video|)\.?(.*)\.com\/?(.*)?\/(.*)$/.exec(src);
	if ( 
		matched!=null && (
		matched[2]=='vimeo' ||
		matched[2]=='youtube' ||
		matched[2]=='google' || 
		matched[2]=='dailymotion'
	)) {
		return pluginGetEmbedVideoHTML(
			matched[2],
			matched[4].replace(/.*docid=/,''),
			attrs
		);
	}
		
	
	// check for document mime-type
	// and retrieve the right setting key
	var type = searchForMimeType( extension(src) );
	var key	 = _pluginSetting.key( type );
		
	// define default QTplayer parameters on the fly
	if ( pluginUseQT(src) ) {
		
		key = "quicktime.*";
		
		if ( !params ) params = {};
		if ( params.autoplay==null) params.autoplay = false;
		if ( params.loop==null ) params.loop = false;
		if ( params.controller==null ) params.controller = true;
		if ( params.enablejavascript==null ) params.enablejavascript = true;
		if ( pluginUseQTDomEvents() && params.postdomevents==null ) params.postdomevents = true;
		if ( params.controller==true && attrs.height!="100%" ) attrs.height+=16;
	}
	
	
	// include additionnals parameters
	var param_obj = "";
	var param_emb = "";
	if ( params ) {
		for (var prop in params) {
			param_obj	+='<param name="'+prop+'" value="'+params[prop]+'" />';
			param_emb	+=' '+prop+'="'+params[prop]+'"';
		}
	}
	if ( type!=null ) param_emb += ' type="'+type+'"';
	
	
	// list elements attributs
	var attrs_obj = "";
	var attrs_emb = "";
	for( var attr in attrs ) {
		attrs_obj += ' '+attr+'="'+attrs[attr]+'"';
		//attrs_emb += ( attr=='id' ? ' '+key+'="'+attrs[attr]+'_embed"' : ' '+attr+'="'+attrs[attr]+'"' );
		attrs_emb += ( attr=='id' ? ' name="'+attrs[attr]+'"' : ' '+attr+'="'+attrs[attr]+'"' );
	}
	
			
	// return HTML tags
	return  _pluginSetting[ key ] ?
				'<object'+attrs_obj
				+ ' classid="'+_pluginSetting[ key ].classid+'"'
	    		+ ' codebase="'+_pluginSetting[ key ].codebase+'"'
	    		+ '>\n'
	    		+ '	<param name="'+(pluginUseQT(src)?'src':'movie')+'" value="'+src+'" />'+param_obj
	    		+ '	<embed'+attrs_emb
	    		+ ' src="'+src+'"'
	    		+ ' '+param_emb
	    		+ ' pluginspage="'+_pluginSetting[ key ].pluginspage+'">'
	    		+ '	<\/embed>'
	    		+ '<\/object>'
	    		:
				'<object'+attrs_obj +'>\n'
	    		+ '	<param name="src" value="'+src+'" />'+param_obj
	    		+ '	<embed'+attrs_emb
	    		+ ' src="'+src+'"'
	    		+ ' '+param_emb
	    		+ '	<\/embed>'
	    		+ '<\/object>';
}


/**
 * Search for a plugin configured to load the given document, and write the object/embed XHTML tags 
 * with all appropriete parameters. 
 *
 * 	additionnals parameters syntax
 *  ------------------------------
 * 	var params = {
 *		autoplay: true,
 *		loop: false,
 *		…
 *	}
 *
 * @param src		the file URL address to be load/play
 * @param attrs		[ an object representing all element aatributs to be inserted ]
 * @param params	[ an object representing all additional parameters to be included ]
 */
function pluginWriteHTML( src, attrs, params ) {
	var html = pluginGetHTML( src, attrs, params );
	document.write( html );
	return true;
}



/**
 * Returns embeded video HTML object tags (Vimeo,Google, Dailymotion,Youtube)
 *
 *  additionnals embeded options
 *  ----------------------------
 * 	
 *	commons:
 * 	   - id, the object element ID
 * 	   - width, the object element width
 *     - height, the object element height
 *	   - fullscreen, allow to play the video in fullscreen mode
 *	   - allowscript, allow to element to be called by scripting
 *
 *  vimeo:
 *	   - (boolean) title
 *	   - (boolean) byline
 *	   - (boolean) portrait
 *	   - (string) color
 *
 *  youtube:
 *	   - (string) language
 *	   - (boolean) border
 *	   - (boolean) links
 *	   - (array[2]) color
 *
 *  google:
 *	   - (string) language
 *
 *  dailymotion:
 *	   - (boolean) links
 *	   - (boolean) autoplay
 *	   - (object) colors { background, glow, special, foreground }
 *
 *
 *
 * @param host		the hosting video website name
 * @param clip		the video clip id
 * @param param 	[ additionals elements attributs and video options ]
 *
 * @return String
 */
function pluginGetEmbedVideoHTML( host, clip, options ) {
	
	if ( !options ) options = {};
	
	var id  = options.id ? options.id : host+"_player";
	var w   = options.width ? options.width : "100%";
	var h   = options.height ? options.height : "100%";
	var fs  = options.fullscreen==false ? false : true;
	var sa  = options.allowscript ? options.allowscript : "always";
	var src	= "";
	
	
	
	// define video URL
	switch( host.toLowerCase() ) {
		
		case 'vimeo' :
			src = "http://vimeo.com/moogaloop.swf?clip_id="+clip
				+ "&amp;server=vimeo.com"
				+ "&amp;show_title="+( options.title ? 1 : 0 )
				+ "&amp;show_byline="+( options.byline ? 1: 0 )
				+ "&amp;show_portrait="+( options.portrait ? 1 : 0 )
				+ "&amp;color="+( options.color ? options.color : "00adef" )
				+ "&amp;fullscreen="+( fs ? 1 : 0 );
			break;
			
		case 'youtube' :
			src = "http://www."+( options.nocookie ? "youtube-nocookie" : "youtube" )+".com/v/"+clip
				+ "&hl="+( options.lang ? options.lang : "en" )
				+ "&border="+( options.border ? 1 : 0 )
				+ "&rel="+( options.links==false ? 0 : 1 )
				+ "&color1="+( options.color ? options.color[0] : "0x666666" )
				+ "&color2="+( options.color ? options.color[1] : "0xEFEFEF" )
				+ "&fs="+( fs ? 1 : 0 );
			break;
				
		case 'google' :
			src = "http://video.google.com/googleplayer.swf?docid="+clip
				+ "&hl="+( options.lang ? options.lang : "en" )
				+ "&fs="+( fs ? "true" : "false" );
			break;
			
		case 'dailymotion' :
			src = "http://www.dailymotion.com/swf/"+clip
				+ "&related="+( options.links==false ? 0 : 1 )
				+ "&autoPlay="+( options.autoplay ? 1 : 0 );
			if ( options.colors )
			src += "&colors="
				+ "background:"+options.colors.background
				+ ";glow:"+options.colors.glow
				+ ";foreground:"+options.colors.foreground
				+ ";special:"+options.colors.special;
			break;
	}
	
	
	// list elements attributs
	var attrs_obj = "";
	var attrs_emb = "";
	for( var key in options ) {
		if (
			key=='autoplay' || key=='links' || key=='fullscreen' || key=='allowscript' || 
			key=='byline' || key=='portrait' || key=='language'|| key=='border' || key=='color'
		) continue;
		attrs_obj += ' '+key+'="'+options[key]+'"';
		attrs_emb += ( key=='id' ? ' '+key+'="'+options[key]+'_embed"' : ' '+key+'="'+options[key]+'"' );
	}
	
	
	// return HTML elements
	return  '<object'+attrs_obj +'>\n'
    		+ '	<param name="movie" value="'+src+'" />'
    		+ ' <param name="allowfullscreen" value="'+fs+'" />'
    		+ ' <param name="allowscriptaccess" value="'+sa+'" />'
    		+ '	<embed'+attrs_emb
	   		+ ' src="'+src+'"'
			+ ' allowfullscreen="'+fs+'"'
			+ ' allowscriptaccess="'+sa+'"'
			+ ' type="application/x-shockwave-flash" '
    		+ '	<\/embed>'
    		+ '<\/object>';
}


/**
 * Write embeded video HTML object tags
 *
 * @param host		the hosting video website name
 * @param clip		the video clip id
 * @param param 	[ additionals elements attributs and video options ]
 */
function pluginWriteEmbedVideoHTML( host, clip, options ) {
	var html = pluginGetEmbedVideoHTML( host, clip, options );
	document.write( html );
	return true;
}


/**
 * Retunrs an error message in a specified language.
 *
 * @param for		the player name to be displayed, the file extension or mime-type
 * @param version	the required player version
 * @param lang		[ the message language : en (default)=english, fr=french ]
 * @return string
 */
function pluginGetErrorMsg( obj, version, lang ) {
	
	var msg;
	var key	 = _pluginSetting.key( obj );
	
	if ( !key ) return "";
	
	switch( lang ) {
		case 'fr' :
			msg = 'Ce document requiert la version %VERSION du lecteur "%PLAYER_NAME".<br />'
				+ '\t<a href="%LINK">Télécharger la dernière version gratuitement ici</a>';
			break;
		default :
			msg	= 'This document required the "%PLAYER_NAME" player version %VERSION. '
				+ 'This plugin could not be found,	or is not installed correctly.<br />'
				+ '\t<a href="%LINK">Download the latest version for free here</a>';
			break;
	}
	msg = '<div class="plugin-errmsg">\n\t<p>'+msg+'\n\t</p>\n</div>\n';
	msg = msg.replace( "%PLAYER_NAME", "<em>"+_pluginSetting[key].player+"</em>" );
	msg = msg.replace( "%VERSION", version );
	msg = msg.replace( "%LINK", _pluginSetting[key].pluginspage );
	
	return msg;
}

/**
 * Write an error message in a specified language.
 *
 * @param obj		the player name to be displayed, the file extension or mime-type
 * @param version	the required player version
 * @param lang		[ the message language : en (default)=english, fr=french ]
 */
function pluginWriteErrorMsg( obj, version, lang ) {
	var msg = pluginGetErrorMsg( obj, version, lang );
	document.write( msg );
}

