//-- Uniplayer packed file consists of these files:
//-- uniplayer core
//-- uniplayer mimes
//-- module quicktime
//-- module vlc
//-- module windowsmedia
//-- module divx
//-- module realplayer
//-- module silverlight
//-- module flash
/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Uniplayer = function(options){
	// options start
	this.options = {
		src: '',							// src file on start
		mimetype: '',						// mime-type for file on start
		volume: .8,							// volume (0-1) on start
		position: 0,						// position (0-1) on start
		id: '',								// id for <object> tag, leave empty to do not add an id attribute at all
		width: 1,							// width of movie
		height: 1,							// height of movie
		autoplay: false,					// auto play movie after load
		autoload: true,					// auto load movie at start
		showControls: false,					// show or not uniplayer controls
		showNativeControls: true,			// show or not current module "native" controls
		clearHolder: false,					// clear ar not holder element before writting player there
		preview: '',						// preview image of start movie, leave empty to show 'supply players' if enabled below
		showSupply: false,					// show or not list of supported players on start
		showSupplyLogos: false,				// show it with logotypes?
		showSupplyLogosSmall: false,		// show logos small
		showSupplyLogosTransparent: false,	// show transparent logos (png images used which incorrect displayed in IE<7)
		updaterInterval: 500,				// interval of plugin status updates in milliseconds
		background: '#00000',				// background of movie
		guiPath: '/uniplayer0.3b/gui/default/',			// path to GUI folder (with trailing slash)
		language: 'en',
		hideStartLogo: false,
		autoloadModules: false,
		noCache: false
	};
	var autoloadModules = [
		'UniplayerFlashJWPlayer',
		'UniplayerSilverlight',
		'UniplayerRealPlayer',
		'UniplayerDivX',
		'UniplayerVLC',
		'UniplayerQuickTime',
		'UniplayerWindowsMedia',
		'UniplayerFlashFlowplayer'
	];
	if(this.options.autoplay && !this.options.autoload){
		this.options.autoload = true;
	}
	// options end - do not edit below
	if(typeof options == 'object'){
		for(var i in options){
			this.options[i] = options[i];
		}
	}
	// options depencies
	if(this.options.autoplay && !this.options.autoload){
		this.options.autoload = true;
	}
	if(this.options.background){
		if(navigator.userAgent.indexOf('MSIE 6')>=0 || navigator.userAgent.indexOf('MSIE 5')>=0){
			this.options.background = '#EDEDED';
			this.options.showSupplyLogosTransparent = false;
		}
		else if(!this.options.showSupplyLogosTransparent){
			this.options.showSupplyLogosTransparent = true;
		}
	}
	
	// setting up
	this.name = 'Uniplayer';
	this.version = '0.2b';
	this.modules = {};
	this.modulesList = [];
	this.supported = {};
	this.mimeTypeCache = {};
	this.holders = {};
	this.states = {
		stopped: 0,
		loading: 1,
		playing: 2,
		paused: 3,
		failed: 4
	};
	this.current = {
		src: this.options.src || '',
		mimetype: this.options.mimetype || '',
		state: this.states.stopped,
		mute: false,
		pageScreen: false,
		volume: this.options.volume || 0,
		duration: 0,
		position: this.options.position || 0,
		width: this.options.width || 1,
		height: this.options.height || 1
	};
	var previous = {};
	// autoload modules
	if(this.options.autoloadModules){
		for(var i=0; i<autoloadModules.length; i++){
			if(typeof window[autoloadModules[i]] == 'function'){
				this.addModule(new window[autoloadModules[i]]);
			}
		}
	}
	// updater
	var fireChangeEvent = function(type, value){
		var eName = 'on' + type.substr(0, 1).toUpperCase() + type.substr(1) + 'Change';
		if(typeof(this[eName]) == 'function'){
			this[eName].call(this, value);
		}
	};
	var updaterChangeTypes = ['src', 'state', 'mute', 'volume', 'duration', 'position'];
	var updaterFunction = function(){
		if(this.current.module){
			try{this.current.state = this.current.module.getState();}catch(e){}
			try{this.current.mute = this.current.module.getMute();}catch(e){}
			try{this.current.volume = this.current.module.getVolume();}catch(e){}
			try{this.current.duration = this.current.module.getDuration();}catch(e){}
			try{this.current.position = this.current.module.getPosition();}catch(e){}
			for(var i=0; i<updaterChangeTypes.length; i++){
				if(previous[updaterChangeTypes[i]] != this.current[updaterChangeTypes[i]]){
					previous[updaterChangeTypes[i]] = this.current[updaterChangeTypes[i]];
					fireChangeEvent.call(this, updaterChangeTypes[i], this.current[updaterChangeTypes[i]]);
				}
			}
		}
	};
	this.updater = setInterval((function(self){return function(){updaterFunction.call(self);};})(this), this.options.updaterInterval);
	// controls
	this.addControl('getVersion', function(){
		var module = this.current.module ? this.current.module.title : '';
		if(this.current.module && this.current.module.getVersion){
			if(version = this.current.module.getVersion()){
				module+= ' '+version;
			}
		}
 		return this.name +' '+ this.version + (module ? ' ('+ module +')' : '');
	});
	this.addControl('getState', function(){
		return this.current.state;
	});
	this.addControl('play', function(){
		if(this.current.module.play){
			return this.current.module.play();
		}
	});
	this.addControl('pause', function(){
		if(this.current.module.pause){
			return this.current.module.pause();
		}
	});
	this.addControl('stop', function(){
		if(this.current.module.stop){
			return this.current.module.stop();
		}
	});
	this.addControl('fullScreen', function(){
		if(this.current.module.fullScreen){
			return this.current.module.fullScreen();
		}
	});
	this.addControl('mute', function(){
		if(this.current.module.setMute && this.current.module.getMute){
			var turn = !this.current.module.getMute();
			this.current.module.setMute(turn);
			return turn;
		}
	});
	this.addControl('volume', function(volume){
		if(typeof(volume) != 'undefined' && this.current.module.setVolume){	
			this.current.module.setVolume(parseFloat(volume));
		}
		return this.current.module.getVolume ? this.current.module.getVolume() : this.current.volume;
	});
	this.addControl('position', function(position){
		if(typeof(position) != 'undefined' && this.current.module.setPosition){
			this.current.module.setPosition(parseFloat(position));
		}
		return this.current.module.getPosition ? this.current.module.getPosition() : this.current.position;
	});
};


UniplayerException = function(e){
	this.error = e || null;
	this.message = this.error ? this.error.message : '';
};


Uniplayer.prototype.log = function(e){
	if(typeof(this.logger) != 'undefined'){
		if(typeof(this.logger) == 'object'){
			this.logger.log('Uniplayer: '+e.message);
		}
		else if(this.logger === 'alert'){
			alert('Uniplayer Exception\n\n' + e.message);
		}
	}
};


Uniplayer.prototype.setOptions = function(options){
	if(typeof options != 'object'){
		return false;
	}
	for(var i in options){
		this.options[i] = options[i];
	}
	return true;
};


Uniplayer.prototype.getMimeType = function(src){
	var mimetype = this.mimeTypeCache[src] || '';
	if(!mimetype){
		var qp = -1;
		if(qp = src.indexOf('?') >= 0){
			src = src.substring(0, qp);
		}
		var ext = UniplayerUtils.getExtension(src);
		if(ext && this.mimes){	// get from file 'uniplayer-mimes.js' if exists
			mimetype = this.mimes[ext];
		}
		if(!mimetype){	// get from server's HTTP header
			mimetype = this.queryMimeType(src);
		}
	}
	this.mimeTypeCache[src] = mimetype;
	return mimetype;
};


Uniplayer.prototype.queryMimeType = function(src){		// works only on same domain due to security reasons
	var jarvey, result = '';
	if(jarvey = new XMLHttpRequest){
		var logindata, user, pass;
		if(logindata = src.substring(src.indexOf('//')+2, src.indexOf('@'))){	// detect user:pass@ in the src
			src = src.replace(logindata+'@', '');
			logindata = logindata.split(':');
			user = logindata[0] || '';
			pass = logindata[1] || '';
		}
		try{
			jarvey.open('HEAD', src, false, user, pass);
			jarvey.send(null);
			if(jarvey.status && jarvey.status.toString().substring(0, 1).valueOf() < 4){
				result = jarvey.getResponseHeader('Content-Type').split(';')[0].replace(/(^\s+)|(\s+$)/g, '');
			}
			else{
				throw new UniplayerException({message:'Seems file is not accessible'});
			}
		}
		catch(e){
			this.log(e);
		}
	}
	return result;
};


Uniplayer.prototype.addModule = function(module){
	try{
		if(typeof(module) != 'object' || !module.name || !(module.supported instanceof Array)){
			throw new UniplayerException({message:'Cannot add an incorrect module'});
		}
		if(this.modules[module.name]){
			throw new UniplayerException({message:'This module already registered'});
		}
	}
	catch(e){
		this.log(e);
		return;
	}
	module.player = this;	// back reference
	this.modules[module.name] = module;
	//this.modulesList.push(module.name);	// for ie5.0
	this.modulesList[this.modulesList.length] = module.name;
	for(var i=0; i<module.supported.length; i++){
		if(!this.supported[module.supported[i]]){
			this.supported[module.supported[i]] = [];
		}
		//this.supported[module.supported[i]].push(module.name);	// for ie5.0
		this.supported[module.supported[i]][this.supported[module.supported[i]].length] = module.name;
	}
	module.present = this.pluginExists(module.needle, module.progid, module.classid);
};


Uniplayer.prototype.addModules = function(modules){
	if(!(modules instanceof Array)) return;
	for(var i=0; i<modules.length; i++){
		this.addModule(modules[i]);
	}
};


Uniplayer.prototype.getModule = function(src, mimetype){
	var modulesList = [], moduleName = '';
	try{
		if(!this.modulesList.length){
			throw new UniplayerException({message:'No modules found'});
		}
	}
	catch(e){
		this.log(e);
		return moduleName;
	}
	if(!mimetype){
		mimetype = this.getMimeType(src);
	}
	if(mimetype && this.supported[mimetype]){
		modulesList = this.supported[mimetype];
	}
	//else{
	//	modulesList = this.modulesList;
	//}
	for(var i=0; i<modulesList.length; i++){
		if(this.modules[modulesList[i]].present){
			moduleName = modulesList[i];	// present module found
			break;
		}
	}
	//if(!moduleName){
	//	moduleName = modulesList[0];	// if no present modules found, use first supported module
	//}
	return moduleName;
};


Uniplayer.prototype.installModule = function(moduleName){
	if(this.modules[moduleName].pluginspage){
		if(confirm(this.modules[moduleName].title+' plug-in is needed to play this movie\nDo you wish to open page "'+this.modules[moduleName].pluginspage+'" to manual install '+this.modules[moduleName].title+' plug-in?')){
			// perform manual install
			window.open(this.modules[moduleName].pluginspage);
			return false;
		}
	}
	if(navigator.userAgent.indexOf('MSIE')>=0 && !this.modules[moduleName].codebase){
		return false;
	}
	return true;
};


Uniplayer.prototype.pluginExists = function(needle, progid, classid){
	var np, result = false;
	if(typeof(ActiveXObject) == 'function'){
		try{
			var axo = new ActiveXObject(progid);
			result = axo ? true : false;
			delete axo;
		}
		catch(e){}
	}
	else if(np=navigator.plugins){
		var re=new RegExp((needle instanceof Array)?needle.join('.*'):needle, 'i');
		for(var i=0; i<np.length; i++){
			if(re.test(np[i].name) || re.test(np[i].description)){
				result = true;
				break;
			}
		}
	}
	return result;
};


Uniplayer.prototype.write = function(holder, GUI){
	try{
		if(typeof holder == 'string'){
			holder = document.getElementById(holder);
		}
		else if(!holder){
			holder = document.body;
		}
		if(!holder){
			throw new UniplayerException({message:'Cannot write player'});
		}
		if(!GUI && typeof(UniplayerGUIDefault) == 'function'){
			GUI = new UniplayerGUIDefault(this);
		}
		if(!GUI || !GUI.getHTML){
			throw new UniplayerException({message:'No GUI available'});
		}
		if(this.options.clearHolder){
			holder.innerHTML = '';
		}
		this.GUI = GUI;
		holder.innerHTML+= GUI.getHTML();
		this.holders.main = UniplayerUtils.getElementsByClassName('upGUI', 'div', holder)[0];
		this.holders.wrapper = UniplayerUtils.getElementsByClassName('upGUIWrapper', 'div', holder)[0];
		this.holders.movie = UniplayerUtils.getElementsByClassName('upGUIMovie', 'div', holder)[0];
		this.holders.controls = UniplayerUtils.getElementsByClassName('upGUIControls', 'div', holder)[0];
		if(!this.holders.main || !this.holders.wrapper || !this.holders.movie || !this.holders.controls){
			throw new UniplayerException({message:'Cannot write broken GUI'});
		}
	}
	catch(e){
		this.log(e);
		return;
	}
	var self = this;
	// background
	this.holders.movie.style.backgroundColor = this.options.background;
	// autoload / preview / showSupply
	if(this.options.autoload && this.current.src){
		this.load(this.current.src, this.current.mimetype);
	}
	else if(this.options.preview && GUI.getPreview){
		this.holders.movie.innerHTML = GUI.getPreview(this.options.preview);
	}
	else if(this.options.showSupply && GUI.getSupply){
		this.holders.movie.innerHTML = GUI.getSupply();
	}
	else if(!this.options.hideStartLogo){
		this.holders.movie.innerHTML = GUI.getPreview();
	}
	// sizing
	this.holders.main.style.width = this.options.width +  (this.holders.controls.style.width ? parseInt(this.holders.controls.style.width) : 0) + 'px';
	this.holders.main.style.height = this.options.height + (this.options.showControls ? (this.holders.controls.offsetHeight + 2) : 0) + 'px';		// 2 for border
	if(this.options.showControls){
		// buttons
		// focus/hover emulation
		var buttons = UniplayerUtils.getElementsByClassName('upGUIButton', 'a', holder);
		var buttonFocus = function(){
			this.className += ' hover';
		};
		var buttonBlur = function(){
			this.className = this.className.replace(' hover', '');
		};
		for(var i=0; i<buttons.length; i++){
			buttons[i].onfocus = buttonFocus;
			buttons[i].onblur = buttonBlur;
		}
		var buttonMenu = UniplayerUtils.getElementsByClassName('upGUIButtonMenu', 'a', holder)[0];
		var buttonPrev = UniplayerUtils.getElementsByClassName('upGUIButtonPrev', 'a', holder)[0];
			if(buttonPrev){buttonPrev.className+= ' disabled';}
		var buttonPlay = UniplayerUtils.getElementsByClassName('upGUIButtonPlay', 'a', holder)[0];
			if(buttonPlay){buttonPlay.onclick = this.play;}
		var buttonPause = UniplayerUtils.getElementsByClassName('upGUIButtonPause', 'a', holder)[0];
			if(buttonPause){buttonPause.onclick = this.pause;}
		
		if(buttonMenu || buttonPause){
  		this.onStateChange = function(state){
  			switch(state){
  				case self.states.playing:
  					if(buttonMenu){buttonMenu.className = buttonMenu.className.replace(' disabled', '');}
  					if(buttonPause){buttonPause.style.visibility = 'visible';}
  				break;
  				case self.states.loading:
  					if(buttonMenu){buttonMenu.className+= ' disabled';}
  				break;
  				default:
  					if(buttonMenu){buttonMenu.className = buttonMenu.className.replace(' disabled', '');}
  					if(buttonPause && buttonPause.style.visibility == 'visible'){buttonPause.style.visibility = 'hidden';}
  				break;
  			}
  		};
		}
			
		var buttonStop = UniplayerUtils.getElementsByClassName('upGUIButtonStop', 'a', holder)[0];
			if(buttonStop){buttonStop.onclick = this.stop;}
		var buttonNext = UniplayerUtils.getElementsByClassName('upGUIButtonNext', 'a', holder)[0];
			if(buttonNext){buttonNext.className+= ' disabled';}
		var buttonFullScreen = UniplayerUtils.getElementsByClassName('upGUIButtonFullScreen', 'a', holder)[0];
			if(buttonFullScreen){buttonFullScreen.onclick = this.fullScreen;}
		// volume
		var volumeSet = UniplayerUtils.getElementsByClassName('upGUIVolume', 'div', holder)[0];
		if(volumeSet){
			var buttonMute = UniplayerUtils.getElementsByClassName('upGUIButtonMute', 'a', volumeSet)[0];
				if(buttonMute){
					buttonMute.onclick = this.mute;
					this.onMuteChange = function(mute){
						if(mute){
							buttonMute.className+= ' disabled';
						}
						else{
							buttonMute.className = buttonMute.className.replace(' disabled', '');
						}
					};
				}
			var volumeSlider = UniplayerUtils.getElementsByClassName('upGUISlider', 'div', volumeSet)[0];
			var volumePointer = UniplayerUtils.getElementsByClassName('upGUIPointer', 'a', volumeSet)[0];
			if(volumeSlider && volumePointer){
				this.volumeSlider = new UniplayerSlider(volumePointer, volumeSlider);
				this.volumeSlider.set(this.options.volume);
				this.volumeSlider.onChange = function(volume){
					self.volume(volume);
				};
				this.onVolumeChange = function(volume){
					self.volumeSlider.set(volume);
				};
			}
		}
		// time
		var timeMonitor = UniplayerUtils.getElementsByClassName('upGUITime', 'div', holder)[0];
		if(timeMonitor){
			timeMonitor.onselectstart = function(){return false;};
			timeMonitor.ondragstart = function(){return false;};
			timeMonitor.onclick = function(){
				if(self.current.state == self.states.paused){
					GUI.timeReverse = !GUI.timeReverse;
					GUI.setTime(timeMonitor, self.current.position*self.current.duration, self.current.duration);
				}
				else if(self.current.state == self.states.playing){
					GUI.timeReverse = !GUI.timeReverse;
				}
			};
			this.onDurationChange = function(duration){
				GUI.setTime(timeMonitor, duration, duration, true);
			};
		}
		// position
		var positionSet = UniplayerUtils.getElementsByClassName('upGUIPosition', 'div', holder)[0];
		if(positionSet){
			var positionSlider = UniplayerUtils.getElementsByClassName('upGUISlider', 'div', positionSet)[0];
			var positionPointer = UniplayerUtils.getElementsByClassName('upGUIPointer', 'a', positionSet)[0];
			if(positionSlider && positionPointer){
				this.positionSlider = new UniplayerSlider(positionPointer, positionSlider);
				this.positionSlider.onChange = function(position){
					self.position(position);
				};
				this.onPositionChange = function(position){
					self.positionSlider.set(position);
					if(timeMonitor){
						var stopped = (!position && self.current.state == self.states.stopped);
						GUI.setTime(timeMonitor, (stopped ? self.current.duration : position*self.current.duration), self.current.duration, stopped);
					}
				};
			}
		}
		// title
		var titleMonitor = UniplayerUtils.getElementsByClassName('upGUITitle', 'nobr', holder)[0];
		if(titleMonitor){
			GUI.titleMonitor = titleMonitor;
			this.onSrcChange = function(src){
				GUI.setTitle(null, src);
				if(buttonFullScreen){
					if(self.current.module && (typeof self.current.module.fullScreen != 'function')){
						buttonFullScreen.className += ' disabled';
					}
					else{
						buttonFullScreen.className = buttonFullScreen.className.replace(' disabled', '');
					}
				}
			};
		}
		// menu
		var menu = UniplayerUtils.getElementsByClassName('upGUIMenu', 'div', holder)[0];
		if(menu && buttonMenu){
			buttonMenu.onclick = function(){
				(menu.style.display = (menu.style.display == 'block' ? 'none' : 'block')) == 'block'
				? (this.className += ' active')
				: (this.className = this.className.replace(' active',''))
			};
		}
		// version
		var version = UniplayerUtils.getElementsByClassName('upGUIVersion', 'span', holder)[0];
		if(version){
			version.innerHTML = this.version;
		}
	}
};


