// Namespace AVP : Accessible Video Player
var AVP = (function($){
	var id = 0;
	var isiPad = navigator.userAgent.match(/iPad/i) != null;
	
	
    // Object Proxy
    var Proxy = function(){
        return {
            dispatchEvent : function(eventName, params){ $(this).trigger(eventName, params);}
			, render : function(el){}
			, play : function(){}
			, pause : function(){}
			, stop : function(){}
			, upVolume : function(){}
			, downVolume : function(){}
			, setVolume : function(percentageVolume){}
			, videoForward : function(){}
			, videoBack : function(){}
        }
    }
	
	
	// Object ProxyHTML5 extends Proxy
    var ProxyHTML5 = function(options){
        var thisProxy = Proxy();
		var player = null;
		var asProgressed = false;
        
		thisProxy.asProgressed = function(){
			var returnProgress = asProgressed;
			asProgressed = true;
			return returnProgress;
		}
		
		thisProxy.render = function(el){
			$el = $(el);
			
			player = $('<video id="myvideo" width="'+options.width+'" height="'+options.height+'" poster="'+options.poster+'"/>')[0];
				var ogv = '';
				var mp4 = '';
				if(options.videoOgg){ ogv = $('<source type="video/ogg" src="'+ options.videoOgg +'"></source>')}
				if(options.videoMP4){ mp4 = $('<source type="video/mp4" src="'+ options.videoMP4 +'"></source>')}
				$(player).append(ogv, mp4)
			$el.append(player);
			
			var events = [
				{name: 'play', callback: function(){ thisProxy.dispatchEvent('videoPlay');}	 } 
				, {name: 'pause', callback: function(){thisProxy.dispatchEvent('videoPause');}}
				, {name: 'ended', callback: function(){ thisProxy.stop() }}
				, {name: 'timeupdate', callback: function(){ if(thisProxy.asProgressed() === false){ thisProxy.dispatchEvent('noProgressEvent'); }; thisProxy.dispatchEvent('videoRunningTime', player.currentTime); }}
				, {name: 'durationchange', callback: function(){ thisProxy.dispatchEvent('videoTotalTime', player.duration); }}
				, {name: 'volumechange', callback: function(){  thisProxy.dispatchEvent('videoMute', player.muted); if(player.muted){var volume = 0}else{var volume = player.volume*100} thisProxy.dispatchEvent('videoVolume', volume); }}
				, {name: 'progress', callback: function(e){ thisProxy.asProgressed(); if(e.loaded == undefined ){thisProxy.dispatchEvent('noProgressEvent');}; var percent = (e.loaded / e.total) *100; thisProxy.dispatchEvent('videoLoad', percent); }}
			];
			// Attach events to player
			$(events).each(function(index,el){
				player.addEventListener(el.name, el.callback, false);
			})
			
			// Add click to video to play/pause it, like in the Flash Player
			// Validate if no controls are display in HTML5, 
			//    else we can't use the HTML5 video controlbar...
			$(player).click(function(){
				if(!$(player).attr('controls')){
					if(player.paused){
						thisProxy.play();
					}else{
						thisProxy.pause();
					}
				}
			});
			
			thisProxy.setVolume(options.volume);
			
		}
		thisProxy.play = function(){
			player.play();
		}
		thisProxy.pause = function(){
			player.pause();
		}
		thisProxy.stop = function(){
			player.currentTime = 0
			player.pause();
			thisProxy.dispatchEvent('videoPause');
			thisProxy.dispatchEvent('videoStop');
		}
		thisProxy.upVolume = function(){
			var step = options.volumeStep
			var volume = (player.volume)*100 + step
			if(volume > 100){volume = 100;}
			thisProxy.setVolume(volume);
		}
		thisProxy.downVolume = function(){
			var step = options.volumeStep
			var volume = (player.volume*100) - step
			if(volume < 0){volume = 0;}
			thisProxy.setVolume(volume);
		}
		thisProxy.setVolume = function(percentageVolume){
			player.volume = parseFloat(percentageVolume/100);
		}
		thisProxy.setMute = function(muteIt){
			player.muted = muteIt;
		}
		thisProxy.videoForward = function(){
			if(!player.paused){
				var step = options.videoStep;
				var time = player.currentTime + step;
				// Ne pas avancer si on est plus loin que la fin du vidéo...
				if(time < player.duration){
					player.currentTime = time;
				}
			}
		}
		thisProxy.videoBack = function(){
			if(!player.paused){
				var step = options.videoStep;
				var time = player.currentTime - step;
				if(time < 0){
					time = 0;
				}
				player.currentTime = time
			}
		}
		
		thisProxy.seekToPercentage = function(percentage){
			var duration = player.duration;
			var time = duration * (percentage /100);
			player.currentTime = time;
		}
		
        return thisProxy;
    }
    
	
	
	
	// Object ProxyFlash extends Proxy
    var ProxyFlash = function(options){
        var thisProxy = Proxy();
		var player = null;

		thisProxy.render = function(el){
				player = jwplayer(el).setup({
					flashplayer: options.flvPlayerSwf
					, file: (options.videoFlv || options.videoMP4)
					, height: options.height
					, width: options.width
					, image : options.poster
					, icons :false
					, controlbar : 'none'
				});
				
				player.onPlay(function(){thisProxy.dispatchEvent('videoPlay');})
				      .onPause(function(){thisProxy.dispatchEvent('videoPause');})
				      .onComplete(function(){ thisProxy.stop(); })
				      .onTime(function(e){ if(e.position){ thisProxy.dispatchEvent('videoRunningTime', e.position); }})
				      .onVolume(function(e){ if(!isNaN(e.volume)){ thisProxy.dispatchEvent('videoVolume', e.volume); }})
					  .onMute(function(e){ thisProxy.dispatchEvent('videoMute', e.mute); })
					  .onBufferChange(function(e){if(e.metadata){ var percent = (e.metadata.loaded / e.metadata.total)*100; thisProxy.dispatchEvent('videoLoad', percent);}})
					  
				// Documentation of jwplayer specify onMetadata... but does'nt work... work with onMeta... Let him decide!
				if(player.onMeta){
					player.onMeta(function(e){ if(e.metadata.duration){ thisProxy.dispatchEvent('videoTotalTime', e.metadata.duration); }})
				}else if(player.onMetadata){
					player.onMetadata(function(e){if(e.metadata.duration){ thisProxy.dispatchEvent('videoTotalTime', e.metadata.duration); }})
				}
				
				
				thisProxy.setVolume(options.volume);
		}
		
		thisProxy.play = function(){
			player.play(true);
		}
		
		thisProxy.pause = function(){
			if(player.getState() == 'PLAYING'){
				player.pause(true);
			}
		}
		
		thisProxy.stop = function(){
			if(player.getState() == 'PLAYING'){
            	player.pause(true)
            }
			player.stop();
			thisProxy.dispatchEvent('videoPause');
			thisProxy.dispatchEvent('videoStop');
			thisProxy.dispatchEvent('videoRunningTime', 0);
		}
		
		thisProxy.upVolume = function(){
			var step = options.volumeStep;
			var volume = player.getVolume();
			volume = volume + step;
			if(volume > 100){ volume = 100; }
			thisProxy.setVolume(volume);	
		}
		thisProxy.downVolume = function(){
			var step = options.volumeStep;
			var volume = player.getVolume();
			volume = volume - step;
			if(volume < 0){ volume = 0; }
			thisProxy.setVolume(volume);
		}
		thisProxy.setVolume = function(percentageVolume){
			player.setVolume(percentageVolume);
		}
		thisProxy.setMute = function(muteId){
			player.setMute(muteId);
		}
		thisProxy.videoForward = function(){
			if(player.getState() == 'PLAYING'){
				var step = options.videoStep;
				var time = player.getPosition() + step;
				// Ne pas avancer si on est plus loin que la fin du vidéo...
				if(time < player.getDuration()){
					player.seek(time)
				}
			}
		}
		
		thisProxy.videoBack = function(){
			if(player.getState() == 'PLAYING'){
				var step = options.videoStep;
				var time = player.getPosition() - step;
				if(time < 0){time = 0;}
				player.seek(time)
			}
		}
		
		thisProxy.seekToPercentage = function(percentage){
			var duration = player.getDuration()
			var time = duration * (percentage /100);
			player.seek(time);
		}
		
        return thisProxy;
    }
	
	
	
	
	// Object Controlbar
	var Controlbar = function(options){
		var lbls = options.buttonsLabel;
		var els = {};
		var totalTime = 0;
		var runningTime = 0;
		
		// Params of the possible buttons/objects for Controlbar
		var confEls = {
			'play'         : {type: button, label: lbls.playBtn,  className:'play',  eventName:'clickPlay' }
			, 'pause'      : {type: button, label: lbls.pauseBtn, className:'pause', eventName:'clickPause'}
			, 'stop'       : {type: button, label: lbls.stopBtn,  className:'stop',  eventName:'clickStop' }
			, 'volumeUp'   : {type: button, label: lbls.volumeUpBtn,  className:'volumeUp',  eventName:'clickVolumeUp' }
			, 'volumeDown' : {type: button, label: lbls.volumeDownBtn,  className:'volumeDown',  eventName:'clickVolumeDown' }
			, 'forward'    : {type: button, label: lbls.forwardBtn,  className:'forward',  eventName:'clickForward' }
			, 'back'       : {type: button, label: lbls.backBtn,  className:'back',  eventName:'clickBack' }
			, 'mute'       : {type: button, label: lbls.muteBtn,  className:'mute',  eventName:'clickMute' }
			, 'unmute'     : {type: button, label: lbls.unmuteBtn,  className:'unmute',  eventName:'clickUnmute' }
			, 'totalTime'  : {type: label, label: '', className:'totalTime', eventName :null}
			, 'runningTime': {type: label, label: '', className:'runningTime', eventName :null}
			, 'timer'      : {type: label, label: '', className:'timer', eventName :null}
			, 'videoSlider': {type: videoSlider, label: '', className:'videoSlider', eventName :'slideTime'}
			, 'volumeSlider': {type: volumeSlider, label: '', className:'volumeSlider', eventName :'slideVolume'}
			, '|': {type: separator, label: '', className:'separator', eventName :null}
		}
		
		
		// Function to create a button
		function button(label, className, eventName, parent){
			var btn = $('<button class="avp-btn avp-'+className+'-btn"><span class="avp-btn-label"><span class="avp-btn-icon-prev"></span><span class="avp-btn-label-text">'+label+'</span><span class="avp-btn-icon-next"></span></span></button>');
			if(eventName){
				btn.click( $.proxy( function(){ this.trigger(eventName); }, $(parent)));
			}
			btn.focus(function(){
				btn.addClass('avp-'+className+'-btn-focus avp-btn-focus');
			})
			btn.blur(function(){
				btn.removeClass('avp-'+className+'-btn-focus avp-btn-focus');
			})
			btn.mouseover(function(){
				btn.addClass('avp-'+className+'-btn-hover avp-btn-hover');
			})
			btn.mouseout(function(){
				btn.removeClass('avp-'+className+'-btn-hover avp-btn-hover');
			})
			return btn;
		}
		
		// Fucntion to create a "label". Mostly for time things...
		function label(label, className, eventName, parent){
			var lbl = $('<span class="avp-label avp-'+className+'-label"><span class="avp-label-label"><span class="avp-label-icon-prev"></span><span class="avp-label-label-text">'+label+'</span><span class="avp-label-icon-next"></span></span></span>')
			return lbl;
		}
		
		function volumeSlider(label, className, eventName, parent){
			var zoneSlider = $('<span class="avp-slider avp-'+className+'-slider"><span class="avp-slider-zone"/></span>');
			var slide = new slideScrub(zoneSlider.find('.avp-slider-zone'), parent, eventName);
			zoneSlider.find('.avp-slider-zone').append(slide);
			return zoneSlider;
		}
		
		function videoSlider(label, className, eventName, parent){
			var zoneSlider = $('<span class="avp-slider avp-'+className+'-slider"><span class="avp-slider-zone"><span class="avp-slider-zone-loaded"/></span></span>');
			var slide = new slideScrub(zoneSlider.find('.avp-slider-zone'), parent, eventName);
			zoneSlider.find('.avp-slider-zone-loaded').append(slide);
			if(options.backForwardInSlider){
					var grpBackForward = $('<span class="avp-'+className+'-slider-backforward" />');
					
					var conf = confEls['back'];
					var el = new conf.type(conf.label, conf.className, conf.eventName, parent);
					var conf2 = confEls['forward'];
					var el2 = new conf2.type(conf2.label, conf2.className, conf2.eventName, parent);
					
					function focusGroup(e){ $(e.target).parent().addClass('avp-'+className+'-slider-backforward-focus')}
					function blurGroup(e){ $(e.target).parent().removeClass('avp-'+className+'-slider-backforward-focus')}
					el.bind('focus', focusGroup)
					el2.bind('focus', focusGroup)
					el.bind('blur', blurGroup)
					el2.bind('blur', blurGroup)
					
					grpBackForward.append(el, el2);
					slide.append(grpBackForward);
			}
			return zoneSlider;
		}
		
		this.setNoLoading = function(){
			if(els['videoSlider']){
				els['videoSlider'].find('.avp-slider-zone-loaded').addClass('avp-slider-zone-loaded-never');
			}
		}
		
		function slideScrub(totalZone, parent, eventName){
			var scrub = $('<span class="avp-slider-scrub"/>');

			
			scrub.mousedown(function(e){
				var target = $(e.target);
				var cursorX = e.pageX;
				var diff = target.position().left - cursorX;
				$(parent).trigger( eventName +'Start' );
				els['videoSlider'].data('isScrubbing', true);
				
				$(document).bind('mousemove.scrub',function(e){
					e.preventDefault();
					var pos = e.pageX + diff;
					var widthParent = target.parent().innerWidth() - target.outerWidth();
					if(pos < 0){ pos = 0;}
					if(pos > widthParent){ pos = widthParent; }
					target.css('left', pos);
					var percent = (pos / (totalZone.innerWidth() - target.outerWidth())) *100;
					
					$(parent).trigger( eventName, percent );
				})
				$(document).mouseup(function(){els['videoSlider'].data('isScrubbing', false); $(parent).trigger( eventName +'End' ); $(document).unbind('mousemove.scrub').unbind('mouseup')});
			});
			
			return scrub;
		}
		
		function separator(label, className, eventName, parent){
			var zoneSlider = $('<span class="avp-'+className+'"></span>');
			return zoneSlider;
		}
		
		this.setRunningTime = function(timeInSec){
			runningTime = timeInSec;
			if(els['runningTime']){
				els['runningTime'].find('.avp-label-label-text').html(formatTime(runningTime));
			}
			updateTimer();
		}
		this.setTotalTime = function(timeInSec){
			totalTime = timeInSec;
			if(els['totalTime']){
				els['totalTime'].find('.avp-label-label-text').html(formatTime(totalTime));
			}
			updateTimer();
		}
		
		var updateTimer = function(){
			if(els['timer']){
				els['timer'].find('.avp-label-label-text').html(formatTime(runningTime)+'/'+formatTime(totalTime));
			}
			
			if(els['videoSlider'] && els['videoSlider'].data('isScrubbing') !== true){
				var total = els['videoSlider'].find('.avp-slider-zone').innerWidth() - els['videoSlider'].find('.avp-slider-scrub').outerWidth();
				if(totalTime != 0){
					var percent = runningTime / totalTime;
				}else{
					var percent = 0
				}
				position =  total * percent;
				els['videoSlider'].find('.avp-slider-scrub').css('left', position);
			}
		}
		
		this.updateLoaded = function(percentage){
			if(els['videoSlider']){
				els['videoSlider'].find('.avp-slider-zone-loaded').width(percentage+'%');;
			}
		}
		
		this.updateVolume = function(percentage){
			if(els['volumeSlider'] && !els['volumeSlider'].find('.avp-slider-scrub').data('isScrubbing')){
				var total = els['volumeSlider'].find('.avp-slider-zone').innerWidth() - els['volumeSlider'].find('.avp-slider-scrub').outerWidth();
				position =  total * (percentage/100);
				els['volumeSlider'].find('.avp-slider-scrub').css('left', position);
			}
		}
		
		var formatTime = function(timeInSec){
			var durationMinutes = Math.floor(timeInSec / 60);
			var durationSeconds = Math.floor(timeInSec % 60);
			
			if(durationSeconds < 10){
				durationSeconds = "0" + durationSeconds;
			}
			if(durationMinutes < 10){
				durationMinutes = "0" + durationMinutes;
			}
			
			return durationMinutes + ':' + durationSeconds
		}
		
		this.toggle = function(toHide, toShow){
			if(els[toHide] && els[toShow]){
				if(els[toHide].data('shouldToggle') || els[toShow].data('shouldToggle')){
					els[toHide].hide();
					els[toShow].show();
					if(els[toHide].hasClass('avp-btn-focus')){
						els[toHide].blur();
						els[toShow].focus();
					}
				}
			}
		}
		
		var disableSelection = function(el) {
			return el.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
				".ui-disableSelection", function( event ) {
					event.preventDefault();
				});
		}
	
		var enableSelection = function(el) {
			return el.unbind( ".ui-disableSelection" );
		}
		
		// Create the controlbar
		var controlbar = $('<div class="avp-controlbar"/>');
		disableSelection(controlbar);
		for(var i = 0; i < options.buttons.length; i++){
			var buttonsList = options.buttons[i];
			var controlbarPart = $('<div class="avp-controlbar-part'+i+'"/>')
			for(var j =0; j < buttonsList.length; j++){
				if(typeof buttonsList[j] != 'object'){
					var elName = buttonsList[j];
					var conf = confEls[elName];
					if((!els[elName] || elName == '|')&& conf){
						var el = new conf.type(conf.label, conf.className, conf.eventName, this);
						els[elName] = el;
						controlbarPart.append(el);
					}
				}else{
					var elName = buttonsList[j].name;
					var conf = $.extend({type: button}, buttonsList[j]);
					var el = new conf.type(conf.label, conf.className, conf.eventName, this);
					if(conf.toggle){
						el.data('shouldToggle',true);
					}
					els[elName] = el;
					controlbarPart.append(el);
				}
			}
			controlbar.append(controlbarPart);
		}
		
		if(options.togglePlayPause && els['play'] && els['pause']){
			els['play'].data('shouldToggle',true);
			this.toggle('pause', 'play');
		}
		if(options.toggleMuteUnmute && els['mute'] && els['unmute']){
			els['mute'].data('shouldToggle',true);
			this.toggle('unmute', 'mute');
		}
		
		this.setTotalTime(options.totalTime);
		this.setRunningTime(0);
		
		var html = controlbar;
		
		this.render = function($el){
			$el.append(html);
			if(options.videoSlideAutowidth && els['videoSlider']){
				els['videoSlider'].css('width',0);
				var part1 = els['videoSlider'].parent().outerWidth();
				var part2 = els['videoSlider'].parent().siblings().outerWidth();
				var width = els['videoSlider'].parent().parent().outerWidth() - (part1 + part2)
				els['videoSlider'].css('width', width);
				
			}
		}
		
		return this;
	}




	// Object PlayerController to bind player Proxy and Controlbar
	var PlayerController = function(proxy, controlbar){
		$proxy = $(proxy);
		$controlbar = $(controlbar);
		var id = controlbar.id;
		
		$controlbar.bind('clickPlay.'+id, function(e){ proxy.play(); })
		$controlbar.bind('clickPause.'+id, function(e){ proxy.pause(); })
		$controlbar.bind('clickStop.'+id, function(e){ proxy.stop(); })
		$controlbar.bind('clickVolumeUp.'+id, function(e){ proxy.upVolume(); })
		$controlbar.bind('clickVolumeDown.'+id, function(e){ proxy.downVolume(); })
		$controlbar.bind('clickForward.'+id, function(e){ proxy.videoForward(); })
		$controlbar.bind('clickBack.'+id, function(e){ proxy.videoBack(); })
		$controlbar.bind('clickMute.'+id, function(e){ proxy.setMute(true); })
		$controlbar.bind('clickUnmute.'+id, function(e){ proxy.setMute(false); })
		$controlbar.bind('slideTime.'+id, function(e, percent){ proxy.seekToPercentage(percent); })
		$controlbar.bind('slideVolume.'+id, function(e, percent){ proxy.setVolume(percent); proxy.setMute(false); })
		
		
		$proxy.bind('videoPlay.'+id, function(e){ controlbar.toggle('play', 'pause'); })
		$proxy.bind('videoPause.'+id, function(e){ controlbar.toggle('pause', 'play'); })
		$proxy.bind('videoMute.'+id, function(e, muted){ if(muted){controlbar.toggle('mute', 'unmute');}else{controlbar.toggle('unmute', 'mute');} })
		$proxy.bind('videoRunningTime.'+id, function(e, timeInSec){ controlbar.setRunningTime(timeInSec); });
		$proxy.bind('videoTotalTime.'+id, function(e, timeInSec){ controlbar.setTotalTime(timeInSec); });
		$proxy.bind('videoStop.'+id, function(e){ controlbar.setRunningTime(0); })
		$proxy.bind('videoLoad.'+id, function(e, percentage){  controlbar.updateLoaded(percentage) })
		$proxy.bind('videoVolume.'+id, function(e, percentage){ controlbar.updateVolume(percentage) })
		$proxy.bind('noProgressEvent.'+id, function(e){ controlbar.setNoLoading() })
		
		
		this.unbind = function(){
			$proxy.unbind('.'+id);
			$controlbar.unbind('.'+id);
		}
	}
	
	// Function to get the good Proxy, dependant of the options
	function getProxy(options){
		var defaultProxy = options.defaultProxy;
		var proxy = false;
		
		if(defaultProxy == 'Flash'){
			if(jwplayer.utils.hasFlash() && (options.videoFlv || options.videoMP4)){
				proxy = new ProxyFlash(options);
			}else{ 
				var supportHTML5 = detectHTML5VideoSupport();
				if((supportHTML5.mp4 && options.videoMP4) || (supportHTML5.ogg && options.videoOgg)){
					proxy = new ProxyHTML5(options);
				}
			}
		}
		
		if(defaultProxy == 'HTML5'){
			var supportHTML5 = detectHTML5VideoSupport();
			if((supportHTML5.mp4 && options.videoMP4) || (supportHTML5.ogg && options.videoOgg)){
				proxy = new ProxyHTML5(options);
			}else{
				if(jwplayer.utils.hasFlash() && (options.videoFlv || options.videoMP4)){
					proxy = new ProxyFlash(options);
				}
			}
		}
		
		return proxy;
	}

	// Function to detect the HTML5 video capability
	var detectHTML5VideoSupport = function(){
		if(!this.HTML5VideoSupport){
			var detect = document.createElement('video') || false;
			
			var html5 = detect && typeof detect.canPlayType !== "undefined";
			var mp4 = html5 && (detect.canPlayType("video/mp4") === "maybe" || detect.canPlayType("video/mp4") === "probably");
			var ogg = html5 && (detect.canPlayType("video/ogg") === "maybe" || detect.canPlayType("video/ogg") === "probably");
			
			this.HTML5VideoSupport = { html5:html5, mp4:mp4, ogg:ogg };
		}
		
		return this.HTML5VideoSupport;
	};
	
	
	var videoDefaultsOptions = {
		defaultProxy : 'Flash'
		, width: 480
		, height: 360
		, flvPlayerSwf : 'player-5.3.swf'
		, videoFlv : false
		, videoOgg : false
		, videoMP4 : false
		, poster : false
		, volume : 50 // sur 100
		, volumeStep : 10 // sur 100
		, videoStep: 10 // en secondes
	};
	
	var controlbarDefaultOptions = {
		togglePlayPause: true
		, toggleMuteUnmute: true
		, buttonInsideVideoSlide: true
		, videoSlideAutowidth : true
		, backForwardInSlider : true
		, totalTime : 0
		, buttonsLabel : {
			playBtn          : "Lire"
			, pauseBtn         : "Pause"
			, stopBtn          : "Revenir au début"
			, muteBtn          : "Fermer le volume"
			, unmuteBtn        : "Ouvrir le volume"
			, forwardBtn       : "Avancer de 10 secondes"
			, backBtn          : "Reculer de 10 secondes"
			, volumeDownBtn    : "Diminuer le volume de 10%"
			, volumeUpBtn      : "Augmenter le volume de 10%"
			}
	};
	
	function changeControlbarDefaultOptions(options){
		controlbarDefaultOptions = $.extend(true, controlbarDefaultOptions, options);
	}
	
	// Function to create an Accessible Video Player
	function createPlayer(options){
		// extends change le premier item...
		options = $.extend(true, {}, videoDefaultsOptions, options);
		// Create the Player via Proxy
		var proxy = getProxy(options);
		// Render the player
		function renderPlayer($el){
			if(proxy){
				$el.empty();
				var playerDiv = $('<div id="AVP_Player_proxy_'+(id++)+'"/>')
					$el.append(playerDiv);
					proxy.render(playerDiv[0]);
				$el.css('width', options.width)
			}
		}
		
		return {
			proxy : proxy
			, render : renderPlayer
		};
	}
	
	var idControlbar = 0;
	
	function createControlbar(options, buttonsList){
		var controlbar = {render:function(){}};
		// fonctionne pas:
		options = $.extend(true, {}, controlbarDefaultOptions, options);
		$.extend(options, {buttons:buttonsList})

		var controlbar = new Controlbar(options);
		controlbar.id = 'controlbar'+ (idControlbar++);
		
		controlbar.playerController = null;
		
		controlbar.detachPlayer = function(){
			if(controlbar.playerController){
				controlbar.playerController.unbind();
				controlbar.playerController = null;
			}
		}
		controlbar.attachPlayer = function(player){
			controlbar.detachPlayer();
			controlbar.playerController = new PlayerController(player.proxy, controlbar);
		}
		
		return controlbar;
	}
	
	function changeVideoDefaultsOptions(options){
		videoDefaultsOptions = $.extend(true, videoDefaultsOptions, options);
	}
	
	function createSubtitle(jsonFile){
		var subtitle = {}
		    subtitle.texts = [];
		var subtitleDiv = $('<div class="avp-subtitle-zone" />')
		var zoneText = $('<div class="avp-subtitle-zone-text" />');
			subtitleDiv.append(zoneText);
		var active = false;
			
		var convertTimeToSec = function(time){
			var parts = time.split(':');
			parts.reverse();
			var timeInSec = 0;
			$(parts).each(function(index,el){
				var mult = (index * 60);
				var t = parseFloat(el);
				
				if(mult != 0){
					var t = t * mult;
				}   
				timeInSec += t;
			});
			
			return timeInSec;
		}
		var processSubtitle = function(data){
			
			$(data).each(function(index, el){
				var start = convertTimeToSec(el.begin);
				var end = convertTimeToSec(el.end);
				var theText = el.text;
				
				subtitle.texts.push({
									start: start
									, end: end
									, theText: theText
				});
			})
			subtitle.texts = $(subtitle.texts);
		}
		
		$.ajax({url:jsonFile, dataType:'json', success : processSubtitle});
		
		subtitle.render = function($el){
			$el.append(subtitleDiv);
		}
		subtitle.show = function(){
			subtitleDiv.addClass('avp-subtitle-zone-visible');
			active = true;
		};
		subtitle.hide = function(){
			subtitleDiv.removeClass('avp-subtitle-zone-visible');
			zoneText.empty();
			active = false;
		};
		
		subtitle.display = function(timeInSec){
			if(active){
				var html = findText(timeInSec);
				if(html != zoneText.html()){
					zoneText.empty();
					zoneText.append(html.html());
				}
			}
		}
		
		var findText = function(timeInSec){
			var html = $('<div />');
			subtitle.texts.each(function(index,el){
				if(el.start < timeInSec && el.end > timeInSec){
					html.append( el.theText );
				}
			});
			return html;
		}
		
		return subtitle;
	}
    

	// AVP Namespace
    return {
		createPlayer : createPlayer
		, createControlbar : createControlbar
		, changeVideoDefaultsOptions : changeVideoDefaultsOptions
		, changeControlbarDefaultOptions : changeControlbarDefaultOptions
		, createSubtitle : createSubtitle
		, isIpad : function(){ return isiPad; }
	};
})(jQuery)

jQuery(function(){
// Reset the player... disable browser cache...
$(window).bind('unload', function(){  })

});
