/*
 * mv_embed version .5
 * for details see: http://metavid.ucsc.edu/wiki/index.php/Mv_embed 
 * and or the README
 *
 * All Metavid Wiki code is Released under the GPL2
 * for more info visit http:/metavid.ucsc.edu/code
 * 
 * @url http://metavid.ucsc.edu
 * 
 * portions sampled from the vlc browser interface:
 * http://people.videolan.org/~damienf/plugin-0.8.6.html * 
 * 
 * parseUri:
 * http://stevenlevithan.com/demo/parseuri/js/
 * 
 * config values you can manually set the location of the mv_embed folder here 
 * (in cases where media will be in a different place than the javascript)
 */
var mv_embed_path = null;
//whether or not to load java from an iframe. 
//note: this is necessary for remote embeding because of java security model)
var mv_java_iframe = true;
//media_server mv_embed_path (the path on media servers to mv_embed for java iframe with leading and trailing slashes)
var mv_media_iframe_path = '/mv_embed/';
//init the global client detect type:
var global_embed_type = null;
var global_ogg_list = new Array();
var _global = this;
var global_dom_ready=0;

var global_libreq= new Object();
var parseUri=function(d){var o=parseUri.options,value=o.parser[o.strictMode?"strict":"loose"].exec(d);for(var i=0,uri={};i<14;i++){uri[o.key[i]]=value[i]||""}uri[o.q.name]={};uri[o.key[12]].replace(o.q.parser,function(a,b,c){if(b)uri[o.q.name][b]=c});return uri};parseUri.options={strictMode:false,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};

//get mv_embed location if it has not been set
if(!mv_embed_path){
	getMvEmbedPath();
}
js_log("mv embed path:"+ mv_embed_path);
//the default thumb nail for missing images:
var mv_default_thumb_url = mv_embed_path + 'images/vid_default_thumb.jpg';

//get the embed type (if not forced): 
if(!global_embed_type){
	global_embed_type = getEmbedType();  
}
//load an external JS (similar to jquery .require plugin)
//but checks for object availability rather than load state
var mvJsLoader = {
	libreq:{},
	load_time:0,
	doLoad:function(libs,callback){
		if(libs){this.libs=libs;}else{libs=this.libs;}
		if(callback){this.callback=callback}else{callback=this.callback;}
		var loading=0;
		for(i in libs){
			//js_log('on lib:'+i + ' '+libs[i]);
			if(!this.libreq[i])loadExternalJs(mv_embed_path + libs[i]);
			this.libreq[i]=1;				
			if(eval('typeof '+i)=='undefined'){
				//js_log('wating for '+ i + ' src:'+ libs[i]);
				loading=1;
			}
		}
		if(loading){
			if( this.load_time++ > 100){ //time out after around 5 seconds 
				js_error('mv_embed: unable to load required javascript libraries\n'+
						 'insert script via DOM has failed ' );			
			}else{
				setTimeout('mvJsLoader.doLoad()',50);
			}
		}else{
			callback();
		}
	}
}
//setup mv_embed object make version info and load required lib:
//it also queues onLoad functions (until Prototype/Scriptaculous is loaded) 
var mvEmbed = {
  Version: '0.5',  
  loaded:false,
  load_time:0,
  flist:Array(),
  loading:false, 
  pc:null, //used to store pointer to parent clip (when in playlist mode) 
  //two loading stages one to first get jQuery
  load_libs:function(){
  	mvJsLoader.doLoad({'window.jQuery':'jquery/jquery-1.2-2.js'},function(){
  		//once jQuery is loaded set up no conflict: 
  		_global['$j'] = jQuery.noConflict();
		//load all the rest of the libs: 
		var plugins = {
			//'$j.sibling':'jquery/src/selector/selector.js',
			//'$j.event':'jquery/src/event/event.js',
			//'$j.ajax':'jquery/src/ajax/ajax.js',
			//'$j.fx':'jquery/src/fx/fx.js',		
			//disable the jquery slider for now use prototype/scriptaculus
			//'$j.fn.offsetParent':'jquery/dimensions/jquery.dimensions.js',
			//'$j.ui.mouseInteraction':'jquery/jqueryUI/ui.mouse.js',
			//'$j.ui.slider':'jquery/jqueryUI/ui.slider.js',
			
			//temporarily use the scriptaculus slider (jQuery based UI still under dev)
			'Prototype':'scriptaculous/lib/prototype.js',
			'Control':'scriptaculous/src/slider.js'
		}
		plugins[global_embed_type+'Embed']='mv_'+global_embed_type+'Embed.js';
		mvJsLoader.doLoad(plugins, function(){mvEmbed.init()});
  	});	    		
  },
  addLoadEvent:function(fn){  	
  	this.flist.push(fn);  	
  },  
  init: function(){
  	//js_log('init');
  	/* jQuery .ready does not work when jQuery is loaded dynamically
  	 * for an example of the problem see:1.1.3 working:http://pastie.caboo.se/92588
  	 * and >= 1.1.4 not working: http://pastie.caboo.se/92595
  	 * $j(document).ready( function(){  	 */
  	 if(global_dom_ready){
  			js_log("doc ready");
			mv_embed();
			//run any queued functions:			
			while (mvEmbed.flist.length){
				mvEmbed.flist.shift()();
			}
	}else{
		if( this.load_time++ > 100){
			js_error('mv_embed: dom never ready');
		}else{
			setTimeout('mvEmbed.init()',50);
		}
	}
	//);
  }
}
//ENTRY POINT when dom ready:
function init_mv_embed(){
	global_dom_ready=1;
	//check if this page does have video or playlist
	if(document.getElementsByTagName("video").length!=0 ||
	   document.getElementsByTagName("playlist").length!=0){
		mvEmbed.load_libs();
	}else{
		js_log('no video or playlist on the page... (done)');
	}
}