Uniplayer.prototype.load = function(src, mimetype, moduleName){
	try{
		if(!src){
			src = this.current.src;
		}
		if(!src){
			throw new UniplayerException({message:'No file to play'});
		}
		if(!moduleName){
			moduleName = this.getModule(src, mimetype);
		}
		if(!moduleName){
			var ext = UniplayerUtils.getExtension(src);
			var message = '';
			if(ext){
				message = 'Unknown file format "'+ext+'"'
			}
			else{
				message = 'Cannot play this URL: ' + decodeURIComponent(src);
			}
			this.GUI.setTitle(message, src);
			throw new UniplayerException({message:message});
		}
		if(!this.modules[moduleName].present){
			if(!this.installModule(moduleName)){
				throw new UniplayerException({message:'Module '+moduleName+' is not present'});
			}
		}
	}
	catch(e){
		this.log(e);
		return;
	}
	this.current.src = src;
	if(this.current.module != this.modules[moduleName]){
		if(this.current.module){
			this.current.module.stop();
		}
		this.current.module = this.modules[moduleName];
		try{
			this.current.movie = this.current.module.build();
			this.holders.main.style.height = this.current.height + this.holders.controls.offsetHeight + 2 + 'px';		// 2 for border
			// check modules override
			if(this.current.module.test && !this.current.module.test()){
				for(var i in this.modules){
					if(i == moduleName){continue;}
					if(this.modules[i].test){
						if(this.modules[i].test()){
							this.current.module = this.modules[i];
							break;
						}
					}
				}
			}
		}
		catch(e){
			this.log(e);
		}
	}
	else{
		try{
			this.current.module.reload();
			if(this.options.autoplay){
				this.current.module.play();
			}
		}
		catch(e){
			this.log(e);
		}
	}
};


Uniplayer.prototype.addControl = function(name, fn){
	if(!name || typeof(fn) != 'function'){
		return false;
	}
	var self = this;
	this[name] = function(){
		var args = arguments;
		try{
			if(name == 'play' && !self.current.module && self.current.src && !self.options.autoload && !self.options.autoplay){
				self.options.autoplay = true;
				self.load(self.current.src, self.current.mimetype);
				self.options.autoplay = false;
				return true;
			}
			else if(typeof self.current.movie == 'undefined'){
				return false;
				//throw new UniplayerException({message:'No movie to control ' + name});
			}
			return fn.apply(self, args);
		}
		catch(e){
			self.log(e);
		}
	};
};


Uniplayer.prototype.pageScreen = function(resize){
	if(!this.current.movie){return;}
	if(!this.current.pageScreen){
		// get wrapper position
		var sx = (typeof pageXOffset != 'undefined') ? pageXOffset : document.body.scrollLeft;
		var sy = (typeof pageYOffset != 'undefined') ? pageYOffset : document.body.scrollTop;
		var ax = UniplayerUtils.getAbsLeft(this.holders.wrapper);
		var ay = UniplayerUtils.getAbsTop(this.holders.wrapper);
		// set wrapper position
		with(this.holders.wrapper.style){
			top = sy - ay + 'px';
			left = sx - ax + 'px';
		}
		// connect window resize
		if(typeof window.onresize == 'function'){window._onresize = window.onresize;}
		var self = this;
		window.onresize = function(){
			if(self.current.pageScreen){
				self.pageScreen.call(self, true);
			}
			if(typeof window._onresize == 'function'){window._onresize.call();}
		}
		// connect 'esc' button
		if(typeof document.onkeydown == 'function'){document._onkeydown = document.onkeydown;}
		document.onkeydown = function(e){
			var keynum, out;
			if(window.event){
				keynum = window.event.keyCode;
			}
			else if(e.which){
				keynum = e.which;
			}
			if(keynum == 27 && self.current.pageScreen){
				self.pageScreen.call(self);
				out = false;
			}
			else{
				out = true;
			}
			if(typeof document._onkeydown == 'function'){document._onkeydown.call();}
			return out;
		}
		this.current.pageScreen = true;
		resize = true;
	}
	if(resize){
		// set movie size
		var cw = (document.documentElement.clientWidth ? document.documentElement.clientWidth : (window.innerWidth ? window.innerWidth : document.body.offsetWidth));
		var ch = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight));
		if(typeof ActiveXObject != 'undefined'){
			cw-= 20;
			ch-= 4;
		}
		this.current.movie.width = cw;
		this.current.movie.height = ch - this.holders.controls.offsetHeight;
		this.holders.wrapper.style.width = this.current.movie.width + 'px';
	}
	else{
		// revert movie size and wrapper position
		this.current.movie.width = this.current.width;
		this.current.movie.height = this.current.height;
		this.holders.wrapper.style.width = this.current.movie.width + 'px';
		with(this.holders.wrapper.style){
			top = 'auto';
			left = 'auto';
		}
		// revert events
		document.onkeydown = (typeof document._onkeydown == 'function') ? document._onkeydown : null;
		window.onresize = (typeof window._onresize == 'function') ? window._onresize : null;
		this.current.pageScreen = false;
	}
	return this.current.pageScreen;
};


Uniplayer.prototype.UniplayerObject = function(options){
	var obj, ax = typeof(ActiveXObject) == 'function';
	if(ax){
		// object
		obj = '<object';
		if(options.id){
			obj+= ' id="'+options.id+'"';
		}
		obj+= ' width="'+options.width+'"';
		obj+= ' height="'+options.height+'"';
		obj+= ' classid="'+options.classid+'"';
		if(options.codebase){
			obj+= ' codebase="'+options.codebase+'"';
		}
		obj+= '>';
		obj+= '</object>';
	}
	else{
		// embed
		obj = document.createElement('embed');
		if(options.id){
			obj.setAttribute('id', options.id);
		}
		obj.setAttribute('src', options.src);
		obj.setAttribute('width', options.width);
		obj.setAttribute('height', options.height);
		obj.setAttribute('type', options.type);
		if(options.pluginspage){
			obj.setAttribute('pluginspage', options.pluginspage);
		}
	}
	
	this.addParam = function(name, value, axOnly){
		if(!name) return;
		if(typeof value == 'boolean'){
			value = value ? 'true' : 'false';
		}
		if(ax){
			obj = obj.replace('</object>', '<param name="'+name+'" value="'+value+'"/></object>');
		}
		else if(!axOnly){
			obj.setAttribute(name, value);
		}
	};
	
	this.write = function(to, append){
		if(!to || !to.tagName) return;
		if(!append){
			to.innerHTML = '';
		}
		if(ax){
			to.innerHTML+= obj;
		}
		else{
			to.appendChild(obj);
		}
		return to.lastChild;
	};
};


UniplayerUtils = {
	getExtension: function(src){
		src = decodeURIComponent(src).substring(src.lastIndexOf('/')+1);
		return src.substring(src.lastIndexOf('.')+1).toLowerCase();
	},
	timeToString: function(time, negative, loading){
		if(!time){return loading ? 'loading ' : '0:00';}
		var addZero = function(number){
			return (number < 10 ? ('0' + number) : number.toString());
		};
		time = parseInt(time);
		if(time < 60){
			return (negative ? '-' : '') + '0:' + addZero(time);
		}
		else{
			var seconds = 0, minutes = 0, hours = 0;
			seconds = time % 60;
			minutes = (time - seconds) / 60;
			if(minutes > 60){
				hours = minutes % 60;
			}
			return (negative ? '-' : '') + (hours ? (hours + ':') : '') + addZero(minutes) +':'+ addZero(seconds);
		}
	},
	getAbsLeft: function(obj, limiter){
		if(!limiter){limiter = document.body;}
		var element = obj;
		var offset = 0;
		while(element){
			if(element == limiter){break;}
			offset += element.offsetLeft;
			element = element.offsetParent;
		}
		return offset;
	},
	getAbsTop: function(obj, limiter){
		if(!limiter){limiter = document.body;}
		var element = obj;
		var offset = 0;
		while(element){
			if(element == limiter){break;}
			offset += element.offsetTop;
			element = element.offsetParent;
		}
		return offset;
	},
	getMousePosition: function(e){
		var x=0, y=0;
		if(!e || (typeof(e.pageX) != 'number' && typeof(e.clientX) != 'number')){return {x: x, y: y};}
		if(typeof(e.pageX) == 'number'){
			var x = e.pageX;
			var y = e.pageY;
		}
		else{
			var x = e.clientX;
			var y = e.clientY;
			if(!(
				(window.navigator.userAgent.indexOf('Opera') + 1)
				|| (window.ScriptEngine && ScriptEngine().indexOf('InScript') + 1)
				|| window.navigator.vendor == 'KDE'
			)){
				if(document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)){
					x += document.documentElement.scrollLeft;
					y += document.documentElement.scrollTop;
				}
				else if(document.body && (document.body.scrollTop || document.body.scrollLeft)){
					x += document.body.scrollLeft;
					y += document.body.scrollTop;
				}
			}
		}
		return {x: x, y: y};
	},
	/*
	Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
	*/
	getElementsByClassName: function (className, tag, elm){
		if (document.getElementsByClassName) {
			getElementsByClassName = function (className, tag, elm) {
				elm = elm || document;
				var elements = elm.getElementsByClassName(className),
					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
					returnElements = [],
					current;
				for(var i=0, il=elements.length; i<il; i+=1){
					current = elements[i];
					if(!nodeName || nodeName.test(current.nodeName)) {
						returnElements.push(current);
					}
				}
				return returnElements;
			};
		}
		else if (document.evaluate) {
			getElementsByClassName = function (className, tag, elm) {
				tag = tag || "*";
				elm = elm || document;
				var classes = className.split(" "),
					classesToCheck = "",
					xhtmlNamespace = "http://www.w3.org/1999/xhtml",
					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
					returnElements = [],
					elements,
					node;
				for(var j=0, jl=classes.length; j<jl; j+=1){
					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
				}
				try	{
					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
				}
				catch (e) {
					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
				}
				while ((node = elements.iterateNext())) {
					returnElements.push(node);
				}
				return returnElements;
			};
		}
		else {
			getElementsByClassName = function (className, tag, elm) {
				tag = tag || "*";
				elm = elm || document;
				var classes = className.split(" "),
					classesToCheck = [],
					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
					current,
					returnElements = [],
					match;
				for(var k=0, kl=classes.length; k<kl; k+=1){
					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
				}
				for(var l=0, ll=elements.length; l<ll; l+=1){
					current = elements[l];
					match = false;
					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
						match = classesToCheck[m].test(current.className);
						if (!match) {
							break;
						}
					}
					if (match) {
						returnElements.push(current);
					}
				}
				return returnElements;
			};
		}
		return getElementsByClassName(className, tag, elm);
	},
	loadCSS: function(src){
		if(!src){return false;}
		var holder = document.getElementsByTagName('head')[0];
		if(!holder){
			holder = document.createElement('head');
			document.body.parentNode.insertBefore(holder, document.body);
		}
		var link = document.createElement('link');
		link.rel = 'stylesheet';
		link.href = src;
		holder.appendChild(link);
		return true;
	},
	animate: function(obj, prop, start, stop, step, interval, callback){
		if(!obj || !prop || typeof(start) != 'number' || typeof(stop) != 'number' || start == stop){return;}
		if(!step){step = 1;}
		if(!interval){interval = 20;}
		var timer;
		var handler = (function(pos){
			var freeze = false;
			return function(){
				if(pos > stop){
					pos-= step;
					if(pos <= stop){
						pos = stop;
						freeze = true;
					}
				}
				else if(pos < stop){
					pos+= step;
					if(pos >= stop){
						pos = stop;
						freeze = true;
					}
				}
				else{
					freeze = true;
				}
				if(freeze){
					clearInterval(timer);
					if(typeof callback == 'function'){
						callback.call(obj);
					}
				}
				obj.style[prop] = pos + 'px';
			};
		})(start);
		return timer = setInterval(handler, interval);
	}
};


UniplayerSlider = function(pointer, holder){
	if(!pointer || (typeof(pointer.tagName) == 'undefined' && !(pointer=document.getElementById(pointer)))){return;}
	if(!holder || (typeof(holder.tagName) == 'undefined' && !(holder=document.getElementById(holder)))){holder = document.body;}
	var self = this;
	this.pointer = pointer;
	this.holder = holder;
	this.vertical = false;
	this.seekInterval = .05; // float percent
	this.pointer.ondragstart = function(){return false;};
	this.pointer.onselectstart = function(){return false;};
	this.set = function(percent, change){
		if(percent < 0){percent = 0;}
		else if(percent > 1){percent = 1;}
		self.pointer.style[self.vertical ? 'top' : 'left'] = Math.floor(percent*100) + '%';
		if(change && typeof(self.onChange) == 'function'){
			self.onChange.call(self, percent);
		}
	};
	// events
	var drag = function(e){
		if(!e && !(e = window.event)){return true;}
		if(document.onmousemove == moving){return false;} // multiclick protection
		self.mouse = UniplayerUtils.getMousePosition(e);
		self.offset = self.vertical ? UniplayerUtils.getAbsTop(self.pointer, self.holder) : UniplayerUtils.getAbsLeft(self.pointer, self.holder);
		self.limit = self.vertical ? self.holder.offsetHeight : self.holder.offsetWidth;
		self._onmousemove = document.onmousemove;
		self._onmouseup = document.onmouseup;
		document.onmousemove = moving;
		document.onmouseup = drop;
		self.holder.style.cursor = 'pointer';
		return false;
	};
	var drop = function(e){
		document.onmousemove = self._onmousemove;
		document.onmouseup = self._onmouseup;
		self.holder.style.cursor = 'default';
		return false;
	};
	var moving = function(e){
		if(!e && !(e = window.event)){return true;}
		var mouse = UniplayerUtils.getMousePosition(e);
		var delta = self.vertical ? (mouse.y - self.mouse.y) : (mouse.x - self.mouse.x);
		var offset = self.offset + delta;
		self.set(offset/self.limit, true);
	};
	var point = function(e){
		if(!e && !(e = window.event)){return true;}
		var mouse = UniplayerUtils.getMousePosition(e);
		var offset = self.vertical ? UniplayerUtils.getAbsTop(self.holder) : UniplayerUtils.getAbsLeft(self.holder);
		var delta = (self.vertical ? mouse.y : mouse.x) - offset - Math.round(self.pointer.offsetWidth/2);
		var limit = self.vertical ? self.holder.offsetHeight : self.holder.offsetWidth;
		if(delta >= 0 || delta <= limit){
			self.set(delta/limit, true);
		}
	};
	var seek = function(e){
		if(!e && !(e = window.event)){return true;}
		var dir;
		if(e.keyCode == 37){
			dir = 'left';
		}
		else if(e.keyCode == 39){
			dir = 'right';
		}
		else{return true;}
		var offset = self.vertical ? self.pointer.offsetTop : self.pointer.offsetLeft;
		var limit = self.vertical ? self.holder.offsetHeight : self.holder.offsetWidth;
		var delta = Math.round(dir == 'right' ? (offset + limit*self.seekInterval) : (offset - limit*self.seekInterval));
		if(delta < 0){
			delta = 0;
		}
		else if(delta > limit){
			delta = limit;
		}
		self.set(delta/limit, true);
	};
	this.holder.onclick = point;
	this.pointer.onmousedown = drag;
	if(navigator.userAgent.indexOf('Firefox') >= 0 && navigator.userAgent.indexOf('Mac') >= 0){
		this.pointer.onkeypress = seek;		// workaround to support repeating in FF on Mac
	}
	else{
		this.pointer.onkeydown = seek;
	}
};


UniplayerLanguages = {
	'en': {
		controlsPrevious: 'Previous',
		controlsPlay: 'Play',
		controlsPause: 'Pause',
		controlsStop: 'Stop',
		controlsNext: 'Next',
		controlsMute: 'Mute',
		controlsVolume: 'Volume',
		controlsTime: 'Time',
		controlsPosition: 'Position',
		controlsFullScreen: 'FullScreen',
		controlsPlaylist: 'Playlist',
		controlsMenu: 'Menu',
		about: 'About'
	},
	'ru': {
		controlsPrevious: '??????????',
		controlsPlay: '???????????????',
		controlsPause: '?????',
		controlsStop: '????',
		controlsNext: '?????????',
		controlsMute: '????????? ????',
		controlsVolume: '?????????',
		controlsTime: '?????',
		controlsPosition: '???????',
		controlsFullScreen: '?? ???? ?????',
		controlsPlaylist: '??????',
		controlsMenu: '????',
		about: '?'
	}
};


UniplayerGUIDefault = function(player){
	var lang = UniplayerLanguages[player.options.language];
	var HTMLControls = '<div class="upGUITitleHolder"><nobr class="upGUITitle"></nobr></div><div class="upGUIButtonSet"><a href="javascript:" class="upGUIButton upGUIButtonPrev" title="'+lang.controlsPrevious+'"></a><a href="javascript:" class="upGUIButton upGUIButtonPlay" title="'+lang.controlsPlay+'"></a><a href="javascript:" class="upGUIButton upGUIButtonPause" title="'+lang.controlsPause+'"></a><a href="javascript:" class="upGUIButton upGUIButtonStop" title="'+lang.controlsStop+'"></a><a href="javascript:" class="upGUIButton upGUIButtonNext" title="'+lang.controlsNext+'"></a></div><div class="upGUIVolume"><a href="javascript:" class="upGUIButton upGUIButtonMute" title="'+lang.controlsMute+'"></a><div class="upGUISlider" title="'+lang.controlsVolume+'"><div class="upGUISliderTail"></div><a href="javascript:" class="upGUIButton upGUIPointer"></a></div></div><div class="upGUIPosition"><div class="upGUITime" title="'+lang.controlsTime+'"></div><div class="upGUISlider" title="'+lang.controlsPosition+'"><div class="upGUISliderTail"></div><a href="javascript:" class="upGUIButton upGUIPointer"></a></div></div><a href="javascript:" class="upGUIButton upGUIButtonFullScreen" title="'+lang.controlsFullScreen+'"></a><a href="javascript:" class="upGUIButton upGUIButtonPlaylist" title="'+lang.controlsPlaylist+'"></a><div class="upGUIMenu"><a class="upGUIMenuAbout" href="http://uniplayer.overdesign.net/">'+lang.about+' Uniplayer <span class="upGUIVersion"></span></a></div><a href="javascript:" class="upGUIButton upGUIButtonMenu" title="'+lang.controlsMenu+'"></a>';
	this.getHTML = function(){
		if(player.options.showControls && player.options.width < 210){
			player.options.width = 210;
		}
		if(player.options.showControls || player.options.showSupply){
			UniplayerUtils.loadCSS(player.options.guiPath + 'uniplayer.css');
		}
		return '<div class="upGUI"><div class="upGUIWrapper"><div class="upGUIMovie"></div><div class="upGUIControls" style="height: 46px; display: '+(player.options.showControls ? 'block' : 'none')+'">'+(player.options.showControls ? HTMLControls : '')+'</div></div></div>';
	};
	this.getPreview = function(src){
		return '<div style="background:#EDEDED url('+(src||'http://uniplayer.overdesign.net/gui/default/img/logo_grey.gif')+') no-repeat center center;height:'+(player.options.height+'px')+'"></div>';
	};
	this.getSupply = function(){
		var src, out = '', amount = 0;
		for(var i=0; i<player.modulesList.length; i++){
			if(!player.modules[player.modulesList[i]].present){
				continue;
			}
			amount++;
			if(player.options.showSupplyLogos){
				src = player.options.guiPath + 'unilogos/' + (player.options.showSupplyLogosSmall ? 'small/' : '') + player.modules[player.modulesList[i]].name + (player.options.showSupplyLogosTransparent ? '.png' : '.gif');
				out+= '<li class="upGUISupplyLogo"><img src="'+src+'" alt="'+player.modules[player.modulesList[i]].title+'" title="'+player.modules[player.modulesList[i]].title+'"/></li>';
			}
			else{
				out+= '<li>'+player.modules[player.modulesList[i]].title+'</li>';
			}
		}
		out+= '</ul>';
		out = '<ul class="upGUISupply" style="height:'+(player.options.height+'px')+'"><li class="upGUISupplyTitle'+(player.options.showSupplyLogosTransparent?' transparent':'')+'">with '+amount+' plugin'+(amount>1?'s':'')+' for your system</li>' + out;
		return out;
	};
	this.timeReverse = false;
	this.setTime = function(timeMonitor, position, duration, ignoreTimeReverse){
		if(!timeMonitor){return;}
		var timeReverse = this.timeReverse && !ignoreTimeReverse;
		if(duration && timeReverse){
			position = duration - position;
		}
		timeMonitor.innerHTML = UniplayerUtils.timeToString(position, timeReverse);
	};
	this.setTitle = function(title, src){
		if(!this.titleMonitor){return;}
		var titleMonitor = this.titleMonitor;
		titleMonitor.title = src ? decodeURIComponent(src) : '';
		if(typeof title != 'string'){
			if(src){
				src = decodeURIComponent(src);
				var qp, sh, dt;
				if((qp = src.indexOf('?')) >= 0){
					src = src.substring(0, qp);
				}
				if((sh = src.lastIndexOf('/')) >= 0){
					src = src.substring(sh + 1);
				}
				if((dt = src.lastIndexOf('.')) >= 0){
					src = src.substring(0, dt);
				}
				title = src.replace(/[\_\+\.\s+]/g, ' ');
			}
			else{
				title = 'No file loaded';
			}
		}
		titleMonitor.style.left = 0;
		titleMonitor.innerHTML = title;
		var titleDiff = titleMonitor.offsetWidth - titleMonitor.offsetParent.offsetWidth;
		if(titleDiff > 0){
			var titleMoving = false;
			var titleMoved = false;
			var titleAnimation;
			var move = function(){
				if(!titleMoving){
					titleMoving = true;
					var start = this.offsetLeft;
					var stop = titleMoved ? 0 : -titleDiff;
					titleAnimation = UniplayerUtils.animate(titleMonitor, 'left', start, stop, 2, 30, function(){titleMoved = !titleMoved; titleMoving = false;});
				}
				return true;
			};
			var pause = function(){
				if(titleMoving){
					clearInterval(titleAnimation);
					titleMoving = false;
				}
				return true;
			};
			var stop = function(){
				pause();
				titleMoved = false;
				titleMonitor.style.left = 0;
				return true;
			};
			titleMonitor.onmouseover = move;
			titleMonitor.onmouseout = pause;
			titleMonitor.onclick = stop;
		}
		else{
			titleMonitor.onmouseover = null;
			titleMonitor.onmouseout = null;
			titleMonitor.onclick = null;
		}
	};
};

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Uniplayer.prototype.mimes = (function(){
	var a = 'audio/';
	var v = 'video/';
	return {
		//-- audio
		'flac':a+'flac',
		'mp3':a+'mpeg',
		'm4a':a+'aac',
		'm4b':a+'aac',
		'm4p':a+'aac',
		'm4r':a+'aac',
		'aac':a+'aac',
		'adts':a+'aac',
		'wav':a+'wav',
		'bwf':a+'wav',
		'aiff':a+'aiff',
		'aif':a+'aiff',
		'aifc':a+'aiff',
		'cdda':a+'aiff',
		'au':a+'basic',
		'snd':a+'basic',
		'ulw':a+'basic',
		'mid':a+'midi',
		'midi':a+'midi',
		'smf':a+'midi',
		'kar':a+'midi',
		'qcp':a+'vnd.qcelp',
		'gsm':a+'x-gsm',
		'amr':a+'amr',
		'caf':a+'x-caf',
		'ac3':a+'ac3',
		'm2a':a+'mpeg',
		'swa':a+'mpeg',
		'wma':a+'x-ms-wma',
		'wax':a+'x-ms-wax',
		'mpga':a+'mpeg',
		'mpega':a+'mpeg',
		'3gpp2':a+'3gpp2',
		//-- video
		'3gp':v+'3gpp',
		'3gpp':v+'3gpp',
		'3g2':v+'3gpp2',
		'3gp2':v+'3gpp2',
		'h261':v+'h261',
		'h263':v+'h263',
		'h264':v+'h264',
		'jpgv':v+'jpeg',
		'jpm':v+'jpm',
		'jpgm':v+'jpm',
		'mj2':v+'mj2',
		'mjp2':v+'mj2',
		'mp4':v+'mp4',
		'mp4v':v+'mp4',
		'mpg4':v+'mp4',
		'm4u':v+'x-mpegurl',
		'mp2':v+'mpeg',
		'mpm':v+'mpeg',
		'mpa':v+'mpeg',
		'mpeg':v+'mpeg',
		'mpg':v+'mpeg',
		'mpe':v+'mpeg',
		'mpv':v+'mpeg',
		'mp2v':v+'mpeg-2',
		'mpv2':v+'mpeg-2',
		'm1s':v+'mpeg',
		'm1a':v+'mpeg',
		'm75':v+'mpeg',
		'm15':v+'mpeg',
		'm1v':v+'mpeg',
		'm2v':v+'mpeg',
		'qt':v+'quicktime',
		'mov':v+'quicktime',
		'mqv':v+'quicktime',
		'fvt':v+'vnd.fvt',
		'mxu':v+'vnd.mpegurl',
		'm4u':v+'vnd.mpegurl',
		'viv':v+'vnd.vivo',
		'vivo':v+'vnd.vivo',
		'fli':v+'fli',
		'flc':v+'flc',
		'cel':v+'flc',
		'asr':v+'x-ms-asf',
		'asf':v+'x-ms-asf',
		'asx':v+'x-ms-asx',
		'lsf':v+'x-la-asf',
		'lsx':v+'x-la-asf',
		'wm':v+'x-ms-wm',
		'wmp':v+'x-ms-wmp',
		'wmv':v+'x-ms-wmv',
		'wmx':v+'x-ms-wmx',
		'wvx':v+'x-ms-wvx',
		'avi':v+'x-msvideo',
		'avs':v+'avs-video',
		'mv':v+'x-sgi-movie',
		'movie':v+'x-sgi-movie',
		'ice':'x-conference/x-cooltalk',
		'f4v':v+'mp4',
		'f4p':v+'mp4',
		'flv':v+'flv',
		'swf':'application/x-shockwave-flash',
		'spl':'application/futuresplash',
		'dxr':'application/x-director',
		'dir':'application/x-director',
		'dcr':'application/x-director',
		'divx':v+'divx',
		'div':v+'divx',
		'dv':v+'x-dv',
		'dif':v+'x-dv',
		'dl':v+'dl',
		'gl':v+'gl',
		'ogv':v+'ogg',
		'ogg':'application/x-ogg',
		'ogx':'application/ogg',
		'axv':v+'annodex',
		'anx':'application/annodex',
		'afl':v+'animaflex',
		'fmf':v+'x-atomic3d-feature',
		'isu':v+'x-isvideo',
		'mjpg':v+'x-motion-jpeg',
		'qtc':v+'x-qtc',
		'rv':v+'vnd.rn-realvideo',
		'ra':'audio/x-pn-realaudio',
		'ram':'audio/x-pn-realaudio',
		'rm':'audio/x-pn-realaudio-plugin',
		'rpm':'audio/x-pn-realaudio-plugin',
		'rpj':'application/vnd.rn-realplayer-javascript',
		'scm':v+'x-scm',
		'vdo':v+'vdo',
		'vos':v+'vosaic',
		'xdr':v+'x-amt-demorun',
		'xsr':v+'x-amt-showrun',
		'sdv':v+'sd-video',
		'vob':v+'mpeg-system',
		'm4v':v+'x-m4v',
		'vlc':'application/x-vlc-plugin',
		'amc':'application/x-mpeg'
	};
})();

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerQuickTime = function(){
	this.name = 'quicktime';
	this.title = 'QuickTime';
	this.needle = ['QuickTime', '(Plug-in|Plugin)'];
	this.progid = 'QuickTime.QuickTime';
	this.classid = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B';
	this.codebase = 'http://uniplayer.overdesign.net/install/QuickTime.cab';	// http://www.apple.com/qtactivex/qtplugin.cab
	this.pluginspage = 'http://www.apple.com/quicktime/download/';
	this.mime = 'video/quicktime';
	this.supported = [
		//-- audio
		'audio/x-wav',
		'audio/wav',
		'audio/aiff',
		'audio/x-aiff',
		'audio/basic',
		'audio/mid',
		'audio/midi',
		'audio/x-midi',
		'audio/vnd.qcelp',
		'audio/x-gsm',
		'audio/amr',
		'audio/aac',
		'audio/x-aac',
		'audio/x-caf',
		'audio/ac3',
		'audio/x-ac3',
		'audio/mpeg',
		'audio/x-mpeg',
		'audio/3gpp',
		'audio/3gpp2',
		'audio/mp4',
		'audio/x-m4a',
		'audio/x-m4p',
		'audio/x-m4b',
		'audio/mp3',
		'audio/x-mp3',
		'audio/mpeg3',
		'audio/x-mpeg3',
		//-- video
		'video/quicktime',
		'video/3gpp',
		'video/x-m4v',
		'video/flc',
		'video/sd-video',
		'video/3gpp',
		'video/3gpp2',
		'video/x-mpeg',
		'video/mpeg',
		'video/mpeg',
		'video/x-msvideo',
		'video/avi',
		'video/mp4'
	];
	this.maxVolume = 256;
	// build		http://developer.apple.com/documentation/QuickTime/Conceptual/QTScripting_HTML/QTScripting_HTML_Document/chapter_1000_section_5.html
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			height+= 16;
		}
		// create object
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: this.player.current.src,
			width: this.player.options.width,
			height: height,
			type: this.mime,
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('src', this.player.current.src, true);
		obj.addParam('autoplay', this.player.options.autoplay);
		obj.addParam('volume', this.player.options.volume*this.maxVolume);
		obj.addParam('controller', this.player.options.showNativeControls);
		obj.addParam('bgcolor', this.player.options.background);
		obj.addParam('scale', 'ToFit');
		//obj.addParam('postdomevents', true);
		obj.addParam('version', 'VideoLAN.VLCPlugin.2');	// if plugin is overridden by VLC, this param is needed to access VLC controls
		// write
		this.movie = obj.write(this.player.holders.movie);
		delete obj;
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		return this.movie;
	};
	// test
	this.test = function(){
		var result = false;
		try{
			result = this.getVersion() ? true : false;
		}
		catch(e){}
		return result;
	};
	//controls		http://developer.apple.com/DOCUMENTATION/quicktime/Conceptual/QTScripting_JavaScript/bQTScripting_JavaScri_Document/chapter_1000_section_7.html
	this.getVersion = function(){
		return this.player.current.movie.GetQuickTimeVersion();
	};
	this.getState = function(){
		var state = typeof(this.state) == 'undefined' ? this.player.current.movie.GetPluginStatus() : this.state;
		var currentState = this.player.current.state;
		switch(state){
			case 'Waiting':
			case 'Loading':
				currentState = this.player.states.loading;
				break;
			case 'Playable':
			case 'Complete':
				currentState = this.player.options.autoplay ? this.player.states.playing : this.player.states.stopped;
				break;
			// custom states
			case 'Playing':
				currentState = this.player.states.playing;
				break;
			case 'Paused':
				currentState = this.player.states.paused;
				break;
			case 'Stopped':
				currentState = this.player.states.stopped;
				break;
			// check error
			default:
				if(state.match(/^Error\:/)){
					currentState = this.player.states.failed;
				}
				break;
		}
		return currentState;
	};
	this.reload = function(){
		delete this.state;
		return this.player.current.movie.SetURL(this.player.current.src);
	};
	this.play = function(){
		this.state = 'Playing';
		return this.player.current.movie.Play();
	};
	this.pause = function(){
		this.state = 'Paused';
		return this.player.current.movie.Stop();
	};
	this.stop = function(){
		this.state = 'Stopped';
		var result = this.player.current.movie.Stop();
		this.setPosition(0);
		return result;
	};
	this.fullScreen = function(){
		return this.player.pageScreen();
	};
	this.getMute = function(){
		return this.player.current.movie.GetMute();
	};
	this.setMute = function(turn){
		return this.player.current.movie.SetMute(turn);
	};
	this.getVolume = function(){
		var volume = this.player.current.movie.GetVolume()/this.player.current.module.maxVolume;
		return (volume < 0 || isNaN(volume)) ? 0 : volume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.SetVolume(volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		var duration = this.player.current.movie.GetDuration()/this.player.current.movie.GetTimeScale();
		return isNaN(duration) ? 0 : duration;
	};
	this.getPosition = function(){
		var position = this.player.current.movie.GetTime();
		return (isNaN(position) || !this.player.current.duration) ? 0 : position/this.player.current.movie.GetTimeScale()/this.player.current.duration;
	};
	this.setPosition = function(position){
		return this.player.current.movie.SetTime(parseInt(position*this.player.current.movie.GetTimeScale()*this.player.current.duration));
	};
};

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerVLC = function(){
	/*
		KNOWN ISSUES
		
		- background
	*/
	this.name = 'vlc';
	this.title = 'VLC';
	this.needle = ['VLC', '(Plug-in|Plugin)'];
	this.progid = 'VideoLAN.VLCPlugin';
	this.classid = 'clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921';
	this.codebase = 'http://uniplayer.overdesign.net/install/VLC.cab';
				  // http://downloads.videolan.org/pub/videolan/vlc/0.8.6c/win32/axvlc.cab
				  // http://downloads.videolan.org/pub/videolan/vlc/0.9.2/win32/axvlc.cab
	this.pluginspage = 'http://www.videolan.org/';
	this.mime = 'application/x-vlc-plugin';
	this.supported = [
		//-- audio
		'audio/flac',
		'audio/mpeg',
		'audio/x-mpeg',
		'audio/mpeg4',
		'audio/wav',
		'audio/x-wav',
		'audio/3gpp',
		'audio/3gpp2',
		//-- video
		'application/x-vlc-plugin',
		'video/mpeg',
		'video/mpeg4',
		'video/x-mpeg',
		'video/x-msvideo',
		'video/x-ms-wmv',
		'application/x-ogg',
		'application/mpeg4-muxcodetable',
		'video/mp4',
		'video/3gpp2',
		'video/x-ms-asf-plugin',
		'video/x-ms-asf',
		'application/mpeg4-iod',
		'video/mpeg-system',
		'video/x-mpeg-system',
		'video/divx',
		'video/x-google-vlc-plugin'
	];
	this.maxVolume = 100;	// can be even 200
	// build		http://www.videolan.org/doc/play-howto/en/ch04.html
	this.build = function(){
		// create object
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: this.player.current.src,
			width: this.player.options.width,
			height: this.player.options.height,
			type: this.mime,
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('src', this.player.current.src, true);
		obj.addParam('version', 'VideoLAN.VLCPlugin.2');
		obj.addParam('autoplay', this.player.options.autoplay);
		obj.addParam('volume', this.player.options.volume*this.maxVolume);
		obj.addParam('showdisplay', true);
		this.movie = obj.write(this.player.holders.movie);
		delete obj;
		this.movie.style.width = this.player.options.width + 'px';
		this.movie.style.height = this.player.options.height + 'px';
		this.player.current.width = this.player.options.width;
		this.player.current.height = this.player.options.height;
		return this.movie;
	};
	// test
	this.test = function(){
		var result = false;
		try{
			result = (this.getVersion() && this.player.current.movie.input) ? true : false;
		}
		catch(e){}
		return result;
	};
	//controls		http://www.videolan.org/doc/play-howto/en/ch04.html
	this.getVersion = function(){
		return this.player.current.movie.VersionInfo;
	};
	this.getState = function(){
		var state = parseInt(this.player.current.movie.input.state);
		var currentState = this.player.current.state;
		switch(state){
			case 1:
			case 2:
				currentState = this.player.states.loading;
				break;
			case 3:
				currentState = this.player.states.playing;
				break;
			case 4:
				currentState = this.player.states.paused;
				break;
			case 6:
				currentState = this.player.states.failed;
				break;
			case 0:
			case 5:
				currentState = this.player.states.stopped;
				break;
		}
		return currentState;
	};
	this.reload = function(){
		this.stop();
		this.player.current.movie.playlist.clear();
		return this.player.current.movie.playlist.add(this.player.current.src);
	};
	this.play = function(){
		return this.player.current.movie.playlist.play();
	};
	this.pause = function(){
		return this.player.current.movie.playlist.togglePause();
	};
	this.stop = function(){
		return this.player.current.movie.playlist.stop();
	};
	this.fullScreen = function(){
		return this.player.current.movie.video.toggleFullscreen();
	};
	this.getMute = function(){
		return this.player.current.movie.audio.mute;
	};
	this.setMute = function(turn){
		return this.player.current.movie.audio.mute = turn;
	};
	this.getVolume = function(){
		return this.player.current.movie.audio.volume/this.player.current.module.maxVolume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.audio.volume = volume*this.player.current.module.maxVolume;
	};
	this.getDuration = function(){
		var duration = this.player.current.movie.input.length/1000;
		return isNaN(duration) ? 0 : duration;
	};
	this.getPosition = function(){
		return this.player.current.movie.input.position;
	};
	this.setPosition = function(position){
		return this.player.current.movie.input.position = position;
	};
};

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerWindowsMedia = function(){
	/*
		KNOWN ISSUES
		
		Windows:
			Firefox3
				-control (needs to install wmpfirefoxplugin.exe)
				-volume-param
			Safari3
				-downgrade to wmp6.4 without wmpfirefoxplugin
				-control (needs to install wmpfirefoxplugin.exe)
				-volume-param
				-volume-js (even if wmpfirefoxplugin installed)
			Opera9
				-volume
				-fullscreen
			IE5.01
				-control

		Flip4Mac:
			ALL
				-volume
				-fullscreen
				-mute
				-getPosition -	instead of Flip4Mac does not provide the Duration property,
				-setPosition	but property CurrentPosition is provided.
			Firefox3
				Flip4Mac controls trows an Exception but works
			Opera9
				-control

		Both:
			- background
			
	*/
	var mac = navigator.appVersion.indexOf('Macintosh') >= 0;
	this.name = mac ? 'flip4mac' : 'windowsmedia';
	this.title = mac ? 'Flip4Mac' : 'Windows Media Player';
	this.needle = ['(Windows Media|ActiveX Plug-in)'];// for google.chrome's activex plugin
	this.progid = 'wmplayer.ocx';
	this.classid = 'clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6';	// 'clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95'; for wmp6.4
	this.codebase = '';	// http://support.microsoft.com/kb/321684
	this.pluginspage = 'http://www.microsoft.com/windows/windowsmedia/player/default.aspx';
	this.mime = 'video/x-ms-wm';	// force using of WMP (VLC or x-mplayer2 may override WMP if other mimetype is used)
	this.supported = [
		'application/x-mplayer2',
		//-- audio
		'audio/mpeg',
		'audio/x-ms-wma',
		'audio/x-ms-wax',
		//-- video
		'video/x-msvideo',
		'video/x-ms-wm',
		'video/x-ms-wmv',
		'video/x-ms-wvx',
		'video/x-ms-asf',
		'video/x-ms-wmx',
		'video/x-ms-asf-plugin',
		'video/x-ms-wmp',
		'video/x-ms-asx'
	];
	this.maxVolume = 100;// -10000 for WMP 6.4;
	// build
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			if(mac){
				height+= 16;
			}
			else{
				height+= 64;
			}
		}
		// create object
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: this.player.current.src,
			width: this.player.options.width,
			height: height,
			type: this.mime,
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('URL', this.player.current.src, true);
		obj.addParam('AutoStart', this.player.options.autoplay ? 1 : 0);
		obj.addParam('volume', this.player.options.volume*this.maxVolume);
		obj.addParam('ShowControls', this.player.options.showNativeControls);
		obj.addParam('ShowStatusBar', this.player.options.showNativeControls);
		obj.addParam('uiMode', this.player.options.showNativeControls ? 'mini' : 'none');
		obj.addParam('version', 'VideoLAN.VLCPlugin.2');	// if plugin is overridden by VLC, this param is needed to access VLC controls
		this.movie = obj.write(this.player.holders.movie);
		delete obj;
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		return this.movie;
	};
	// test
	this.test = function(){
		var result = false;
		try{
			result = (this.player.current.movie.controls || this.player.current.movie.FileName) ? true : false;
		}
		catch(e){}
		return result;
	};
	//controls		http://msdn.microsoft.com/en-us/library/bb248464(VS.85).aspx
	//	wmp6.4		http://msdn.microsoft.com/en-us/ms870192.aspx
	//flip4mac		http://forum.flip4mac.com/forum/messageview.aspx?catid=9&threadid=1271
	//				Flip4Mac WMV Supports the following methods and properties from the Windows Media 6.4 SDK
	//				Methods: "play","pause","Play","Pause","Stop","Next","Previous","Open"
	//				Properties: "CurrentPosition","FileName","PlayState" 
	this.getVersion = function(){
		return this.player.current.movie.versionInfo;		// flip4mac returns undefined
	};
	this.getState = function(){
		var state = 0;
		if(this.player.current.movie.controls){
			state = this.player.current.movie.playState;
		}
		else{
			state = this.player.current.movie.PlayState;
		}
		state = parseInt(state);
		var currentState = this.player.current.state;
		if(this.player.current.movie.controls){
			switch(state){
				case 4:
				case 5:
				case 6:
				case 7:
				case 9:
				case 11:
					currentState = this.player.states.loading;
					break;
				case 3:
					currentState = this.player.states.playing;
					break;
				case 2:
					currentState = this.player.states.paused;
					break;
				case 0:
				case 1:
				case 8:
				case 10:
					currentState = this.player.states.stopped;
					break;
			}
		}
		else{
			switch(state){
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
					currentState = this.player.states.loading;
					break;
				case 2:
					currentState = this.player.states.playing;
					break;
				case 1:
					currentState = this.player.states.paused;
					break;
				case 0:
				case 8:
					currentState = this.player.states.stopped;
					break;
			}
		}
		return currentState;
	};
	this.reload = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.URL = this.player.current.src;
		}
		else{
			return this.player.current.movie.FileName = this.player.current.src;
		}
	};
	this.play = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.controls.play();
		}
		else{
			return this.player.current.movie.Play();
		}
	};
	this.pause = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.controls.pause();
		}
		else{
			return this.player.current.movie.Pause();
		}
	};
	this.stop = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.controls.stop();
		}
		else{
			return this.player.current.movie.Stop();
		}
	};
	this.fullScreen = function(){
		if(mac){
			return this.player.pageScreen();
		}
		else if(this.player.current.movie.controls){
			return this.player.current.movie.fullScreen = true;
		}
		else{
			return this.player.current.movie.displaySize = 3;
		}
	};
	this.getMute = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.settings.mute;
		}
		else{
			return this.player.current.movie.Mute;
		}
	};
	this.setMute = function(turn){
		if(this.player.current.movie.controls){
			return this.player.current.movie.settings.mute = turn;
		}
		else{
			return this.player.current.movie.Mute = turn;
		}
	};
	this.getVolume = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.settings.volume/this.player.current.module.maxVolume;
		}
		else{
			return isNaN(this.player.current.movie.Volume) ? this.player.current.volume : (this.player.current.movie.Volume+10000)/10000;
		}
	};
	this.setVolume = function(volume){
		if(this.player.current.movie.controls){
			return this.player.current.movie.settings.volume = volume*this.player.current.module.maxVolume;
		}
		else{
			return this.player.current.movie.Volume = volume*10000-10000;
		}
	};
	this.getDuration = function(){
		if(this.player.current.movie.controls){
			return this.player.current.movie.currentMedia.duration;
		}
		else{
			return isNaN(this.player.current.movie.Duration) ? 0 : this.player.current.movie.Duration;
		}
	};
	this.getPosition = function(){
		if(this.player.current.movie.controls){
			return this.player.current.duration ? this.player.current.movie.controls.currentPosition/this.player.current.duration : 0;
		}
		else{
			return (!this.player.current.duration || isNaN(this.player.current.movie.CurrentPosition) || this.player.current.movie.CurrentPosition < 0) ? 0 : this.player.current.movie.CurrentPosition/this.player.current.duration;
		}
	};
	this.setPosition = function(position){
		if(this.player.current.movie.controls){
			return this.player.current.movie.controls.currentPosition = position*this.player.current.duration;
		}
		else{
			return this.player.current.movie.currentPosition = position*this.player.current.duration;
		}
	};
};

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerDivX = function(){
	/*
		KNOWN ISSUES
		
		- no javascript control for getVolume
		- background
	*/
	this.name = 'divx';
	this.title = 'DivX';
	this.needle = 'DivX';
	this.progid = 'npdivx.DivXBrowserPlugin';
	this.classid = 'clsid:67DABFBF-D0AB-41fa-9C46-CC0F21721616';
	this.codebase = 'http://uniplayer.overdesign.net/install/DivX.cab';
	this.pluginspage = 'http://go.divx.com/plugin/download/';	// for linux: http://packman.links2linux.org/package/mplayerplug-in
	this.mime = 'video/divx';
	this.supported = [
		'video/divx'
	];
	this.maxVolume = 100;
	this.state = 0;
	this.position = 0;
	// build
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			height+= 20;
		}
		// create object
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: this.player.current.src,
			width: this.player.options.width,
			height: height,
			type: this.mime,
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('src', this.player.current.src, true);
		obj.addParam('autoPlay', this.player.options.autoplay);
		obj.addParam('bannerEnabled', false);
		obj.addParam('mode', this.player.options.showNativeControls?'mini':'null');
		obj.addParam('version', 'VideoLAN.VLCPlugin.2');	// if DivX is overridden by VLC, this param is needed to access VLC controls
		// event statusCallback is only way to get divx web player's status
		var fSeed = 'uniplayer_' + this.name + '_' + Math.floor(Math.random()*100000000);
		var fStateName = fSeed + '_onStateChange';
		var self = this;
		var onStateChange = function(state){
			var currentState = self.player.current.state;
			switch(parseInt(state)){
				case 12:
				case 13:
				case 15:
				case 17:
					currentState = self.player.states.loading;
					break;
				case 10:
					currentState = self.player.states.playing;
					break;
				case 11:
					currentState = self.player.states.paused;
					break;
				case 18:
					currentState = self.player.states.failed;
					break;
				case 14:
				case 16:
				case 19:
					currentState = self.player.states.stopped;
					break;
			}
			self.state = currentState;
		};
		window[fStateName] = onStateChange;
		obj.addParam('statusCallback', fStateName);
		// event timeCallback is only way to get divx web player's status
		var fTimeName = fSeed + '_onPositionChange';
		var self = this;
		var onPositionChange = function(position){
			self.position = self.player.current.duration ? position/self.player.current.duration : 0;
		};
		window[fTimeName] = onPositionChange;
		obj.addParam('timeCallback', fTimeName);
		// write
		this.movie = obj.write(this.player.holders.movie);
		delete obj;
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		return this.movie;
	};
	// test
	this.test = function(){
		var result = false;
		try{
			result = this.getVersion() ? true : false;
		}
		catch(e){}
		return result;
	};
	//controls		http://labs.divx.com/node/5000
	this.getVersion = function(){
		return this.player.current.movie.GetVersion();
	};
	this.getState = function(){
		return this.state;
	};
	this.reload = function(){
		return this.player.current.movie.Open(this.player.current.src);
	};
	this.play = function(){
		return this.player.current.movie.Play();
	};
	this.pause = function(){
		return this.player.current.movie.Pause();
	};
	this.stop = function(){
		return this.player.current.movie.Stop();
	};
	this.fullScreen = function(){
		return this.player.current.movie.GoFullscreen();
	};
	this.getMute = function(){		// divx web player has no way to get current mute state
		return this.player.current.mute;
	};
	this.setMute = function(turn){
		this.player.current.mute = turn ? true : false;
		return turn ? this.player.current.movie.Mute() : this.player.current.movie.UnMute();
	};
	this.getVolume = function(){		// divx web player has no way to get current volume
		return this.player.current.volume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.SetVolume(volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		var duration = this.player.current.movie.GetTotalTime();
		return isNaN(duration) ? 0 : duration;
	};
	this.getPosition = function(){
		return this.position;
	};
	this.setPosition = function(position){
		position = Math.round(position*100);
		this.player.current.movie.Seek('DOWN', position.toString());	// don't work in opera and safari if passed as number
		this.player.current.movie.Seek('UP', position.toString());
		return this.position;
	};
};

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerRealPlayer = function(){
	/*
		KNOWN ISSUES
		
		- no js control in google chrome
		- no js control to fullScreen in Internet Explorer (win)
	*/
	this.name = 'realplayer';
	this.title = 'Real Player';
	this.needle = 'RealPlayer';
	this.progid = 'rmocx.RealPlayer G2 Control';
	this.classid = 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA';
	this.codebase = 'http://uniplayer.overdesign.net/install/RealPlayer.cab';
	this.pluginspage = 'http://www.real.com/';
	this.mime = 'audio/x-pn-realaudio-plugin';
	this.supported = [
		'audio/x-pn-realaudio-plugin',
		'audio/x-pn-realaudio',
		'video/vnd.rn-realvideo',
		'application/vnd.rn-realplayer-javascript'
	];
	this.maxVolume = 100;
	// build		http://service.real.com/help/library/guides/extend/htmfiles/appc_par.htm
	this.build = function(){
		// show native controls
		// real player requires creating of addition <object> for controls
		if(this.player.options.showNativeControls){
			// uniqueName is needed for CONSOLE parameter of both objects
			var uniqueName = 'uniplayer_'+Math.ceil(Math.random()*10000000);
		}
		// create object
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: this.player.current.src,
			width: this.player.options.width,
			height: this.player.options.height,
			type: this.mime,
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('SRC', this.player.current.src, true);
		obj.addParam('AUTOSTART', this.player.options.autoplay);
		obj.addParam('BACKGROUNDCOLOR', this.player.options.background);
		obj.addParam('CONTROLS', 'ImageWindow');
		obj.addParam('NOLOGO', true);
		if(this.player.options.showNativeControls){
			obj.addParam('CONSOLE', uniqueName);
		}
		this.movie = obj.write(this.player.holders.movie);
		delete obj;

		if(this.player.options.showNativeControls){
			// create object for controls realplayer
			var objControls = new this.player.UniplayerObject({
				src: this.player.current.src,
				width: this.player.options.width,
				height: 36,
				type: this.mime,
				classid: this.classid,
				codebase: this.codebase,
				pluginspage: this.pluginspage
			});
			objControls.addParam('SRC', this.player.current.src, true);
			objControls.addParam('AUTOSTART', this.player.options.autoplay);
			objControls.addParam('CONTROLS', 'ControlPanel');
			objControls.addParam('CONSOLE', uniqueName);
			this.movie = objControls.write(this.player.holders.movie, true);
			delete objControls;
		}
		this.player.current.width = this.player.options.width;
		this.player.current.height = this.player.options.height + (this.player.options.showNativeControls ? 36 : 0);
		return this.movie;
	};
	/* test
	this.test = function(){
		var result = false;
		try{
			result = this.getVersion() ? true : false;
		}
		catch(e){}
		return result;
	};*/
	//controls		http://service.real.com/help/library/guides/extend/htmfiles/appa_met.htm
	this.getVersion = function(){
		return this.player.current.movie.GetVersionInfo();
	};
	this.getState = function(){
		var state = parseInt(this.player.current.movie.GetPlayState());
		var currentState = this.player.current.state;
		switch(state){
			case 1:
			case 2:
			case 5:
				currentState = this.player.states.loading;
				break;
			case 3:
				currentState = this.player.states.playing;
				break;
			case 4:
				currentState = this.player.states.paused;
				break;
			case 0:
				currentState = this.player.states.stopped;
				break;
		}
		return currentState;
	};
	this.reload = function(){
		return this.player.current.movie.SetSource(this.player.current.src);
	};
	this.play = function(){
		return this.player.current.movie.DoPlay();
	};
	this.pause = function(){
		return this.player.current.movie.DoPause();
	};
	this.stop = function(){
		return this.player.current.movie.DoStop();
	};
	this.fullScreen = function(){
		return this.player.current.movie.SetFullScreen();
	};
	this.getMute = function(){
		return this.player.current.movie.GetMute();
	};
	this.setMute = function(turn){
		return this.player.current.movie.SetMute(turn);
	};
	this.getVolume = function(){
		var volume = this.player.current.movie.GetVolume();
		return isNaN(volume) ? 0 : volume/this.player.current.module.maxVolume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.SetVolume(volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		var duration = this.player.current.movie.GetLength();
		return isNaN(duration) ? 0 : duration/1000;
	};
	this.getPosition = function(){
		var position = this.player.current.movie.GetPosition();
		return (isNaN(position) || !this.player.current.duration) ? 0 : position/1000/this.player.current.duration;
	};
	this.setPosition = function(position){
		return this.player.current.movie.SetPosition(parseInt(position*1000*this.player.current.duration));
	};
};

///////////////////////////////////////////////////////////////////////////////
//
//  Silverlight.js   			version 2.0.30523.6
//
//  This file is provided by Microsoft as a helper file for websites that
//  incorporate Silverlight Objects. This file is provided under the Microsoft
//  Public License available at 
//  http://code.msdn.microsoft.com/silverlightjs/Project/License.aspx.  
//  You may not use or distribute this file or the code in this file except as 
//  expressly permitted under that license.
// 
//  Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////

if (!window.Silverlight)
{
    window.Silverlight = { };
}

//////////////////////////////////////////////////////////////////
//
// _silverlightCount:
//
// Counter of globalized event handlers
//
//////////////////////////////////////////////////////////////////
Silverlight._silverlightCount = 0;

//////////////////////////////////////////////////////////////////
//
// fwlinkRoot:
//
// Prefix for fwlink URL's
//
//////////////////////////////////////////////////////////////////
Silverlight.fwlinkRoot='http://go2.microsoft.com/fwlink/?LinkID=';

//////////////////////////////////////////////////////////////////
//  
// onGetSilverlight:
//
// Called by Silverlight.GetSilverlight to notify the page that a user
// has requested the Silverlight installer
//
//////////////////////////////////////////////////////////////////
Silverlight.onGetSilverlight = null;

//////////////////////////////////////////////////////////////////
//
// onSilverlightInstalled:
//
// Called by Silverlight.WaitForInstallCompletion when the page detects
// that Silverlight has been installed. The event handler is not called
// in upgrade scenarios.
//
//////////////////////////////////////////////////////////////////
Silverlight.onSilverlightInstalled = function () {window.location.reload(false);};

//////////////////////////////////////////////////////////////////
//
// isInstalled:
//
// Checks to see if the correct version is installed
//
//////////////////////////////////////////////////////////////////
Silverlight.isInstalled = function(version)
{
    var isVersionSupported=false;
    var container = null;
    
    try 
    {
        var control = null;
        
        try
        {
            control = new ActiveXObject('AgControl.AgControl');
            if ( version == null )
            {
                isVersionSupported = true;
            }
            else if ( control.IsVersionSupported(version) )
            {
                isVersionSupported = true;
            }
            control = null;
        }
        catch (e)
        {
            var plugin = navigator.plugins["Silverlight Plug-In"] ;
            if ( plugin )
            {
                if ( version === null )
                {
                    isVersionSupported = true;
                }
                else
                {
                    var actualVer = plugin.description;
                    if ( actualVer === "1.0.30226.2")
                        actualVer = "2.0.30226.2";
                    var actualVerArray =actualVer.split(".");
                    while ( actualVerArray.length > 3)
                    {
                        actualVerArray.pop();
                    }
                    while ( actualVerArray.length < 4)
                    {
                        actualVerArray.push(0);
                    }
                    var reqVerArray = version.split(".");
                    while ( reqVerArray.length > 4)
                    {
                        reqVerArray.pop();
                    }
                    
                    var requiredVersionPart ;
                    var actualVersionPart
                    var index = 0;
                    
                    
                    do
                    {
                        requiredVersionPart = parseInt(reqVerArray[index]);
                        actualVersionPart = parseInt(actualVerArray[index]);
                        index++;
                    }
                    while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
                    
                    if ( requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart) )
                    {
                        isVersionSupported = true;
                    }
                }
            }
        }
    }
    catch (e) 
    {
        isVersionSupported = false;
    }
    if (container) 
    {
        document.body.removeChild(container);
    }
    
    return isVersionSupported;
}
//////////////////////////////////////////////////////////////////
//
// WaitForInstallCompletion:
//
// Occasionally checks for Silverlight installation status. If it
// detects that Silverlight has been installed then it calls
// Silverlight.onSilverlightInstalled();. This is only supported
// if Silverlight was not previously installed on this computer.
//
//////////////////////////////////////////////////////////////////
Silverlight.WaitForInstallCompletion = function()
{
    if ( ! Silverlight.isBrowserRestartRequired && Silverlight.onSilverlightInstalled )
    {
        try
        {
            navigator.plugins.refresh();
        }
        catch(e)
        {
        }
        if ( Silverlight.isInstalled(null) )
        {
            Silverlight.onSilverlightInstalled();
        }
        else
        {
              setTimeout(Silverlight.WaitForInstallCompletion, 3000);
        }    
    }
}
//////////////////////////////////////////////////////////////////
//
// __startup:
//
// Performs startup tasks
//////////////////////////////////////////////////////////////////
Silverlight.__startup = function()
{
    Silverlight.isBrowserRestartRequired = Silverlight.isInstalled(null);
    if ( !Silverlight.isBrowserRestartRequired)
    {
        Silverlight.WaitForInstallCompletion();
    }
    if (window.removeEventListener) { 
       window.removeEventListener('load', Silverlight.__startup , false);
    }
    else { 
        window.detachEvent('onload', Silverlight.__startup );
    }
}