//SET DOM Ready state:
// for Mozilla browsers
if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", function(){init_mv_embed()}, false);
}
//for IE:
if (document.all && !window.opera){ //Crude test for IE
//Define a "blank" external JavaScript tag
  document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>')
  var contentloadtag=document.getElementById("contentloadtag")
  contentloadtag.onreadystatechange=function(){
    if (this.readyState=="complete")
      init_mv_embed();
  }
}

 
/*
* Coverts all occurrences of <video> tag into video object
* (if a native support is not found) 
*/
function mv_embed(){    
	//get mv_embed location if it has not been set
	if(!mv_embed_path){
		getMvEmbedPath();
	}
	js_log('mv_embed ' + mvEmbed.Version);
    //send a request to load the given type
    js_log('detected: '+ global_embed_type);
    video_elements = document.getElementsByTagName("video");
    //js_log('found video '+ video_elements.length);
    if( video_elements.length > 0) {     	
        for(i = 0; i < video_elements.length; i++) {           	         	        
            //grab id:
            vid_id = video_elements[i].getAttribute("id");       
            //if vid_id is empty
            if(!vid_id || vid_id==''){
  				video_elements[i].id= 'v'+ global_ogg_list.length;    	
            }
            //js_log('on video ' + vid_id );      	                        	
            if(global_embed_type=='native'){ 
            	//native html5 support... but probably want to rewrite this as well. 
            }else{                        	
            	//create the video interface:
				var videoInterface = new embedVideo(video_elements[i]);	
                //swap the video element for our own embed video element           
                js_log('made videoInterface: ' + videoInterface.id)
                if( swapEmbedVideoElement(video_elements[i], videoInterface) ){
	             	//decrement i cuz we have swaped out the current video element
	                i--;
	            }  
	            
            }                                                          
        }
    }else{
    	js_log('no <video> elements found');
    }
    //if there are no playlist elements do not load the playlist-js
    playlist_elements = document.getElementsByTagName("playlist");
    if( playlist_elements.length > 0) {   
    	//playlist elements exist include the playlist library
		loadExternalJs(mv_embed_path + 'mv_playlist.js');
		do_playlist_functions(playlist_elements);
    }
}
var pl_load_time=0
function do_playlist_functions(){
	if(typeof mvPlayList =='undefined'){
		if(pl_load_time++ > 100){
			alert('unable to load mv_playlist.js');
		}else{
			setTimeout('do_playlist_functions()', 50);
		}
	}else{
		playlist_elements = document.getElementsByTagName("playlist");
		js_log('loded pl js ' +playlist_elements.length );
		for(var i = 0; i < playlist_elements.length; i++) {  
			var pl_id = playlist_elements[i].getAttribute('id');
			if(!pl_id || pl_id==''){
  				playlist_elements[i].id = 'v'+ global_ogg_list.length;    	
            }
			//create new playlist interface:
			var playlistInterface = new mvPlayList( playlist_elements[i] );
			if(swapEmbedVideoElement(playlist_elements[i], playlistInterface) ){	                 	   
				i--;			
			}
		}
	}
}

/*
* the base video control JSON object with default attributes
*    for supported attribute details see README
*/
var video_attributes = {
    "id":null,
    "class":null,
    "style":null,
    "name":null,     
    "innerHTML":null,
    "width":"320",
    "height":"240",
    
    "src":null,      
    "autoplay":false,   
    "start":0,
    "end":null,
    "controls":false,            
    
    //custom attributes for mv_embed: 
    "thumbnail":null, 
    "linkback":null, 
    "embed_link":false };

//state attributes (per html5 spec http://www.whatwg.org/specs/web-apps/current-work/#video)
var video_states={
    "paused":true,
    "readyState":0,  //http://www.whatwg.org/specs/web-apps/current-work/#readystate
    "currentTime":0, //current playback position (should be overwritten by local functions) 
    "duration":NaN   //media duration (read from file)
}