if (window.addEventListener) 
{
    window.addEventListener('load', Silverlight.__startup , false);
}
else 
{
    window.attachEvent('onload', Silverlight.__startup );
}

///////////////////////////////////////////////////////////////////////////////
// createObject:
//
// Inserts a Silverlight <object> tag or installation experience into the HTML
// DOM based on the current installed state of Silverlight. 
//
/////////////////////////////////////////////////////////////////////////////////

Silverlight.createObject = function(source, parentElement, id, properties, events, initParams, userContext)
{
    var slPluginHelper = new Object();
    var slProperties = properties;
    var slEvents = events;
    
    slPluginHelper.version = slProperties.version;
    slProperties.source = source;    
    slPluginHelper.alt = slProperties.alt;
    
    //rename properties to their tag property names. For bacwards compatibility
    //with Silverlight.js version 1.0
    if ( initParams )
        slProperties.initParams = initParams;
    if ( slProperties.isWindowless && !slProperties.windowless)
        slProperties.windowless = slProperties.isWindowless;
    if ( slProperties.framerate && !slProperties.maxFramerate)
        slProperties.maxFramerate = slProperties.framerate;
    if ( id && !slProperties.id)
        slProperties.id = id;
    
    // remove elements which are not to be added to the instantiation tag
    delete slProperties.ignoreBrowserVer;
    delete slProperties.inplaceInstallPrompt;
    delete slProperties.version;
    delete slProperties.isWindowless;
    delete slProperties.framerate;
    delete slProperties.data;
    delete slProperties.src;
    delete slProperties.alt;


    // detect that the correct version of Silverlight is installed, else display install

    if (Silverlight.isInstalled(slPluginHelper.version))
    {
        //move unknown events to the slProperties array
        for (var name in slEvents)
        {
            if ( slEvents[name])
            {
                if ( name == "onLoad" && typeof slEvents[name] == "function" && slEvents[name].length != 1 )
                {
                    var onLoadHandler = slEvents[name];
                    slEvents[name]=function (sender){ return onLoadHandler(document.getElementById(id), userContext, sender)};
                }
                var handlerName = Silverlight.__getHandlerName(slEvents[name]);
                if ( handlerName != null )
                {
                    slProperties[name] = handlerName;
                    slEvents[name] = null;
                }
                else
                {
                    throw "typeof events."+name+" must be 'function' or 'string'";
                }
            }
        }
        slPluginHTML = Silverlight.buildHTML(slProperties);
    }
    //The control could not be instantiated. Show the installation prompt
    else 
    {
        slPluginHTML = Silverlight.buildPromptHTML(slPluginHelper);
    }

    // insert or return the HTML
    if(parentElement)
    {
        parentElement.innerHTML = slPluginHTML;
    }
    else
    {
        return slPluginHTML;
    }

}