/*
* createEmbedVideoElement 
* takes a video element as input and swaps it out with 
* an embed video interface based on the video_elements attributes
*/
function swapEmbedVideoElement(video_element, videoInterface){
	js_log('do swap');
	embed_video = document.createElement('div');	
	//inherit the video interface  
	for(method in  videoInterface){
		if(method!='readyState'){ //readyState crashes IE
			if(method=='style'){
					embed_video.setAttribute('style', videoInterface[method]);			
			}else if(method=='class'){
				if(isIE())
					embed_video.setAttribute("className", videoInterface['class']);
				else
					embed_video.setAttribute("class", videoInterface['class']);
			}else{		
				//normal inherit: 
				embed_video[method]=videoInterface[method];
			}
		}
	}
	///js_log('did vI style');
  	//now swap out the video element for the embed_video obj:
    var parent_elm = video_element.parentNode;
    parent_elm.removeChild(video_element);
    
    //append the object into the dom: 
    parent_elm.appendChild(embed_video);  
   
    
    //now run the getHTML on the new embedVideo Obj:
    embed_video.getHTML(); 
    //js_log('html set:' + document.getElementById(embed_video.id).innerHTML);
    
    //store a reference to the id 
    //(for single instance plugins that need to keep track of other instances on the page)
    global_ogg_list.push(embed_video.id);
        
    js_log('append child: ' + embed_video.id + ' len:'+global_ogg_list.length);
 	return true;
}
/* 
*  The base embedVideo object constructor 
*/
var embedVideo = function(element) {	
	return this.init(element);
};
embedVideo.prototype = {
	slider:null,
	init: function(element){		   
		 //inherit all the default video_attributes 
	    for(var attr in video_attributes){       
	        if(element.getAttribute(attr)){
	            this[attr]=element.getAttribute(attr);
	            //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+'elm_val:' + element.getAttribute(attr) + "\n (set by elm)");  
	        }else{        
	            this[attr]=video_attributes[attr];
	            //js_log('attr:' + attr + ' val: ' + video_attributes[attr] +" "+ 'elm_val:' + element.getAttribute(attr) + "\n (set by attr)");  
	        }
	    }
	    //init the default states: 
	    for(var state in video_states){
	    	 this[state]=video_states[state];
	    }
	    //if the thumbnail is null replace with default thumb:
	    if(!this['thumbnail']){
			this['thumbnail'] = mv_default_thumb_url;
	    }
	    //if style is set override width and height
	    if(element.style.width)this.width = element.style.width.replace('px','');
	    if(element.style.height)this.height = element.style.height.replace('px','');
	    //set the plugin id
	    this.pid = 'pid_' + this.id;
	         
	    //grab any innerHTML and set it to missing_plugin_html
	    if(element.innerHTML!=''){
	        this.user_missing_plugin_html=element.innerHTML;
	    } 
	    /*
	    * override all relevant exported functions with the {embed_type} Object 
	    * place the base functions in parent.{function name}
	    */
	    if(global_embed_type){           
	        eval('embedObj = ' +global_embed_type +'Embed;');
	        //js_log('set embed obj');
	        for(method in embedObj){
	        	//ghetto js parrent method preservation for local overwitten methods
	        	if(this[method])this['parent_' + method] = this[method];
	            this[method]=embedObj[method];
	        }
	    }  
	   //do a local call to getDuration (as the plugin may not be loaded yet) 
	   this.getDuration();
	   //test: 
	   //js_log('HTML FROM IN OBJECT' + this.getHTML());
	   //return this object:	   
	   return this;
	},
	 /*
	  * funciton getDuration in milliseconds 
	  * special case derive duration from request url (in float seconds) @@todo should be milliseconds
	  * (for media_url?t=ntp_start/ntp_end url request format
	  */  
	 getDuration : function(){	 	
	 	 js_log('get duration for:' + this.src);
		 var index_time_val = false;
	     if(this.src.indexOf('?t=')!=-1)index_time_val='?t=';
	     if(this.src.indexOf('&t=')!=-1)index_time_val='&t=';
	     if(index_time_val){
	     	var end_index = (this.src.indexOf('&', this.src.indexOf(index_time_val))==-1)?
	     					this.src.length:
			    			this.src.indexOf('&', this.src.indexOf(index_time_val));
		    this.start_offset = ntp2seconds(this.src.substring( 
	   				this.src.indexOf(index_time_val)+index_time_val.length,
		    		this.src.indexOf('/', this.src.indexOf(index_time_val) )));
	   		this.duration = ntp2seconds(this.src.substring(
		    		this.src.indexOf('/', this.src.indexOf(index_time_val))+1, end_index)
		    	) - this.start_offset;
		    //put values into ms:
		    this.start_offset =  this.start_offset*1000
		    this.duration = this.duration*1000;
	     }else{
	     	//else normal media request (can't predict the duration)
	     	this.duration=null;
	   	 	this.start_offset=0;
	     }
		 //return duration in ms: 
	     return this.duration;
	},
	/* get the duration in ntp format */
	getDurationNTP:function(){
		return seconds2ntp(this.getDuration()/1000);
	},
	getHTML : function (){
		js_log('get html: ' + $j('#'+this.id).html() );
	    //returns the innerHTML based on auto play option and global_embed_type
	    //if auto play==true directly embed the plugin
	    if(this.autoplay){ 	   
			this.thumbnail_disp = false;
			this.innerHTML =  this.getEmbedHTML() ;
	    }else{
	        //if autoplay=false or render out a thumbnail with link to embed html      
	       this.thumbnail_disp = true;
	       this.innerHTML = this.getThumbnailHTML();
	    }
	},
	/*
	* get missing plugin html (check for user included code)
	*/ 
	getPluginMissingHTML : function(){		
	    if(this.user_missing_plugin_html){
	        return this.user_missing_plugin_html;
	    }else{
		  return '<div style="margin:6px;width:'+this.width+'px;height:'+this.height+'px"><p>Supported in-browser playback methods include: '+
			' <a href="http://www.videolan.org/doc/play-howto/en/ch04.html#id293992">vlc plugin</a> IE & Firefox (linux, osx, win)<br> '+		
			' <a href="http://java.com/en/download/index.jsp">java plug-in</a> IE & Firefox (linux, osx, win) <br>'+
			' generic application/ogg mine type also supported (<a href="http://mplayerplug-in.sourceforge.net/">mplayer</a>, totem etc)' +
			' <br>for more info <i>see metavid <a href="http://metavid.ucsc.edu/wiki/index.php/MetavidFAQ#How_can_I_play_back_Metavid_video">playback help</a></i>'+
			'<p><b>alternatively</b> you can <a href="'+this.src +'">'+
			'download this clip</a> to be viewed outside the web browser with video application such as '+
				'<a href="http://www.videolan.org/vlc/">VLC</a>'+
			'</div>';
		}
	},
	//updates the video src
	//@@todo virtual playlist support and addVideoSrc
	updateVideoSrc : function(src){
		this.src = src;
	},
	//updates the thumbnail if the thumbnail is being displayed
	updateThumbnail : function(src){
		if(this.thumbnail_disp){
			//just do a simple swap
			if(typeof Effect=='undefined'){	
				this['thumbnail'] =src;
				document.getElementById('img_thumb_'+this.id);
			}else{		
				//do a fancy fade swap
				//create new image
			 	var im = document.createElement("img");
			 	im.src=src;
			 	im.style.display='none';
			 	im.style.position='absolute';
			 	im.style.zindex='2';
			 	im.style.top='0px';
			 	im.style.left='0px';
			 	im.style.width=this.width;
			 	im.style.height=this.height;
			 	im.id='new_img_thumb_'+this.id;
			 	var im_container = document.getElementById('dc_'+this.id);
			 	im_container.appendChild(im);
				//new Effect.Fade('img_thumb_'+this.id, {duration:.5});
				new Effect.Appear('new_img_thumb_'+this.id, {duration:.5,from:0.0,to:1.0,
					afterFinish:thumbnail_restore_id} );
			}
		}
	},
	getThumbnailHTML : function (){
	    var thumb_html = '';
	    var class_atr='';
	    var style_atr='';
	    //if(this.class)class_atr = ' class="'+this.class+'"';
	    //if(this.style)style_atr = ' style="'+this.style+'"';
	    //    else style_atr = 'overflow:hidden;height:'+this.height+'px;width:'+this.width+'px;';   
	
	    //put it all in the div container dc_id
	    thumb_html+= '<div id="dc_'+this.id+'" style="position:relative;'+
	    	' overflow:hidden; top:0px; left:0px; width:'+this.width+'px; height:'+this.height+'px; z-index:0;">'+
	        '<img width="'+this.width+'" height="'+this.height+'" style="position:relative;width:'+this.width+';height:'+this.height+'"' +
	        ' id="img_thumb_'+this.id+'" src="' + this.thumbnail + '">';
	    
	  	thumb_html+=this.getPlayButton();
	    //add link back if requested
	    if(this.linkback){
	    	thumb_html+='<div style="position:absolute;bottom:0px;right:0px;z-index:1">'+
		     '<a title="clip linkback" target="_new" href="'+this.linkback+'">';
		    thumb_html+=getTransparentPng({id:'lb_'+this.id, width:"27", height:"27", border:"0", 
						src:mv_embed_path + 'images/vid_info_sm.png' });
			thumb_html+='</div>';    	
	    }
	    //add in embed link (if requested) 
	    if(this.embed_link){	
	    	var right_offset = (this.linkback)?30:0;
			thumb_html+='<div style="position:absolute;bottom:0px;right:'+right_offset+'px;z-index:1">'+
		     '<a title="Playlist Embed Clip Code" href="javascript:document.getElementById(\''+this.id+'\').hideShowEmbedCode();">';
	
			thumb_html+=getTransparentPng(new Object ({id:'le_'+this.id, width:"27", height:"27", border:"0", 
						src:mv_embed_path + 'images/vid_embed_sm.png' }));
			thumb_html+='</a></div>';
			//make link absolute (if it was not already)
			embed_thumb_html = (this.thumbnail.indexOf('http://')!=-1)?this.thumbnail:mv_embed_path + this.thumbnail;
			var embed_code_html = '&lt;script type=&quot;text/javascript&quot; ' +
						'src=&quot;'+mv_embed_path+'mv_embed.js&quot;&gt;&lt;/script&gt' +
						'&lt;video id=&quot;'+this.id+'&quot; ' + 
						'src=&quot;'+this.src+'&quot; ' + 
						'thumbnail=&quot;'+embed_thumb_html+'&quot;/&gt;';
	
			//add the hidden embed code:
			thumb_html+='<div id="embed_code_'+this.id+'" style="border:solid;border-color:black;overflow:hidden;display:none;position:absolute;bottom:2px;right:'+(right_offset+30)+'px;width:'+(this.width-70)+'px;z-index:1">'+
				'<input onClick="this.select();" type="text" size="40" length="1024" value="'+embed_code_html+'">'
				 '</div>';
	    }    
	
	    thumb_html+='</div>';
	
	    return thumb_html;
	},
	getPlayButton:function(id){
		if(!id)id=this.id;
		  //put in the center: 
	    var play_btn_height = play_btn_width = 109;
	    var top = Math.round(this.height/2)- (play_btn_height/2);
	    var left = Math.round(this.width/2)- (play_btn_width/2);
	    out='';
	    out+='<div style="position:absolute;top:'+top+'px;left:'+left+'px;z-index:1">'+
				     '<a id="big_play_link_'+id+'" title="Play Media" href="javascript:document.getElementById(\''+id+'\').play();">';	
				     
	        //fix for IE<7 and its lack of PNG support:
		out+=getTransparentPng(new Object ({id:'play_'+id, width:play_btn_width, height:play_btn_height, border:"0", 
						src:mv_embed_path + 'images/mv_embed_play.png' }));				
		out+='</a></div>';
		return out;
	},
	//display the code to remotely embed this video:
	//if scriptaculus is available animate its appearance. 
	hideShowEmbedCode : function(){
		if($j('#embed_code_'+this.id).css('display')=='none'){
			$j('#embed_code_'+this.id).fadeIn("slow");
		}else{
			$j('#embed_code_'+this.id).fadeOut("slow", function(){
				$j('#embed_code_'+this.id).css('display', 'none');
			});
		}		
		/* this should workd but does not! :( 
		$j('#embed_code_'+this.id).toggle(function(){
			$j(this).fadeIn("slow");	
		},function(){
			$j(this).fadeOut("slow");
		} );
		* 
		*/		
	},			
	/*
	*  base embed controls 
	*	the play button calls 
	*/
	play : function(){	
		js_log("mv_embed play");
		//check if thumbnail is being displayed and embed html
		if(this.thumbnail_disp){
			//js_log('rewrite embed');
			if(!global_embed_type){
				//this.innerHTML = this.getPluginMissingHTML(); 
				$j('#'+this.id).html(this.getPluginMissingHTML());
			}else{						
				$j('#'+this.id).html(this.getEmbedHTML());
			}
			this.paused = false;
			this.thumbnail_disp=false;	
		}else{
			//the plugin is already being displayed
		}
	},
	play_or_pause : function(){	
		js_log('base play or pause');
		var id = (this.pc!=null)?this.pc.pp.id:this.id;
		
		var play_or_pause = document.getElementById('mv_play_or_pause_'+id);	
		//check if we are in a playlist: 
		
	    if(play_or_pause){
	    	//check state and set play or pause
	    	if(this.paused){
	    		//js_log('do play');
				//(paused) do play
				this.play();
				play_or_pause.innerHTML = getTransparentPng(new Object ({id:'mv_pop_btn_'+id,style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_pause_sm.png' }));
			}else{
				//js_log('do pause');
				//(playing) do pause
				this.paused=true;
				this.pause();
				play_or_pause.innerHTML = getTransparentPng(new Object ({id:'mv_pop_btn_'+id,style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_play_sm.png' }));
			}
	    }
	},
	//called when we play to the end of a stream
	streamEnd : function(){
		//if there are more clips in the sequence play next
		//if not stop the video (return to thumbnail) 
		this.stop();
	},
	/*
	 * base embed pause
	 * 	there is no general way to pause the video 
	 *  must be overwritten by embed object to support this functionality. 
	 */
	pause : function(){
		return null
	},
	
	/*
	 * base embed stop (should be overwritten by the plugin) 
	 */
	stop: function(){
		js_log('base stop');
		//check if thumbnail is being displayed in which case do nothing
		if(this.thumbnail_disp){
			//already in stooped state
			js_log('already in stopped state');
		}else{
			//rewrite the html to thumbnail disp 
			$j('#'+this.id).html(this.getThumbnailHTML());
			this.thumbnail_disp=true;
		}
	},
	/* returns bool true if playing false if paused or stooped
	 */
	isPlaying : function(){
		if(this.thumbnail_disp){
			//in stoped state
			return false;
		}else{
			return true;
		}
	},
	//loads in the css and js for the extended interface (controls = true) 
	get_interface_lib : function(doLoad){				
		//var doLoad = (doLoad==null)? true:doLoad;
		//js_log('get interface:' + doLoad);
		var loading_interface =false;
	
		//scriptaculous version: 
		/*if(typeof Prototype=='undefined'){
			if(doLoad) loadExternalJs(mv_embed_path + 'scriptaculous/lib/prototype.js');
			//js_log('Prototype und');
			loading_interface = true;
		}
		if(typeof Scriptaculous=='undefined' || typeof Control=='undefined' ){
			if(doLoad) loadExternalJs(mv_embed_path + 'scriptaculous/src/scriptaculous.js');
			//js_log('Scriptaculousmv_track und');		
			loading_interface=true;
		}*/					
		//grab the css file: 
		if(!styleSheetPresent(mv_embed_path+'mv_embed.css')){	
			if(doLoad) loadExternalCss(mv_embed_path+'mv_embed.css');
			js_log('css und');
			loading_interface=true;
		}
	
		if(loading_interface){
			//call get_interface_lib (without requests) until interface is done loading: 
			setTimeout('document.getElementById(\''+this.id+'\').get_interface_lib(false)', 50);
			//if loading interface is not yet available 
			return false;			
		}else{
			//js_log('loading_interface = false');
			//if it was a load request and it was already loaded return true
			if(doLoad){
				return true;
			}else{
				//non loading request means time has passed so we need to update the innerHTML
				$j('#'+this.id).html(this.getEmbedHTML());
			}
		}
	},
	playlistSupport:function(){
		//by default not supported (implemented in js) 
		return false;
	}, 
	postEmbedJS:function(){
		return '';
	},
	getPluginEmbed : function(){
		if (window.document[this.pid]){
	        return window.document[this.pid];
		}
		if (navigator.appName.indexOf("Microsoft Internet")==-1){
	        if (document.embeds && document.embeds[this.pid])
	        	return  document.embeds[this.pid]; 
		}else{
	    	return document.getElementById(this.pid );
		}
	},
	activateSlider : function(slider_id){		
		if(!slider_id)slider_id=this.id;
		//get a pointer to this id (as this in onSlide context is not "this") 
		/*var parent_id = this.id;	*/
		var thisVid = this;
		this.slider = new Control.Slider('playhead_'+slider_id, 'track_'+slider_id,{
			sliderValue:0,
			onSlide:function(v){
				if(! thisVid.userSlide){
					//user slide clip:
					thisVid.userSlide=true;
					js_log('user slide: ' + thisVid.userSlide);
				}										
			},
			onChange:function(v){ 
				if(thisVid.userSlide==true){						
					//seek to a given position:
					js_log('this.userSlide seek to: ' + v);	
					thisVid.doSeek(v);	
					thisVid.userSlide=false;
				}
			}
		});	
		/* non-active jQuery based slider:     
		js_log('parent id: '+ parent_id + ' id: ' + this.id);
		$j('#slider_'+this.id).slider({
				change: function(slider){
					js_log("change");
					for(i in slider){
						js_log('slider:'+i + slider[i]);
					}
				}
		});*/
	},
	setSliderValue: function(perc){
		//js_log('set value:'+ perc);
		this.slider.setValue(perc);
	},
	setStatus:function(value){
		//update status: 
		var info = document.getElementById("info_"+this.id);
		if(info)info.innerHTML=value;
	},
	wrapEmebedContainer:function(embed_code){
		//check if parent clip is set( ie we are in a playlist so name the embed container by playlistID)
		var id = (this.pc!=null)?this.pc.pp.id:this.id;
		return '<div id="mv_ebct_'+id+'" style="width:'+this.width+'px;height:'+this.height+'px;">' + 
					embed_code + 
				'</div>';
	},
	getEmbedHTML:function(){
    	var controls_html ='';
		if(this.controls){
			//all that is supported when we don't know the js hooks is "stop"
			controls_html = this.getControlsHtml('stop');
		}
        return this.wrapEmebedContainer( this.getEmbedObj() ) + controls_html;
    },    
	getControlsHtml : function(type){
		var id = (this.pc)?this.pc.pp.id:this.id;
		switch(type){
			case 'all':
				return 	this.getControlsHtml('play_head') +					
						this.getControlsHtml('play_or_pause') + 
						this.getControlsHtml('stop') + 
						this.getControlsHtml('fullscreen') + 
						this.getControlsHtml('info_span');
			break;
			case 'play_or_pause':
				return '<a id="mv_play_or_pause_'+id+'" title="play_or_pause" href="javascript:document.getElementById(\''+id+'\').play_or_pause();">'+
					getTransparentPng(new Object ({id:'mv_pop_btn_'+id,style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_pause_sm.png' })) + 
					'</a>';
			break;
			case 'play':
				return '<a title="play" href="javascript:document.getElementById(\''+id+'\').play();">'+
					getTransparentPng(new Object ({id:'mv_play_btn',style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_play_sm.png' })) + 
					'</a>';
			break;
			case 'stop':
				return	'<a title="stop" href="javascript:document.getElementById(\''+id+'\').stop();">'+
					getTransparentPng(new Object ({id:'mv_stop_btn',style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_stop_sm.png' })) + 							
					'</a>';
			break;
			case 'fullscreen':
				return '<a title="fullscreen" href="javascript:document.getElementById(\''+id+'\').fullscreen();">'+
					getTransparentPng(new Object ({id:'mv_fs_btn',style:'float:left',width:'27', height:'27', border:"0", 
						src:mv_embed_path+'images/vid_full_screen_sm.png' })) + 
				'</a>';
			break;
			case 'play_head':
				//use style for bg (to use paths
				return '<div id="track_'+id+'" class="mv_track" ' +
						'style="background: url('+mv_embed_path+'images/bd-gray.gif);' +
						'width:'+(this.width)+'px; height:4px;">'+
				'<div id="playhead_'+id+'" style="background:url(\''+mv_embed_path+'images/slider_handle.gif\');"' +
					' class="mv_playhead"></div>'+
				'</div>';
				/* jQuery based slider: 
				return '<div id="slider_'+id+'" style="position: relative; margin: 5px; width: '+(this.width-10)+'px; 
							height: 4px; background: url('+mv_embed_path+'images/bd-gray.gif) repeat scroll 5px 0px;">'+
								' <div id="playhead_'+id+'" class="ui-slider-handle" style="position: absolute; 
									 height: 21px; left: 0px; top: 10px; width: 17px; 
									 background-image: url('+mv_embed_path+'images/slider_handle.gif);"></div>' + 						
						'</div>';
				*/
			break;
			case 'info_span':
				return '<span id="info_'+id+'" class="mv_status" style="float:left">--</span>'
			break;		
		}		
	}
}
/* returns html for a transparent png (for ie<7)*/
function getTransparentPng(image){
	if(!image.style)image.style='';
	if( isIE() ){
		return '<span id="'+image.id+'" style="display:inline-block;cursor:hand;width:'+image.width+'px;height:'+image.height+'px;' +
    		'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' +
    		'(src=\''+image.src+'\', sizingMethod=\'scale\');'+image.style+'"></span>';	
	}else{		
		return '<img id="'+image.id+'" style="'+image.style+'"  width="'+image.width+'" height="'+image.height+'" border="0" src="'+
			image.src + '">';
	}
}
//returns the original name to the faded img (	//take off the new_)
function thumbnail_restore_id(obj){
	if(obj.element){
		var default_id=obj.element.id.substr(4);
		var this_id = obj.element.id.substr(14);
		//remove original 
		img_container = document.getElementById('dc_'+this_id);
		if(img_container){
			org_img = document.getElementById(default_id);
			img_container.removeChild(org_img);
			//set the new obj id to the default:
			obj.element.id=default_id;
		}
		//console.log('restore ' + obj.element.id);
	}
}

/*
* EMBED OBJECTS:
* (dynamically included)
*/

/* the most simple implementation used for unknown application/ogg plugin */
function genericEmbed(){
    this.getEmbedObj = function(){
    	return '<object type="application/ogg" '+
			      'width="'+this.width+'" height="'+this.height+'" ' +
		    	  'data="' + this.src + '"></object>';
    }
}


/*
IE specific functions:  
*/
//check if we are an IE browser
function isIE(){
    return navigator.appName.indexOf("Microsoft") != -1;
    //return !(navigator.plugins && navigator.plugins.length);
}

/*
* utility functions: 
*/
function seconds2ntp(sec){
	sec = parseInt(sec);
	hours = Math.floor(sec/ 3600);
	minutes = Math.floor((sec/60) % 60);
	seconds = sec % 60;
	//if ( hours < 10 ) hours = "0" + hours;
	if ( minutes < 10 ) minutes = "0" + minutes;
	if ( seconds < 10 ) seconds = "0" + seconds;
	return hours+":"+minutes+":"+seconds;
}
/* takes hh:mm:ss input returns number of seconds */
function ntp2seconds(ntp){
	times = ntp.split(':');
	if(times.length!=3)
		return null;
	//return seconds float (ie take seconds float value if present): 
	return parseInt(times[0]*3600)+parseInt(times[1]*60)+parseFloat(times[2]);
}
//addLoadEvent for adding functions to be run when the page DOM is done loading
function addLoadEvent(func) {
	//check if the mediaWiki addOnloadHook is present else do our own: 
	if(window.addOnloadHook){
		addOnloadHook(func);			
	}else{
		//opera does not work :(
		if(navigator.userAgent.indexOf("Opera")!=-1){			
			alert('opera is not currently supported with mv_embed' + "\n" + 
				  '( document.getElementsByTagName("video").length = zero ) ');
		}else{
		    //ie, safari, firefox whenDOMReady:
		    //whenDOMReady(func);
		    mvEmbed.addLoadEvent(func);
		}
	    /*var oldonload = window.onload;
	   */
	}
}

function loadExternalJs(url){  
   js_log('load js: '+ url);
   var e = document.createElement("script");
   e.setAttribute('src', url);
   e.setAttribute('type',"text/javascript");
   e.setAttribute('defer', true);
   document.getElementsByTagName("head")[0].appendChild(e);     
}

function styleSheetPresent(url){
    style_elements = document.getElementsByTagName('link');  
    if( style_elements.length > 0) {
        for(i = 0; i < style_elements.length; i++) {   
			if(style_elements[i].href==url)
				return true;
		}
    }
    return false;
}
function loadExternalCss(url){
   //js_log('load css: ' + url);
   var e = document.createElement("link");
   e.href = url;
   e.type = "text/css";
   e.rel = 'stylesheet';
   document.getElementsByTagName("head")[0].appendChild(e);
}
/*
 * sets the global mv_embed path based on the scripts location
 */
function getMvEmbedPath(){
	js_elements = document.getElementsByTagName("script");
	for(i=0;i<js_elements.length; i++){
		var mstr = js_elements[i].src.indexOf('mv_embed.js');
		if( mstr !=-1){
			mv_embed_path = js_elements[i].src.substr(0,mstr);
		}	
	}	
	//js_log('found mv_embed:'+ mv_embed_path +' '+ mv_embed_path.indexOf('://'));
	//absolute the url (if relative) (if we don't have mv_embed path)
	if(mv_embed_path.indexOf('://')==-1){
		//js_log('url: ' + document.URL);
		var pURL = parseUri(document.URL);		
		if(mv_embed_path.charAt(0)=='/'){
			mv_embed_path = pURL.protocol + '://' + pURL.authority + mv_embed_path;
		}else{
			//relative:
			if(mv_embed_path==''){
				mv_embed_path = pURL.protocol + '://' + pURL.authority + pURL.directory + mv_embed_path; 
			}
		}
	}else{
		js_log('already absolute');
	}
}

/*
* Returns embed type:
	native: <video> tag support
    oggplay: oggplay video plugin support
    vlc:    vlc browser plugin detected
    generic: mime type application/ogg found (generic via xine, totem or some other plugin)
    java:   java detected
    null:   no playback support system found
*/
function getEmbedType(){
	var oggplayPlugin=false;
    var genericOggPlugin=false;
    var vlcPlugin=false;
    var javaPlugin=false;
     
    //check for native support:
    if(document.getElementsByTagName("video").length > 0) {
      var myvideo = document.getElementsByTagName("video")[0];      
      if(myvideo.play) {
        return 'native';
      }
    }
    
    //first check the navigator.plugins 
	if (navigator.plugins && navigator.plugins.length > 0) {
		// for each plugin...
		for (var i=0; i < navigator.plugins.length; i++ ) {	
			//js_log(navigator.plugins[i].name);			
		}
	 }

    //check mimeTypes (for generic ogg support):
    if(navigator.mimeTypes && navigator.mimeTypes.length > 0) {               
       for (var i = 0; i < navigator.mimeTypes.length; i++) {
       		if(navigator.mimeTypes[i].type.indexOf("application/liboggplay") > -1) {
                oggplayPlugin = true;
            }
            if(navigator.mimeTypes[i].type.indexOf("application/ogg") > -1) {
                genericOggPlugin = true;
            }
            if(navigator.mimeTypes[i].type.indexOf("application/x-vlc-plugin") > -1) {
                vlcPlugin = true;
            }	
            if(navigator.mimeTypes[i].type.indexOf("application/x-java-applet") > -1) {
               javaPlugin = true;
            }
        }
        //opera sometimes thinks it has vlc when it does not
        if(navigator.userAgent.indexOf("Opera")!=-1){
        	vlcPlugin=false;        
        }
        //preference order: necessary as vlc plugin will show up as both generic and its x-name-plugin
        //(because we have no js hooks for generic we prefer java over the generic plugins such as mplayer
        // and Totem...we should add in support for others over time)
        if(oggplayPlugin)return 'oggplay';
        if(vlcPlugin)return 'vlc';     
        if(javaPlugin)return 'java';
        if(genericOggPlugin)return 'generic';
    }
    //if IE check for vlc ActiveX object: 
    if(isIE()){
		var p;
		try {
			p = new ActiveXObject('VideoLAN.VLCPlugin.2');
		}
		catch (e) {
			//alert('vlc not found');
		}
		if (p){
			return 'vlc';
		}	
	}	
    //general way to check for java in IE (others should have been found in mime type check)
    if(isIE()){
    	if(navigator.javaEnabled() == 1){
    		return 'java';
    	}
    }
	//exhausted all detection return null 
	return null;
}

/*
* utility functions:
*/
function js_log(string){
 /* if( window.console ){
        console.log(string); 
   }else{   	 
     var log_elm = document.getElementById('mv_js_log');
     if(!log_elm){
     	document.write('<textarea id="mv_js_log" cols="80" rows="6"></textarea>');
     	var log_elm = document.getElementById('mv_js_log');
     }
     if(log_elm){
     	log_elm.value+=string+"\n";
     }
   }*/
}
//report errors as alerts: 
function js_error(string){
	alert(string);
}
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects
	 for(var item in arr) {
	  var value = arr[item];
	 
	  if(typeof(value) == 'object') { //If it is an array,
	   dumped_text += level_padding + "'" + item + "' ...\n";
	   dumped_text += dump(value,level+1);
	  } else {
	   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
	  }
	 }
	} else { //Stings/Chars/Numbers etc.
	 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
} 