///////////////////////////////////////////////////////////////////////////////
//
//  buildHTML:
//
//  create HTML that instantiates the control
//
///////////////////////////////////////////////////////////////////////////////
Silverlight.buildHTML = function( slProperties)
{
    var htmlBuilder = [];

    htmlBuilder.push('<object type=\"application/x-silverlight\" data="data:application/x-silverlight,"');
    if ( slProperties.id != null )
    {
        htmlBuilder.push(' id="' + slProperties.id + '"');
    }
    if ( slProperties.width != null )
    {
        htmlBuilder.push(' width="' + slProperties.width+ '"');
    }
    if ( slProperties.height != null )
    {
        htmlBuilder.push(' height="' + slProperties.height + '"');
    }
    htmlBuilder.push(' >');
    
    delete slProperties.id;
    delete slProperties.width;
    delete slProperties.height;
    
    for (var name in slProperties)
    {
        if (slProperties[name])
        {
            htmlBuilder.push('<param name="'+Silverlight.HtmlAttributeEncode(name)+'" value="'+Silverlight.HtmlAttributeEncode(slProperties[name])+'" />');
        }
    }
    htmlBuilder.push('<\/object>');
    return htmlBuilder.join('');
}



//////////////////////////////////////////////////////////////////
//
// createObjectEx:
//
// takes a single parameter of all createObject 
// parameters enclosed in {}
//
//////////////////////////////////////////////////////////////////

Silverlight.createObjectEx = function(params)
{
    var parameters = params;
    var html = Silverlight.createObject(parameters.source, parameters.parentElement, parameters.id, parameters.properties, parameters.events, parameters.initParams, parameters.context);
    if (parameters.parentElement == null)
    {
        return html;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// buildPromptHTML
//
// Builds the HTML to prompt the user to download and install Silverlight
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.buildPromptHTML = function(slPluginHelper)
{
    var slPluginHTML = "";
    var urlRoot = Silverlight.fwlinkRoot;
    var shortVer = slPluginHelper.version ;
    if ( slPluginHelper.alt )
    {
        slPluginHTML = slPluginHelper.alt;
    }
    else
    {
        if (! shortVer )
        {
            shortVer="";
        }
        slPluginHTML = "<a href='javascript:Silverlight.getSilverlight(\"{1}\");' style='text-decoration: none;'><img src='{2}' alt='Get Microsoft Silverlight' style='border-style: none'/></a>";
        slPluginHTML = slPluginHTML.replace('{1}', shortVer );
        slPluginHTML = slPluginHTML.replace('{2}', urlRoot + '108181');
    }
    
    return slPluginHTML;
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// getSilverlight:
//
// Navigates the browser to the appropriate Silverlight installer
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.getSilverlight = function(version)
{
    if (Silverlight.onGetSilverlight )
    {
        Silverlight.onGetSilverlight();
    }
    
    var shortVer = "";
    var reqVerArray = String(version).split(".");
    if (reqVerArray.length > 1)
    {
        var majorNum = parseInt(reqVerArray[0] );
        if ( isNaN(majorNum) || majorNum < 2 )
        {
            shortVer = "1.0";
        }
        else
        {
            shortVer = reqVerArray[0]+'.'+reqVerArray[1];
        }
    }
    
    var verArg = "";
    
    if (shortVer.match(/^\d+\056\d+$/) )
    {
        verArg = "&v="+shortVer;
    }
    
    Silverlight.followFWLink("114576" + verArg);
}


///////////////////////////////////////////////////////////////////////////////////////////////
//
// followFWLink:
//
// Navigates to a url based on fwlinkid
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.followFWLink = function(linkid)
{
    top.location=Silverlight.fwlinkRoot+String(linkid);
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// HtmlAttributeEncode:
//
// Encodes special characters in input strings as charcodes
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.HtmlAttributeEncode = function( strInput )
{
      var c;
      var retVal = '';

    if(strInput == null)
      {
          return null;
    }
      
      for(var cnt = 0; cnt < strInput.length; cnt++)
      {
            c = strInput.charCodeAt(cnt);

            if (( ( c > 96 ) && ( c < 123 ) ) ||
                  ( ( c > 64 ) && ( c < 91 ) ) ||
                  ( ( c > 43 ) && ( c < 58 ) && (c!=47)) ||
                  ( c == 95 ))
            {
                  retVal = retVal + String.fromCharCode(c);
            }
            else
            {
                  retVal = retVal + '&#' + c + ';';
            }
      }
      
      return retVal;
}
///////////////////////////////////////////////////////////////////////////////
//
//  default_error_handler:
//
//  Default error handling function 
//
///////////////////////////////////////////////////////////////////////////////

Silverlight.default_error_handler = function (sender, args)
{
    var iErrorCode;
    var errorType = args.ErrorType;

    iErrorCode = args.ErrorCode;

    var errMsg = "\nSilverlight error message     \n" ;

    errMsg += "ErrorCode: "+ iErrorCode + "\n";


    errMsg += "ErrorType: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError")
    {
        errMsg += "XamlFile: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError")
    {
        if (args.lineNumber != 0)
        {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " +  args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }
    alert (errMsg);
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __cleanup:
//
// Releases event handler resources when the page is unloaded
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__cleanup = function ()
{
    for (var i = Silverlight._silverlightCount - 1; i >= 0; i--) {
        window['__slEvent' + i] = null;
    }
    Silverlight._silverlightCount = 0;
    if (window.removeEventListener) { 
       window.removeEventListener('unload', Silverlight.__cleanup , false);
    }
    else { 
        window.detachEvent('onunload', Silverlight.__cleanup );
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __getHandlerName:
//
// Generates named event handlers for delegates.
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__getHandlerName = function (handler)
{
    var handlerName = "";
    if ( typeof handler == "string")
    {
        handlerName = handler;
    }
    else if ( typeof handler == "function" )
    {
        if (Silverlight._silverlightCount == 0)
        {
            if (window.addEventListener) 
            {
                window.addEventListener('onunload', Silverlight.__cleanup , false);
            }
            else 
            {
                window.attachEvent('onunload', Silverlight.__cleanup );
            }
        }
        var count = Silverlight._silverlightCount++;
        handlerName = "__slEvent"+count;
        
        window[handlerName]=handler;
    }
    else
    {
        handlerName = null;
    }
    return handlerName;
}

/****************************************************************************
* JW WMV Player version 1.1, created with M$ Silverlight 1.0
*
* This file contains all logic for the JW WMV Player. For a functional setup,
* the following two files are also needed:
* - silverlight.js (for instantiating the silverlight plugin)
* - wmvplayer.xaml (or another XAML skin describing the player graphics)
*
* More info: http://www.jeroenwijering.com/?item=JW_WMV_Player
****************************************************************************/
if(typeof jeroenwijering == "undefined") {
	var jeroenwijering = new Object();
	jeroenwijering.utils = new Object();
}










/****************************************************************************
* The player wrapper; loads config variables and starts MVC cycle.
****************************************************************************/
jeroenwijering.Player = function(cnt,src,cfg) {
	this.controller;
	this.model;
	this.view;
	this.configuration = {
		backgroundcolor:'FFFFFF',
		windowless:'false',
		file:'',
		height:'260',
		image:'',
		backcolor:'FFFFFF',
		frontcolor:'000000',
		lightcolor:'000000',
		screencolor:'000000',
		width:'320',
		logo:'',
		overstretch:'false',
		shownavigation:'true',
		showstop:'false',
		showdigits:'true',
		usefullscreen:'true',
		usemute:'false',
		autostart:'false',
		bufferlength:'3',
		duration:'0',
		repeat:'false',
		sender:'',
		start:'0',
		volume:'90',
		link:'',
		linkfromdisplay:'false',
		linktarget:'_self'
	};
	for(itm in this.configuration) {
		if(cfg[itm] != undefined) {
			if (itm.indexOf('color') > 0) { 
				this.configuration[itm] = cfg[itm].substr(cfg[itm].length-6);
			} else {
				this.configuration[itm] = cfg[itm];
			}
		}
	}
	Silverlight.createObjectEx({
		source:src,
		parentElement:cnt,
		properties:{
			width:this.configuration['width'],
			height:this.configuration['height'],
			version:'1.0',
			inplaceInstallPrompt:true,
			isWindowless:this.configuration['windowless'],
			background:'#'+this.configuration['backgroundcolor']
		},
		events:{
			onLoad:this.onLoadHandler,
			onError:null
		},
		context:this
	});
}

jeroenwijering.Player.prototype = {
	addListener: function(typ,fcn) {
		this.view.listeners.push({type:typ,func:fcn});
	},

	getConfig: function() { 
		return this.configuration;
	},

	onLoadHandler: function(pid,tgt,sdr) {
		tgt.configuration['sender'] = sdr;
		tgt.controller = new jeroenwijering.Controller(tgt.configuration);
		tgt.view = new jeroenwijering.View(tgt.configuration,tgt.controller);
		tgt.model = new jeroenwijering.Model(tgt.configuration,tgt.controller,tgt.view);
		tgt.controller.startMVC(tgt.view,tgt.model);
	},

	sendEvent: function(typ,prm) {
		switch(typ.toUpperCase()) {
			case 'LINK':
				this.controller.setLink();
				break;
			case 'LOAD':
				this.controller.setLoad(prm);
				break;
			case 'MUTE':
				this.controller.setMute();
				break;
			case 'PLAY':
				this.controller.setPlay();
				break;
			case 'SCRUB':
				this.controller.setScrub(prm);
				break;
			case 'STOP':
				this.controller.setStop();
				break;
			case 'VOLUME':
				this.controller.setVolume(prm);
				break;
		}
	}
}










/****************************************************************************
* The controller of the player MVC triad, which processes all user input.
****************************************************************************/
jeroenwijering.Controller = function(cfg) {
	this.configuration = cfg;
}

jeroenwijering.Controller.prototype = {
	startMVC: function(vie,mdl) {
		this.view = vie;
		this.model = mdl;
		if(this.configuration['usemute'] == 'true') {
			this.view.onVolume(0);
			this.view.onMute(true);
			this.model.goVolume(0);
		} else {
			this.view.onVolume(this.configuration['volume']);
			this.model.goVolume(this.configuration['volume']);
		}
		if(this.configuration['autostart'] == 'true') {
			this.model.goStart();
		} else { 
			this.model.goPause();
		}
	},

	setState: function(old,stt) {
		this.state = stt;
		var pos = this.configuration['start'];
		if(old == 'Closed' && pos > 0) {
			setTimeout(jeroenwijering.utils.delegate(this,this.setScrub),200,pos);
		} 
	},

	setLink: function() {
		if (this.configuration['linktarget'].indexOf('javascript:') == 0) {
			return Function(this.configuration['linktarget']).apply();
		} else if (this.configuration['linktarget'] == '_blank') {
			window.open(this.configuration['link']);
		} else if (this.configuration['linktarget'] != '') {
			window.location = this.configuration['link'];
		}
	},

	setLoad: function(fil) {
		if(this.model.state != "Closed") {
			this.model.goStop(); 
		}
		this.configuration['file'] = fil;
		if(this.configuration['autostart'] == 'true') {
			setTimeout(jeroenwijering.utils.delegate(this.model,this.model.goStart),100);
		}
	},

	setMute: function() {
		if(this.configuration['usemute'] == 'true') {
			this.configuration['usemute'] = 'false';
			this.model.goVolume(this.configuration['volume']);
			this.view.onMute(false);
		} else {
			this.configuration['usemute'] = 'true';
			this.model.goVolume(0);
			this.view.onMute(true);
		}
	},

	setPlay: function() {
		if(this.state == 'Buffering' || this.state == 'Playing') {
			if(this.configuration['duration'] == 0) { 
				this.model.goStop();
			} else { 
				this.model.goPause();
			}
		} else {
			this.model.goStart();
		}
	},

	setScrub: function(sec) {
		if(sec < 2) {
			sec = 0;
		} else if (sec > this.configuration['duration']-4) {
			sec = this.configuration['duration']-4;
		}
		if(this.state == 'Buffering' || this.state == 'Playing') {
			this.model.goStart(sec);
		} else {
			this.model.goPause(sec);
		}
	},

	setStop: function() {
		this.model.goStop();
	},

	setVolume: function(pct) {
		if(pct < 0) { pct = 0; } else if(pct > 100) { pct = 100; }
		this.configuration['volume'] = Math.round(pct);
		this.model.goVolume(pct);
		this.view.onVolume(pct);
		if(this.configuration['usemute'] == 'true') {
			this.configuration['usemute'] = 'false';
			this.view.onMute(false);
		} 
	},

	setFullscreen: function() {
		var fss = !this.configuration['sender'].getHost().content.FullScreen;
		this.configuration['sender'].getHost().content.FullScreen = fss;
		jeroenwijering.utils.delegate(this.view,this.view.onFullscreen);
	}
}










/****************************************************************************
* The view of the player MVC triad, which manages the graphics.
****************************************************************************/
jeroenwijering.View = function(cfg,ctr) {
	this.configuration = cfg;
	this.listeners = Array();
	this.controller = ctr;
	this.fstimeout;
	this.fslistener;
	this.display = this.configuration['sender'].findName("PlayerDisplay");
	this.controlbar = this.configuration['sender'].findName("PlayerControls");
	this.configuration['sender'].getHost().content.onResize = 
		jeroenwijering.utils.delegate(this,this.resizePlayer);
	this.configuration['sender'].getHost().content.onFullScreenChange = 
		jeroenwijering.utils.delegate(this,this.onFullscreen);
	this.assignColorsClicks();
	this.resizePlayer();
}

jeroenwijering.View.prototype = {
	onBuffer: function(pct) {
		var snd = this.configuration['sender'];
		if(pct == 0) { 
			snd.findName("BufferText").Text = null;
		} else { 
			pct < 10 ? pct = "0"+pct: pct = ""+pct;
			snd.findName("BufferText").Text = pct;
		}
		this.delegate('BUFFER',[pct]);
	},

	onFullscreen: function(fss) {
		var snd = this.configuration['sender'];
		var fst = snd.getHost().content.FullScreen;
		if(fst) { 
			this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
				this.hideFSControls),2000);
			this.fslistener = this.display.addEventListener('MouseMove',
				jeroenwijering.utils.delegate(this,this.showFSControls));
			snd.findName("FullscreenSymbol").Visibility = "Collapsed";
			snd.findName("FullscreenOffSymbol").Visibility = "Visible";
		} else {
			clearTimeout(this.fstimeout);
			this.display.removeEventListener("MouseMove",this.fslistener);
			this.controlbar.Visibility = "Visible";
			this.display.Cursor = "Hand";
			snd.findName("FullscreenSymbol").Visibility = "Visible";
			snd.findName("FullscreenOffSymbol").Visibility = "Collapsed";
		}
		this.resizePlayer();
		this.delegate('FULLSCREEN');
	},

	showFSControls: function(sdr,arg) {
		var vbt = sdr.findName('PlayerControls');
		var yps = arg.GetPosition(vbt).Y;
		clearTimeout(this.fstimeout);
		this.controlbar.Visibility = "Visible";
		this.display.Cursor = "Hand";
		if(yps < 0) { 
			this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
				this.hideFSControls),2000);
		}
	},

	hideFSControls: function() {
		this.controlbar.Visibility = "Collapsed";
		this.display.Cursor = "None";
	},

	onLoad: function(pct) {
		var snd = this.configuration['sender'];
		var max = snd.findName("TimeSlider").Width;
		snd.findName("DownloadProgress").Width = Math.round(max*pct/100);
		this.delegate('LOAD',[pct]);
	},

	onMute: function(mut) {
		var snd = this.configuration['sender'];
		this.configuration['usemute'] = ''+mut;
		if(mut) {
			snd.findName("VolumeHighlight").Visibility = "Collapsed";
			snd.findName("MuteSymbol").Visibility = "Visible";
			snd.findName("MuteOffSymbol").Visibility = "Collapsed";
			if(this.state == 'Playing') {
				snd.findName("MuteIcon").Visibility = "Visible";
			}
		} else {
			snd.findName("VolumeHighlight").Visibility = "Visible";
			snd.findName("MuteSymbol").Visibility = "Collapsed";
			snd.findName("MuteOffSymbol").Visibility = "Visible";
			snd.findName("MuteIcon").Visibility = "Collapsed";
		}
		this.delegate('MUTE');
	},

	onState: function(old,stt) {
		var snd = this.configuration['sender'];
		this.state = stt;
		if(stt == 'Buffering' || stt == 'Playing' || stt == 'Opening') {
			snd.findName("PlayIcon").Visibility = "Collapsed";
			snd.findName("PlaySymbol").Visibility = "Collapsed";
			snd.findName("PlayOffSymbol").Visibility = "Visible";
			if (stt=='Playing') {
				snd.findName("BufferIcon").Visibility = "Collapsed";
				snd.findName("BufferText").Visibility = "Collapsed";
				if(this.configuration['usemute'] == 'true') {
					snd.findName("MuteIcon").Visibility = "Visible";
				}
			} else{
				snd.findName("BufferIcon").Visibility = "Visible";
				snd.findName("BufferText").Visibility = "Visible";
			}
		} else { 
			snd.findName("MuteIcon").Visibility = "Collapsed";
			snd.findName("BufferIcon").Visibility = "Collapsed";
			snd.findName("BufferText").Visibility = "Collapsed";
			snd.findName("PlayOffSymbol").Visibility = "Collapsed";
			snd.findName("PlaySymbol").Visibility = "Visible";
			if(this.configuration['linkfromdisplay'] == 'true') {
				snd.findName("PlayIcon").Visibility = "Collapsed";
			} else { 
				snd.findName("PlayIcon").Visibility = "Visible";
			}
		}
		try {
			if(!(old == 'Completed' && stt == 'Buffering') &&
				!(old == 'Buffering' && stt == 'Paused')) {
				playerStatusChange(old.toUpperCase(),stt.toUpperCase());
			}
		} catch (err) {}
		this.delegate('STATE',[old,stt]);
	},

	onTime: function(elp,dur) {
		var snd = this.configuration['sender'];
		var snd = this.configuration['sender'];
		var max = snd.findName("TimeSlider").Width;
		if(dur > 0) {
			var pos = Math.round(max*elp/dur);
			this.configuration['duration'] = dur;
			snd.findName("ElapsedText").Text = jeroenwijering.utils.timestring(elp);
			snd.findName("RemainingText").Text = jeroenwijering.utils.timestring(dur-elp);
			snd.findName("TimeSymbol").Visibility = "Visible";
			snd.findName("TimeSymbol")['Canvas.Left'] = pos+4;
			snd.findName("TimeHighlight").Width = pos-2;
		} else  { 
			snd.findName("TimeSymbol").Visibility = "Collapsed";
		}
		this.delegate('TIME',[elp,dur]);
	},

	onVolume: function(pct) {
		var snd = this.configuration['sender'];
		snd.findName("VolumeHighlight").Width = Math.round(pct/5);
		this.delegate('VOLUME',[pct]);
	},

	assignColorsClicks: function() {
		this.display.Cursor = "Hand";
		this.display.Background = "#FF"+this.configuration['screencolor'];
		if(this.configuration['linkfromdisplay'] == 'false') { 
			this.display.addEventListener('MouseLeftButtonUp',
				jeroenwijering.utils.delegate(this.controller,
				this.controller.setPlay));
		} else { 
			this.display.addEventListener('MouseLeftButtonUp',
				jeroenwijering.utils.delegate(this.controller,
				this.controller.setLink));
			this.display.findName("PlayIcon").Visibility = "Collapsed";
		}
		if(this.configuration['logo'] != '') {
			this.display.findName('OverlayCanvas').Visibility = "Visible";
			this.display.findName('OverlayLogo').ImageSource = 
				this.configuration['logo'];
		}
		this.controlbar.findName("ControlbarBack").Fill = 
			"#FF"+this.configuration['backcolor'];
		this.assignButton('Play',this.controller.setPlay);
		this.assignButton('Stop',this.controller.setStop);
		this.configuration['sender'].findName('ElapsedText').Foreground = 
			"#FF"+this.configuration['frontcolor'];
		this.assignSlider('Time',this.changeTime);
		this.configuration['sender'].findName('DownloadProgress').Fill = 
			"#FF"+this.configuration['frontcolor'];
		this.configuration['sender'].findName('RemainingText').Foreground = 
			"#FF"+this.configuration['frontcolor'];
		this.assignButton('Link',this.controller.setLink);
		this.assignButton('Fullscreen',this.controller.setFullscreen);
		this.assignButton('Mute',this.controller.setMute);
		this.assignSlider('Volume',this.changeVolume);
	},

	assignButton: function(btn,act) {
		var el1 = this.configuration['sender'].findName(btn+'Button');
		el1.Cursor = "Hand";
		el1.addEventListener('MouseLeftButtonUp',
			jeroenwijering.utils.delegate(this.controller,act));
		el1.addEventListener('MouseEnter',
			jeroenwijering.utils.delegate(this,this.rollOver));
		el1.addEventListener('MouseLeave',
			jeroenwijering.utils.delegate(this,this.rollOut));
		this.configuration['sender'].findName(btn+'Symbol').Fill = 
			"#FF"+this.configuration['frontcolor'];
		try {
			this.configuration['sender'].findName(btn+'OffSymbol').Fill = 
				"#FF"+this.configuration['frontcolor'];
		} catch(e) {}
	},

	assignSlider: function(sld,act) {
		var el1 = this.configuration['sender'].findName(sld+'Button');
		el1.Cursor = "Hand";
		el1.addEventListener('MouseLeftButtonUp',
			jeroenwijering.utils.delegate(this,act));
		el1.addEventListener('MouseEnter',
			jeroenwijering.utils.delegate(this,this.rollOver));
		el1.addEventListener('MouseLeave',
			jeroenwijering.utils.delegate(this,this.rollOut));
		this.configuration['sender'].findName(sld+'Slider').Fill = 
			"#FF"+this.configuration['frontcolor'];
		this.configuration['sender'].findName(sld+'Highlight').Fill = 
			"#FF"+this.configuration['frontcolor'];
		this.configuration['sender'].findName(sld+'Symbol').Fill = 
			"#FF"+this.configuration['frontcolor'];
	},

	delegate: function(typ,arg) {
		for(var i=0; i<this.listeners.length; i++) {
			if(this.listeners[i]['type'].toUpperCase() == typ) {
				this.listeners[i]['func'].apply(null,arg);
			}
		}
	},

	rollOver: function(sdr) {
		var str = sdr.Name.substr(0,sdr.Name.length-6);
		this.configuration['sender'].findName(str+'Symbol').Fill = 
			"#FF"+this.configuration['lightcolor'];
		try {
			this.configuration['sender'].findName(str+'OffSymbol').Fill = 
				"#FF"+this.configuration['lightcolor'];
		} catch(e) {}
	},

	rollOut: function(sdr) {
		var str = sdr.Name.substr(0,sdr.Name.length-6);
		this.configuration['sender'].findName(str+'Symbol').Fill = 
			"#FF"+this.configuration['frontcolor'];
		try {
			this.configuration['sender'].findName(str+'OffSymbol').Fill = 
				"#FF"+this.configuration['frontcolor'];
		} catch(e) {}
	},

	changeTime: function(sdr,arg) {
		var tbt = sdr.findName('TimeSlider');
		var xps = arg.GetPosition(tbt).X;
		var sec = Math.floor(xps/tbt.Width*this.configuration['duration']);
		this.controller.setScrub(sec);
	},

	changeVolume: function(sdr,arg) {
		var vbt = sdr.findName('VolumeButton');
		var xps = arg.GetPosition(vbt).X;
		this.controller.setVolume(xps*5);
	},

	resizePlayer: function() {
		var wid = this.configuration['sender'].getHost().content.actualWidth;
		var hei = this.configuration['sender'].getHost().content.actualHeight;
		var fss = this.configuration['sender'].getHost().content.FullScreen;
		if(this.configuration['shownavigation'] == 'true') {
			if(fss == true) {
				this.resizeDisplay(wid,hei);
				this.controlbar['Canvas.Left'] = Math.round(wid/2-250);
				this.resizeControlbar(500,hei-this.controlbar.Height-16);
				this.controlbar.findName('ControlbarBack')['Opacity'] = 0.5;
			} else { 
				this.resizeDisplay(wid,hei-20);
				this.controlbar['Canvas.Left'] = 0;
				this.resizeControlbar(wid,hei-this.controlbar.Height);
				this.controlbar.findName('ControlbarBack')['Opacity'] = 1;
			}
		} else {
			this.resizeDisplay(wid,hei);
		}
	},

	resizeDisplay: function(wid,hei) {
		this.stretchElement('PlayerDisplay',wid,hei);
		this.stretchElement('VideoWindow',wid,hei);
		this.stretchElement('PlaceholderImage',wid,hei);
		this.centerElement('PlayIcon',wid,hei);
		this.centerElement('MuteIcon',wid,hei);
		this.centerElement('BufferIcon',wid,hei);
		this.centerElement('BufferText',wid,hei);
		this.display.findName('OverlayCanvas')['Canvas.Left'] = wid -
			this.display.findName('OverlayCanvas').Width - 10;
		this.display.Visibility = "Visible";
	},

	resizeControlbar: function(wid,yps,alp) {
		this.controlbar['Canvas.Top'] = yps;
		this.stretchElement('PlayerControls',wid);
		this.stretchElement('ControlbarBack',wid);
		this.placeElement('PlayButton',0);
		var lft = 17;
		this.placeElement('VolumeButton',wid-24);
		this.placeElement('MuteButton',wid-37);
		var rgt = 37;
		if(this.configuration['showstop'] == 'true') {
			this.placeElement('StopButton',lft);
			lft += 17;
		} else {
			this.controlbar.findName('StopButton').Visibility="Collapsed";
		}
		if(this.configuration['usefullscreen'] == 'true') {
			rgt += 18;
			this.placeElement('FullscreenButton',wid-rgt);
		} else {
			this.controlbar.findName('FullscreenButton').Visibility = 
				"Collapsed";
		}
		if(this.configuration['link'] != '') {
			rgt += 18;
			this.placeElement('LinkButton',wid-rgt);
		} else {
			this.controlbar.findName('LinkButton').Visibility="Collapsed";
		}
		if(this.configuration['showdigits'] == 'true' && wid-rgt-lft> 160) {
			rgt += 35;
			this.controlbar.findName('RemainingButton').Visibility="Visible";
			this.controlbar.findName('ElapsedButton').Visibility="Visible";
			this.placeElement('RemainingButton',wid-rgt);
			this.placeElement('ElapsedButton',lft);
			lft +=35;
		} else {
			this.controlbar.findName('RemainingButton').Visibility = 
				"Collapsed";
			this.controlbar.findName('ElapsedButton').Visibility="Collapsed";
		}
		this.placeElement('TimeButton',lft);
		this.stretchElement('TimeButton',wid-lft-rgt);
		this.stretchElement('TimeShadow',wid-lft-rgt);
		this.stretchElement('TimeStroke',wid-lft-rgt);
		this.stretchElement('TimeFill',wid-lft-rgt);
		this.stretchElement('TimeSlider',wid-lft-rgt-10);
		this.stretchElement('DownloadProgress',wid-lft-rgt-10);
		var tsb = this.configuration['sender'].findName('TimeSymbol');
		this.stretchElement('TimeHighlight',tsb['Canvas.Left']-5);
		this.controlbar.Visibility = "Visible";
	},

	centerElement: function(nam,wid,hei) {
		var elm = this.configuration['sender'].findName(nam);
		elm['Canvas.Left'] = Math.round(wid/2 - elm.Width/2);
		elm['Canvas.Top'] = Math.round(hei/2 - elm.Height/2);
	},

	stretchElement: function(nam,wid,hei) {
		var elm = this.configuration['sender'].findName(nam);
		elm.Width = wid;
		if (hei != undefined) { elm.Height = hei; }
	},

	placeElement: function(nam,xps,yps) {
		var elm = this.configuration['sender'].findName(nam);
		elm['Canvas.Left'] = xps;
		if(yps) { elm['Canvas.Top'] = yps; }
	}
}










/****************************************************************************
* The model of the player MVC triad, which stores all playback logic.
****************************************************************************/
jeroenwijering.Model = function(cfg,ctr,vie) {
	this.configuration = cfg;
	this.controller = ctr;
	this.view = vie;
	this.video = this.configuration['sender'].findName("VideoWindow");
	this.preview = this.configuration['sender'].findName("PlaceholderImage");
	var str = {
		'true':'UniformToFill',
		'false':'Uniform',
		'fit':'Fill',
		'none':'None'
	}
	this.state = this.video.CurrentState;
	this.timeint;
	this.video.Stretch = str[this.configuration['overstretch']];
	this.preview.Stretch = str[this.configuration['overstretch']];
	this.video.BufferingTime = 
		jeroenwijering.utils.spanstring(this.configuration['bufferlength']);
	this.video.AutoPlay = true;
	this.video.AddEventListener("CurrentStateChanged",
		jeroenwijering.utils.delegate(this,this.stateChanged));
	this.video.AddEventListener("MediaEnded",
		jeroenwijering.utils.delegate(this,this.mediaEnded));
	this.video.AddEventListener("BufferingProgressChanged",
		jeroenwijering.utils.delegate(this,this.bufferChanged));
	this.video.AddEventListener("DownloadProgressChanged",
		jeroenwijering.utils.delegate(this,this.downloadChanged));
	if(this.configuration['image'] != '') {
		this.preview.Source = this.configuration['image'];
	}
}

jeroenwijering.Model.prototype = {
	goPause: function(sec) {
		this.video.pause();
		if(!isNaN(sec)) {
			this.video.Position = jeroenwijering.utils.spanstring(sec);
		}
		this.timeChanged();
	},

	goStart: function(sec) {
		this.video.Visibility = 'Visible';
		this.preview.Visibility = 'Collapsed';
		if(this.state == "Closed") {
			this.video.Source = this.configuration['file'];
		} else {
			this.video.play();
		}
		if(!isNaN(sec)) {
			this.video.Position = jeroenwijering.utils.spanstring(sec);
		}
	},

	goStop: function() {
		this.video.Visibility = 'Collapsed';
		this.preview.Visibility = 'Visible';
		this.goPause(0);
		this.video.Source = 'null';
		this.view.onBuffer(0);
		clearInterval(this.timeint);
	},

	goVolume: function(pct) {
		this.video.Volume = pct/100;
	},

	stateChanged: function() {
		var stt = this.video.CurrentState;
		if(stt != this.state) {
			this.controller.setState(this.state,stt);
			this.view.onState(this.state,stt);
			this.state = stt;
			this.configuration['duration'] = 
				Math.round(this.video.NaturalDuration.Seconds*10)/10;
			if(stt != "Playing" && stt != "Buffering" && stt != "Opening") {
				clearInterval(this.timeint);
			} else {
				this.timeint = setInterval(jeroenwijering.utils.delegate(
					this,this.timeChanged),100);
			}
		}
	},

	mediaEnded: function() {
		if(this.configuration['repeat'] == 'true') {
			this.goStart(0);
		} else {
			this.state = 'Completed';
			this.view.onState(this.state,'Completed');
			this.video.Visibility = 'Collapsed';
			this.preview.Visibility = 'Visible';
			this.goPause(0);
		}
	},

	bufferChanged: function() {
		var bfr = Math.round(this.video.BufferingProgress*100);
		this.view.onBuffer(bfr);
	},

	downloadChanged: function() {
		var dld = Math.round(this.video.DownloadProgress*100);
		this.view.onLoad(dld);
	},

	timeChanged: function() {
		var pos = Math.round(this.video.Position.Seconds*10)/10;
		this.view.onTime(pos,this.configuration['duration']);
	}
}










/****************************************************************************
* Some utility functions.
****************************************************************************/
jeroenwijering.utils.delegate = function(obj,fcn) {
	return function() {
		return fcn.apply(obj,arguments);
	}
}
jeroenwijering.utils.timestring = function(stp) {
	var hrs = Math.floor(stp/3600);
	var min = Math.floor(stp%3600/60);
	var sec = Math.round(stp%60);
	var str = "";
	sec > 9 ? str += sec: str +='0'+sec;
	min > 9 ? str = min+":"+str: str='0'+min+":"+str;
	hrs > 0 ? str = hrs+":"+str: null;
	return str;
}
jeroenwijering.utils.spanstring = function(stp) {
	var hrs = Math.floor(stp/3600);
	var min = Math.floor(stp%3600/60);
	var sec = Math.round(stp%60*10)/10;
	var str = hrs+':'+min+':'+sec;
	return str;
}

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerSilverlight = function(conf){
	/*
		KNOWN ISSUES
		
		- fullScreen
		- pageScreen
		- getVersion
		- background
	*/
	this.name = 'silverlight';
	this.title = 'Silverlight JW Player';
	this.logo = 'silverlight.gif';
	this.needle = 'Silverlight';
	this.progid = 'AgControl.AgControl';
	this.classid = 'clsid:DFEAF541-F3E1-4c24-ACAC-99C30715084A';
	this.codebase = '';
	this.pluginspage = '';
	this.mime = 'application/x-silverlight';
	this.supported = [
		//-- audio
		'audio/mpeg',
		'audio/x-ms-wma',
		//-- video
		'video/x-ms-wmv',
		'video/x-ms-asf',
		'application/x-silverlight',
		'application/x-silverlight-2-b2'
	];
	this.maxVolume = 100;
	this.duration = 0;
	this.position = 0;
	this.state = 0;
	// build		http://developer.longtailvideo.com/trac/wiki/SLVars
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			height+= 20;
		}
		// create object
		var xaml = (conf && conf.xaml) ? conf.xaml : 'http://uniplayer.overdesign.net/components/jwplayerSilverlight/wmvplayer.xaml';
		this.movie = new jeroenwijering.Player(this.player.holders.movie, xaml, {
			height: height,
			width: this.player.options.width,
			file: this.player.current.src,
			autostart: this.player.options.autoplay ? 'true' : 'false',
			volume: this.player.options.volume*this.maxVolume,
			backgroundcolor: this.player.options.background,
			screencolor: this.player.options.background,
			shownavigation: this.player.options.showNativeControls ? 'true' : 'false',
			showstop: 'true'
		});
		var self = this;
		var stateUpdate = function(oldstate, newstate){
			switch(newstate){
				case 'Opening':
				case 'Buffering':
					self.state = self.player.states.loading;
					break;
				case 'Playing':
					self.state = self.player.states.playing;
					break;
				case 'Paused':
					self.state = self.player.states.paused;
					break;
				case 'Closed':
				case 'Stopped':
				case 'Completed':
					self.state = self.player.states.stopped;
					break;
			}
		};
		var timeUpdate = function(elapsed, total){
			self.duration = total;
			self.position = self.duration ? elapsed/self.duration : 0;
		};
		var addListeners = function(){
			if(typeof self.movie.view != 'undefined'){
				self.movie.addListener('STATE', stateUpdate);
				self.movie.addListener('TIME', timeUpdate);
			}
			else{
				setTimeout(addListeners, 100);
			}
		};
		addListeners();
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		return this.movie;
	};
	// controls		http://developer.longtailvideo.com/trac/wiki/SLAPI
	this.getState = function(){
		return this.state;
	};
	this.reload = function(){
		this.player.current.movie.sendEvent('LOAD', this.player.current.src);
	};
	this.play = function(){
		return this.player.current.movie.sendEvent('PLAY', true);
	};
	this.pause = function(){
		return this.player.current.movie.sendEvent('PLAY', false);
	};
	this.stop = function(){
		return this.player.current.movie.sendEvent('STOP');
	};
	this.getMute = function(){
		return this.player.current.movie.getConfig().mute;
	};
	this.setMute = function(turn){
		return this.player.current.movie.sendEvent('MUTE', turn);
	};
	this.getVolume = function(){
		return this.player.current.movie.getConfig().volume/this.player.current.module.maxVolume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.sendEvent('VOLUME', volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		return this.duration;
	};
	this.getPosition = function(){
		return this.position;
	};
	this.setPosition = function(position){
		return this.player.current.movie.sendEvent('SCRUB', position*100);
	};
};

/* 
 * flowplayer.js 3.1.0. The Flowplayer API
 * 
 * Copyright 2009 Flowplayer Oy
 * 
 * This file is part of Flowplayer.
 * 
 * Flowplayer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Flowplayer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Flowplayer.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Date: 2009-04-15 06:02:21 +0000 (Wed, 15 Apr 2009)
 * Revision: 199 
 */
(function(){function g(o){console.log("$f.fireEvent",[].slice.call(o))}function k(q){if(!q||typeof q!="object"){return q}var o=new q.constructor();for(var p in q){if(q.hasOwnProperty(p)){o[p]=k(q[p])}}return o}function m(t,q){if(!t){return}var o,p=0,r=t.length;if(r===undefined){for(o in t){if(q.call(t[o],o,t[o])===false){break}}}else{for(var s=t[0];p<r&&q.call(s,p,s)!==false;s=t[++p]){}}return t}function c(o){return document.getElementById(o)}function i(q,p,o){if(typeof p!="object"){return q}if(q&&p){m(p,function(r,s){if(!o||typeof s!="function"){q[r]=s}})}return q}function n(s){var q=s.indexOf(".");if(q!=-1){var p=s.substring(0,q)||"*";var o=s.substring(q+1,s.length);var r=[];m(document.getElementsByTagName(p),function(){if(this.className&&this.className.indexOf(o)!=-1){r.push(this)}});return r}}function f(o){o=o||window.event;if(o.preventDefault){o.stopPropagation();o.preventDefault()}else{o.returnValue=false;o.cancelBubble=true}return false}function j(q,o,p){q[o]=q[o]||[];q[o].push(p)}function e(){return"_"+(""+Math.random()).substring(2,10)}var h=function(t,r,s){var q=this;var p={};var u={};q.index=r;if(typeof t=="string"){t={url:t}}i(this,t,true);m(("Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop").split(","),function(){var v="on"+this;if(v.indexOf("*")!=-1){v=v.substring(0,v.length-1);var w="onBefore"+v.substring(2);q[w]=function(x){j(u,w,x);return q}}q[v]=function(x){j(u,v,x);return q};if(r==-1){if(q[w]){s[w]=q[w]}if(q[v]){s[v]=q[v]}}});i(this,{onCuepoint:function(x,w){if(arguments.length==1){p.embedded=[null,x];return q}if(typeof x=="number"){x=[x]}var v=e();p[v]=[x,w];if(s.isLoaded()){s._api().fp_addCuepoints(x,r,v)}return q},update:function(w){i(q,w);if(s.isLoaded()){s._api().fp_updateClip(w,r)}var v=s.getConfig();var x=(r==-1)?v.clip:v.playlist[r];i(x,w,true)},_fireEvent:function(v,y,w,A){if(v=="onLoad"){m(p,function(B,C){if(C[0]){s._api().fp_addCuepoints(C[0],r,B)}});return false}A=A||q;if(v=="onCuepoint"){var z=p[y];if(z){return z[1].call(s,A,w)}}if(v=="onStart"||v=="onUpdate"){i(A,y);if(!A.duration){A.duration=y.metaData.duration}else{A.fullDuration=y.metaData.duration}}var x=true;m(u[v],function(){x=this.call(s,A,y,w)});return x}});if(t.onCuepoint){var o=t.onCuepoint;q.onCuepoint.apply(q,typeof o=="function"?[o]:o);delete t.onCuepoint}m(t,function(v,w){if(typeof w=="function"){j(u,v,w);delete t[v]}});if(r==-1){s.onCuepoint=this.onCuepoint}};var l=function(p,r,q,t){var s={};var o=this;var u=false;if(t){i(s,t)}m(r,function(v,w){if(typeof w=="function"){s[v]=w;delete r[v]}});i(this,{animate:function(y,z,x){if(!y){return o}if(typeof z=="function"){x=z;z=500}if(typeof y=="string"){var w=y;y={};y[w]=z;z=500}if(x){var v=e();s[v]=x}if(z===undefined){z=500}r=q._api().fp_animate(p,y,z,v);return o},css:function(w,x){if(x!==undefined){var v={};v[w]=x;w=v}r=q._api().fp_css(p,w);i(o,r);return o},show:function(){this.display="block";q._api().fp_showPlugin(p);return o},hide:function(){this.display="none";q._api().fp_hidePlugin(p);return o},toggle:function(){this.display=q._api().fp_togglePlugin(p);return o},fadeTo:function(y,x,w){if(typeof x=="function"){w=x;x=500}if(w){var v=e();s[v]=w}this.display=q._api().fp_fadeTo(p,y,x,v);this.opacity=y;return o},fadeIn:function(w,v){return o.fadeTo(1,w,v)},fadeOut:function(w,v){return o.fadeTo(0,w,v)},getName:function(){return p},getPlayer:function(){return q},_fireEvent:function(w,v,x){if(w=="onUpdate"){var y=q._api().fp_getPlugin(p);if(!y){return}i(o,y);delete o.methods;if(!u){m(y.methods,function(){var A=""+this;o[A]=function(){var B=[].slice.call(arguments);var C=q._api().fp_invoke(p,A,B);return C=="undefined"?o:C}});u=true}}var z=s[w];if(z){z.apply(o,v);if(w.substring(0,1)=="_"){delete s[w]}}}})};function b(o,t,z){var E=this,y=null,x,u,p=[],s={},B={},r,v,w,D,A,q;i(E,{id:function(){return r},isLoaded:function(){return(y!==null)},getParent:function(){return o},hide:function(F){if(F){o.style.height="0px"}if(y){y.style.height="0px"}return E},show:function(){o.style.height=q+"px";if(y){y.style.height=A+"px"}return E},isHidden:function(){return y&&parseInt(y.style.height,10)===0},load:function(F){if(!y&&E._fireEvent("onBeforeLoad")!==false){m(a,function(){this.unload()});x=o.innerHTML;if(x&&!flashembed.isSupported([9,0])){wrappper.innerHTML=""}flashembed(o,t,{config:z});if(F){F.cached=true;j(B,"onLoad",F)}}return E},unload:function(){try{if(!y||y.fp_isFullscreen()){return E}}catch(F){return E}if(x.replace(/\s/g,"")!==""){if(E._fireEvent("onBeforeUnload")===false){return false}y.fp_close();y=null;o.innerHTML=x;E._fireEvent("onUnload")}return E},getClip:function(F){if(F===undefined){F=D}return p[F]},getCommonClip:function(){return u},getPlaylist:function(){return p},getPlugin:function(F){var H=s[F];if(!H&&E.isLoaded()){var G=E._api().fp_getPlugin(F);if(G){H=new l(F,G,E);s[F]=H}}return H},getScreen:function(){return E.getPlugin("screen")},getControls:function(){return E.getPlugin("controls")},getConfig:function(F){return F?k(z):z},getFlashParams:function(){return t},loadPlugin:function(I,H,K,J){if(typeof K=="function"){J=K;K={}}var G=J?e():"_";E._api().fp_loadPlugin(I,H,K,G);var F={};F[G]=J;var L=new l(I,null,E,F);s[I]=L;return L},getState:function(){return y?y.fp_getState():-1},play:function(F){function G(){if(F!==undefined){E._api().fp_play(F)}else{E._api().fp_play()}}if(y){G()}else{E.load(function(){G()})}return E},getVersion:function(){var G="flowplayer.js 3.1.0";if(y){var F=y.fp_getVersion();F.push(G);return F}return G},_api:function(){if(!y){throw"Flowplayer "+E.id()+" not loaded when calling an API method"}return y},setClip:function(F){E.setPlaylist([F]);return E},getIndex:function(){return w}});m(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),function(){var F="on"+this;if(F.indexOf("*")!=-1){F=F.substring(0,F.length-1);var G="onBefore"+F.substring(2);E[G]=function(H){j(B,G,H);return E}}E[F]=function(H){j(B,F,H);return E}});m(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset,close,setPlaylist").split(","),function(){var F=this;E[F]=function(G){if(!y){return E}var H=(G===undefined)?y["fp_"+F]():y["fp_"+F](G);return H=="undefined"?E:H}});E._fireEvent=function(O){if(typeof O=="string"){O=[O]}var P=O[0];var L=O[1];var K=O[2];var J=O[3];if(z.debug){g(O)}if(!y&&P=="onLoad"&&L=="player"){y=y||c(v);A=y.clientHeight;m(p,function(){this._fireEvent("onLoad")});m(s,function(Q,R){R._fireEvent("onUpdate")});u._fireEvent("onLoad")}if(P=="onLoad"&&L!="player"){return}if(P=="onError"){if(typeof L=="string"||(typeof L=="number"&&typeof K=="number")){L=K;K=J}}if(P=="onContextMenu"){m(z.contextMenu[L],function(Q,R){R.call(E)});return}if(P=="onPluginEvent"){var F=L.name||L;var G=s[F];if(G){G._fireEvent("onUpdate",L);G._fireEvent(K,O.slice(3))}return}if(P=="onPlaylistReplace"){p=[];var M=0;m(L,function(){p.push(new h(this,M++,E))})}var N=true;if(typeof L=="number"&&L<p.length){D=L;var H=p[L];if(H){N=H._fireEvent(P,K,J)}if(!H||N!==false){N=u._fireEvent(P,K,J,H)}}var I=0;m(B[P],function(){N=this.call(E,L,K);if(this.cached){B[P].splice(I,1)}if(N===false){return false}I++});return N};function C(){if($f(o)){$f(o).getParent().innerHTML="";w=$f(o).getIndex();a[w]=E}else{a.push(E);w=a.length-1}q=parseInt(o.style.height,10)||o.clientHeight;if(typeof t=="string"){t={src:t}}r=o.id||"fp"+e();v=t.id||r+"_api";t.id=v;z.playerId=r;if(typeof z=="string"){z={clip:{url:z}}}if(typeof z.clip=="string"){z.clip={url:z.clip}}z.clip=z.clip||{};if(o.getAttribute("href",2)&&!z.clip.url){z.clip.url=o.getAttribute("href",2)}u=new h(z.clip,-1,E);z.playlist=z.playlist||[z.clip];var F=0;m(z.playlist,function(){var H=this;if(typeof H=="object"&&H.length){H={url:""+H}}m(z.clip,function(I,J){if(J!==undefined&&H[I]===undefined&&typeof J!="function"){H[I]=J}});z.playlist[F]=H;H=new h(H,F,E);p.push(H);F++});m(z,function(H,I){if(typeof I=="function"){j(B,H,I);delete z[H]}});m(z.plugins,function(H,I){if(I){s[H]=new l(H,I,E)}});if(!z.plugins||z.plugins.controls===undefined){s.controls=new l("controls",null,E)}s.canvas=new l("canvas",null,E);t.bgcolor=t.bgcolor||"#000000";t.version=t.version||[9,0];t.expressInstall="http://www.flowplayer.org/swf/expressinstall.swf";function G(H){if(!E.isLoaded()&&E._fireEvent("onBeforeClick")!==false){E.load()}return f(H)}x=o.innerHTML;if(x.replace(/\s/g,"")!==""){if(o.addEventListener){o.addEventListener("click",G,false)}else{if(o.attachEvent){o.attachEvent("onclick",G)}}}else{if(o.addEventListener){o.addEventListener("click",f,false)}E.load()}}if(typeof o=="string"){flashembed.domReady(function(){var F=c(o);if(!F){throw"Flowplayer cannot access element: "+o}else{o=F;C()}})}else{C()}}var a=[];function d(o){this.length=o.length;this.each=function(p){m(o,p)};this.size=function(){return o.length}}window.flowplayer=window.$f=function(){var p=null;var o=arguments[0];if(!arguments.length){m(a,function(){if(this.isLoaded()){p=this;return false}});return p||a[0]}if(arguments.length==1){if(typeof o=="number"){return a[o]}else{if(o=="*"){return new d(a)}m(a,function(){if(this.id()==o.id||this.id()==o||this.getParent()==o){p=this;return false}});return p}}if(arguments.length>1){var r=arguments[1];var q=(arguments.length==3)?arguments[2]:{};if(typeof o=="string"){if(o.indexOf(".")!=-1){var t=[];m(n(o),function(){t.push(new b(this,k(r),k(q)))});return new d(t)}else{var s=c(o);return new b(s!==null?s:o,r,q)}}else{if(o){return new b(o,r,q)}}}return null};i(window.$f,{fireEvent:function(){var o=[].slice.call(arguments);var q=$f(o[0]);return q?q._fireEvent(o.slice(1)):null},addPlugin:function(o,p){b.prototype[o]=p;return $f},each:m,extend:i});if(document.all){window.onbeforeunload=function(){$f("*").each(function(){if(this.isLoaded()){this.close()}})}}if(typeof jQuery=="function"){jQuery.prototype.flowplayer=function(q,p){if(!arguments.length||typeof arguments[0]=="number"){var o=[];this.each(function(){var r=$f(this);if(r){o.push(r)}});return arguments.length?o[arguments[0]]:new d(o)}return this.each(function(){$f(this,k(q),p?k(p):{})})}}})();(function(){var e=typeof jQuery=="function";function i(){if(c.done){return false}var k=document;if(k&&k.getElementsByTagName&&k.getElementById&&k.body){clearInterval(c.timer);c.timer=null;for(var j=0;j<c.ready.length;j++){c.ready[j].call()}c.ready=null;c.done=true}}var c=e?jQuery:function(j){if(c.done){return j()}if(c.timer){c.ready.push(j)}else{c.ready=[j];c.timer=setInterval(i,13)}};function f(k,j){if(j){for(key in j){if(j.hasOwnProperty(key)){k[key]=j[key]}}}return k}function g(j){switch(h(j)){case"string":j=j.replace(new RegExp('(["\\\\])',"g"),"\\$1");j=j.replace(/^\s?(\d+)%/,"$1pct");return'"'+j+'"';case"array":return"["+b(j,function(m){return g(m)}).join(",")+"]";case"function":return'"function()"';case"object":var k=[];for(var l in j){if(j.hasOwnProperty(l)){k.push('"'+l+'":'+g(j[l]))}}return"{"+k.join(",")+"}"}return String(j).replace(/\s/g," ").replace(/\'/g,'"')}function h(k){if(k===null||k===undefined){return false}var j=typeof k;return(j=="object"&&k.push)?"array":j}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function b(j,m){var l=[];for(var k in j){if(j.hasOwnProperty(k)){l[k]=m(j[k])}}return l}function a(q,s){var o=f({},q);var r=document.all;var m='<object width="'+o.width+'" height="'+o.height+'"';if(r&&!o.id){o.id="_"+(""+Math.random()).substring(9)}if(o.id){m+=' id="'+o.id+'"'}o.src+=((o.src.indexOf("?")!=-1?"&":"?")+Math.random());if(o.w3c||!r){m+=' data="'+o.src+'" type="application/x-shockwave-flash"'}else{m+=' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'}m+=">";if(o.w3c||r){m+='<param name="movie" value="'+o.src+'" />'}o.width=o.height=o.id=o.w3c=o.src=null;for(var j in o){if(o[j]!==null){m+='<param name="'+j+'" value="'+o[j]+'" />'}}var n="";if(s){for(var l in s){if(s[l]!==null){n+=l+"="+(typeof s[l]=="object"?g(s[l]):s[l])+"&"}}n=n.substring(0,n.length-1);m+='<param name="flashvars" value=\''+n+"' />"}m+="</object>";return m}function d(l,o,k){var j=flashembed.getVersion();f(this,{getContainer:function(){return l},getConf:function(){return conf},getVersion:function(){return j},getFlashvars:function(){return k},getApi:function(){return l.firstChild},getHTML:function(){return a(o,k)}});var p=o.version;var q=o.expressInstall;var n=!p||flashembed.isSupported(p);if(n){o.onFail=o.version=o.expressInstall=null;l.innerHTML=a(o,k)}else{if(p&&q&&flashembed.isSupported([6,65])){f(o,{src:q});k={MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title};l.innerHTML=a(o,k)}else{if(l.innerHTML.replace(/\s/g,"")!==""){}else{l.innerHTML="<h2>Flash version "+p+" or greater is required</h2><h3>"+(j[0]>0?"Your version is "+j:"You have no flash plugin installed")+"</h3>"+(l.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='http://www.adobe.com/go/getflashplayer'>here</a></p>");if(l.tagName=="A"){l.href="http://www.adobe.com/go/getflashplayer"}}}}if(!n&&o.onFail){var m=o.onFail.call(this);if(typeof m=="string"){l.innerHTML=m}}}window.flashembed=function(k,l,j){if(typeof k=="string"){var m=document.getElementById(k);if(m){k=m}else{c(function(){flashembed(k,l,j)});return}}if(!k){return}var n={width:"100%",height:"100%",allowFullScreen:true,allowscriptaccess:"always",quality:"high",version:null,onFail:null,expressInstall:null,w3c:false};if(typeof l=="string"){l={src:l}}f(n,l);return new d(k,n,j)};f(window.flashembed,{getVersion:function(){var l=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var k=navigator.plugins["Shockwave Flash"].description;if(typeof k!="undefined"){k=k.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var m=parseInt(k.replace(/^(.*)\..*$/,"$1"),10);var q=/r/.test(k)?parseInt(k.replace(/^.*r(.*)$/,"$1"),10):0;l=[m,q]}}else{if(window.ActiveXObject){try{var o=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7")}catch(p){try{o=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");l=[6,0];o.AllowScriptAccess="always"}catch(j){if(l[0]==6){return}}try{o=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")}catch(n){}}if(typeof o=="object"){k=o.GetVariable("$version");if(typeof k!="undefined"){k=k.replace(/^\S+\s+(.*)$/,"$1").split(",");l=[parseInt(k[0],10),parseInt(k[2],10)]}}}}return l},isSupported:function(j){var l=flashembed.getVersion();var k=(l[0]>j[0])||(l[0]==j[0]&&l[1]>=j[1]);return k},domReady:c,asString:g,getHTML:a});if(e){jQuery.prototype.flashembed=function(k,j){return this.each(function(){flashembed(this,k,j)})}}})();

/*
    Uniplayer - Universal Web Media Player
    Copyright (C) 2008 Artem Bandur <artico@overdesign.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

UniplayerFlashJWPlayer = function(conf){
	/*
		KNOWN ISSUES
		
		- no javascript control for fullScreen due to flash security restrictions
	*/
	this.name = 'flashjw';
	this.title = 'Flash JW Player';
	this.needle = 'Flash';
	this.progid = 'ShockwaveFlash.ShockwaveFlash';
	this.classid = 'clsid:D27CDB6E-AE6D-11CF-96B8-444553540000';
	this.codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab';	// http://uniplayer.overdesign.net/install/Flash.cab
	this.pluginspage = 'http://www.macromedia.com/go/getflashplayer';
	this.mime = 'application/x-shockwave-flash';
	this.supported = [
		//-- audio
		'audio/mpeg',
		//'audio/aac',
		//'audio/aacp',
		//-- video
		'video/flv',
		'application/x-shockwave-flash',
		'video/mp4'
	];
	this.maxVolume = 100;
	this.duration = 0;
	this.position = 0;
	// build		http://developer.longtailvideo.com/trac/wiki/FlashVars
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			height+= 20;
		}
		// create object
		var swf = (conf && conf.swf) ? conf.swf : 'http://uniplayer.overdesign.net/components/jwplayer/player.swf';
		if(!this.player.options.id){
			this.player.options.id = 'uniplayer_' + this.name + '_' + Math.floor(Math.random()*100000000);	// jwplayer needs the ID to work correctly in IE
		}
		var obj = new this.player.UniplayerObject({
			id:	this.player.options.id,
			src: swf,
			width: this.player.options.width,
			height: height,
			type: 'application/x-shockwave-flash',
			classid: this.classid,
			codebase: this.codebase,
			pluginspage: this.pluginspage
		});
		obj.addParam('movie', swf, true);
		obj.addParam('quality', 'high');
		obj.addParam('wmode', 'opaque');
		obj.addParam('allowfullscreen', true);
		obj.addParam('allowscriptaccess', 'always');
		var flashvars = 'file='+escape(this.player.current.src);
		flashvars+= '&id='+this.player.options.id;
		flashvars+= '&controlbar='+(this.player.options.showNativeControls?'bottom':'none');
		flashvars+= '&autostart='+(this.player.options.autoplay?'true':'false');
		flashvars+= '&volume='+this.player.options.volume*this.maxVolume;
		if(!this.player.options.showNativeControls){
			flashvars+= '&displayclick=fullscreen';
		}
		if(this.player.options.background){
			flashvars+= '&screencolor=' + this.player.options.background;
			obj.addParam('bgcolor', this.player.options.background);
		}
		if(conf && conf.flashvars){
			for(var i in conf.flashvars){
				flashvars+= '&' + i + '=' + conf.flashvars[i];
			}
		}
		obj.addParam('flashvars', flashvars);
		this.movie = obj.write(this.player.holders.movie);
		delete obj;
		// event time is only way to get jw flv player's position and duration
		var self = this;
		window.playerReady = function(obj){
			if(obj.id != self.player.options.id){return;}
			window[self.player.options.id + '_onPositionChange'] = function(obj){
				self.duration = obj.duration;
				self.position = self.duration ? obj.position/self.duration : 0;
			};
			self.player.current.movie.addModelListener('TIME', self.player.options.id + '_onPositionChange');
			delete window.playerReady;
		};
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		return this.movie;
	};
	// controls		http://developer.longtailvideo.com/trac/wiki/FlashVars
	this.getVersion = function(){
		return this.player.current.movie.getConfig().version;
	};
	this.getState = function(){
		var state = this.player.current.movie.getConfig().state;
		var currentState = this.player.current.state;
		switch(state){
			case 'BUFFERING':
				currentState = this.player.states.loading;
				break;
			case 'PLAYING':
				currentState = this.player.states.playing;
				break;
			case 'PAUSED':
				currentState = this.player.states.paused;
				break;
			case 'IDLE':
			case 'COMPLETED':
				currentState = this.player.states.stopped;
				break;
			default:
				currentState = this.player.states.stopped;
				break;
		}
		return currentState;
	};
	this.reload = function(){
		this.player.current.movie.sendEvent('LOAD', this.player.current.src);
	};
	this.play = function(){
		return this.player.current.movie.sendEvent('PLAY', true);
	};
	this.pause = function(){
		return this.player.current.movie.sendEvent('PLAY', false);
	};
	this.stop = function(){
		return this.player.current.movie.sendEvent('STOP');
	};
	this.fullScreen = function(){
		return this.player.pageScreen();
	};
	this.getMute = function(){
		return this.player.current.movie.getConfig().mute;
	};
	this.setMute = function(turn){
		return this.player.current.movie.sendEvent('MUTE', turn);
	};
	this.getVolume = function(){
		return this.player.current.movie.getConfig().volume/this.player.current.module.maxVolume;
	};
	this.setVolume = function(volume){
		return this.player.current.movie.sendEvent('VOLUME', volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		return this.duration;
	};
	this.getPosition = function(){
		return this.position;
	};
	this.setPosition = function(position){
		return this.player.current.movie.sendEvent('SEEK', position*this.player.current.duration);
	};
};








UniplayerFlashFlowplayer = function(conf){
	/*
		KNOWN ISSUES
		
		- no javascript control for fullScreen due to flash security restrictions
	*/
	this.name = 'flashflow';
	this.title = 'Flash Flowplayer';
	this.needle = 'Flash';
	this.progid = 'ShockwaveFlash.ShockwaveFlash';
	this.classid = 'clsid:D27CDB6E-AE6D-11CF-96B8-444553540000';
	this.codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab';	// http://uniplayer.overdesign.net/install/Flash.cab
	this.pluginspage = 'http://www.macromedia.com/go/getflashplayer';
	this.mime = 'application/x-shockwave-flash';
	this.supported = [
		//-- audio
		'audio/mpeg',
		//'audio/aac',
		//'audio/aacp',
		//-- video
		'video/flv',
		'application/x-shockwave-flash',
		'video/mp4'
	];
	this.maxVolume = 100;
	this.duration = 0;
	this.position = 0;
	this.mute = false;
	var fp;
	// build		http://flowplayer.org/documentation/configuration/index.html
	this.build = function(){
		// show native controls
		var height = this.player.options.height;
		if(this.player.options.showNativeControls){
			height+= 24;
		}
		// create object
		var swf = (conf && conf.swf) ? conf.swf : 'http://uniplayer.overdesign.net/components/flowplayer/flowplayer-3.1.0.swf';
		if(!this.player.options.id){
			this.player.options.id = 'uniplayer_' + this.name + '_' + Math.floor(Math.random()*100000000);	// flowplayer needs an ID
		}
		this.player.holders.movie.innerHTML = '';	// because of flowplayer's bug
		fp = flowplayer(this.player.holders.movie, swf, {
			'playerId': this.player.options.id,
			clip: {
				url: this.player.current.src,
				autoPlay: this.player.options.autoplay
			},
			plugins: {
				controls: {
					display: this.player.options.showNativeControls ? 'block' : 'none'
				}
			}
		});
		this.movie = this.player.holders.movie.firstChild;
		this.player.current.width = this.player.options.width;
		this.player.current.height = height;
		this.movie.width = this.player.current.width;
		this.movie.height = this.player.current.height;
		return this.movie;
	};
	// controls		http://flowplayer.org/documentation/api/flowplayer.html
	this.getVersion = function(){
		return fp.getVersion().splice(0, 3).join('.');
	};
	this.getState = function(){
		var currentState = this.player.current.state;
		switch(fp.getState()){
			case 2:
				currentState = this.player.states.loading;
				break;
			case 3:
				currentState = this.player.states.playing;
				break;
			case 4:
				currentState = this.player.states.paused;
				break;
			case -1:
			case 0:
			case 1:
			case 5:
				currentState = this.player.states.stopped;
				break;
			default:
				currentState = this.player.states.stopped;
				break;
		}
		return currentState;
	};
	this.reload = function(){
		this.stop();
		return fp.getClip().update({url: this.player.current.src});
		if(this.player.options.autoplay){
			fp.play();
		}
	};
	this.play = function(){
    /*if(this.player.options.noCache){
      var url = this.player.current.src + (this.player.current.src.indexOf('?') >= 0 ? '&' : '?') + 'seed=' + Math.floor(Math.random()*100000000);
      alert(url);
      fp.getClip().update({url: url});
    }*/
		return fp.play();
	};
	this.pause = function(){
		return fp.pause();
	};
	this.stop = function(){
		return fp.stopBuffering().stop();
	};
	this.fullScreen = function(){
		return this.player.pageScreen();
	};
	this.getMute = function(){
		return fp.getStatus().muted;
	};
	this.setMute = function(turn){
		return turn ? fp.mute() : fp.unmute();
	};
	this.getVolume = function(){
		return fp.getVolume()/this.player.current.module.maxVolume;
	};
	this.setVolume = function(volume){
		return fp.setVolume(volume*this.player.current.module.maxVolume);
	};
	this.getDuration = function(){
		return fp.getClip().fullDuration;
	};
	this.getPosition = function(){
		var position = fp.getTime();
		return (isNaN(position) || !this.player.current.duration) ? 0 : position/this.player.current.duration;
	};
	this.setPosition = function(position){
		return fp.seek(position*this.player.current.duration);
	};
};
