(function($) {

	var g_anv_pl_cnt = 0;
	var g_ipad = (navigator.userAgent.match(/(iPhone|iPod|iPad)/i));
	function hesc ( s )
	{
		return s.split("&").join("&amp;").split( "<").join("&lt;").split(">").join("&gt;");
	}
	
	// =======================
	// Create player
	// =======================
	$.fn.anvplayer = function ( pars ) {
		
		if ( !pars.skinpath )
			pars.skinpath = '../assets/skins/anvato';
			
		return this.each(function() {
			var vp = $(this);
			
			this.load_playlist = function ( playlist, autoplay ) {
				load_playlist ( vp, playlist, autoplay );
			};

			vp.g_pars = pars;

			// widxht are clipped if too small
			vp.g_wid = Math.max(320, pars.width);
			vp.g_ht = Math.max(120, pars.height);
			
			// state machine
			vp.g_state = 'init';
			
			// a unique anvpalyer id for this embedding
			vp.idp = 'anvp'+g_anv_pl_cnt+'_';
			g_anv_pl_cnt++;

			// which video is being played
			vp.g_cur_video_url = '';
			
			vp.g_schedule_ctlbar_hide = 0;
			vp.g_last_digits = '';

			// write an empty container.
			var hs = '<div id="'+safe_id(vp,'container')+'" style="width:'+vp.g_wid+'px;height:'+vp.g_ht+'px;position:relative;background:black;font-family:tahoma,arial,helvetica,sans-serif"></div>';
			vp.html ( hs );
			
			// no playlist
			reset_playlist ( vp );

			// if a playlist is provided, load that
			if ( pars.playlist != null )
			{
				load_playlist ( vp, pars.playlist, pars.autoplay );
			}
		} );
	};
	
	// ======================
	// safe_id
	// ======================
	var safe_id = function ( vp, id )
	{
		return vp.idp+id;
	};

	// ======================
	// get_obj
	// ======================
	var get_obj = function ( vp, id )
	{
		return $('#'+vp.idp+id);
	};
	
	// ======================
	// get_vid
	// ======================
	var get_vid = function ( vp )
	{
		var vid = get_obj(vp,'avideo');

		if ( !vid.is('*') )
			return null;
		
		return vid[0];
	};

	// ======================
	// reset_playlist
	// ======================
	var reset_playlist = function  ( vp )
	{
		vp.g_cur_playlist = {info:{title:''}, items:[]};
	};
	
	// ======================
	// get_source_url
	// ======================
	function get_source_url ( vp )
	{
		return vp.g_cur_video_url;
	}
	
	// ======================
	// find_cur_playlist_idx
	// ======================
	function find_cur_playlist_idx ( vp )
	{
		var url = get_source_url ( vp );//get_obj(vp,'avideo').attr('src');
		
		// Find which one we are playing:
		for ( var i=0;i<vp.g_cur_playlist.items.length;i++ )
		{
			if ( vp.g_cur_playlist.items[i].video == url )
			{
				return i;
			}
		}

		return -1;
	}
	
	// ======================
	// time_fmt
	// ======================
	function time_fmt ( s )
	{
		if ( s== 0 || isNaN(s) )
			return '00:00';

		var h = Math.floor ( s/3600 );
		s -= h*3600;

		var m = Math.floor ( s/60 );
		s -= m*60;

		if ( h>0 )
		{
			return h.toString()+":"+(m<10?"0":"")+m.toString()+":"+(s<10?"0":"")+s.toString();
		}
		else
		{
			return (m<10?"0":"")+m.toString()+":"+(s<10?"0":"")+s.toString();
		}
	}

	// ======================
	// write_digits
	// ======================
	function write_digits ( vp, id, str )
	{
		var hs = '';
		for ( var i=0;i<str.length;i++ )
		{
			var wid = 6;
			var pos = 0;
			if ( str.charAt(i) == '/' )
				pos = -10;
			else if ( str.charAt(i) == ':' )
			{
				wid = 4;
				pos = -11;
			}
			else
				pos = -parseInt ( str.charAt(i) );

			pos *= 6;
				
			hs += '<div style=\'float:left;width:'+wid+'px;height:7px;background-position:'+pos+'px;background-image:url("'+vp.g_pars.skinpath+'/digits.png")\'></div>';
		}
		hs += '<div style="clear:both"></div>';
		
		get_obj(vp,id).html ( hs );
	};

	// ==============================
	// load_splash
	// ==============================
	function load_splash ( vp, item )
	{
		var hs = '<div id="'+safe_id(vp,'splash')+'" style="position:absolute;width:100%;height:100%;top:0px;left:0px">'+
					'<img style="display:inline;width:100%;height:100%;display:none;left:0px;top:0px;width:100%;height:100%" src="'+item.image+'" id="'+safe_id(vp,'splash_image_img')+'"/>'+
					'<div style="position:absolute;display: table-cell;vertical-align: middle;left:0;top:0;width:100%;height:100%;">'+
						'<table style="text-align:center;width:100%;height:100%;border:0px none;border-collapse:collapse">'+
							'<tr><td><img style="display:inline;" src="'+vp.g_pars.skinpath+'/OnScreenPlayBtn_En.png"  id="'+safe_id(vp,'splash_image_btn')+'"/></td></tr>'+
						'</table>'+
					'</div>'+
				 '</div>';

		get_obj ( vp,'container' ).html ( hs );
		get_obj ( vp,'splash_image_img').load ( function() {get_obj(vp,'splash_image_img').show ( );} );
		
		// javascript centering: (set to display:none; as default)
		//get_obj ( vp,'splash_image_btn').load ( function() {$(this).css({left:(vp.g_wid - $(this).width())/2+'px',top:(vp.g_ht - $(this).height())/2+'px'}); $(this).show ( );} );
		
		make_button ( vp, 'splash_image_btn', ''+vp.g_pars.skinpath+'/Splash_Flash.png', function(vp){ load_video_internal(vp, vp.g_splash_item);} );
		//get_obj ( vp,'splash_image_btn').click ( function() {load_video_internal(vp, vp.g_splash_item);} );
	}

	// ==============================
	// ==============================
	function busy_loading ( vp, msg )
	{
		vp.g_loading_cnt++;

		get_obj ( vp,'loading' ).remove();
		
		var hs = '<div id="'+safe_id(vp,'loading')+'" style="position:absolute;width:100%;height:100%;top:0px;left:0px">'+
					'<div id="'+safe_id(vp,'loading_message')+'" style="position:absolute;top: 4px;left:4px;font-weight:bold;font-size:10px;color:white"></div>'+
					'<div style="position:absolute;display: table-cell;vertical-align: middle;left:0;top:0;width:100%;height:100%;">'+
						'<table style="text-align:center;width:100%;height:100%;border:0px none;border-collapse:collapse">'+
							'<tr><td><img src="'+vp.g_pars.skinpath+'/loading.gif" style="display:inline"/></td></tr>'+
						'</table>'+
					'</div>'+
				 '</div>';

		get_obj ( vp,'container' ).append ( hs );
		get_obj ( vp,'loading_message').text ( msg );
	}
	
	// ==============================
	// ==============================
	function done_loading ( vp )
	{
		vp.g_loading_cnt--;
		
		// we may send multiple done_loading's to get rid of the icon, cnt may dip below 0.
		if ( vp.g_loading_cnt <= 0 )
		{
			force_done_loading ( vp );
		}
	}
	
	// ==============================
	// ==============================
	function force_done_loading ( vp )
	{
		vp.g_loading_cnt = 0;
		get_obj ( vp,'loading' ).remove();
	}

	// ==============================
	// ==============================
	var try_hide_ctlbar = function ( vp )
	{
		var now = new Date().getTime();
		if ( now < vp.g_schedule_ctlbar_hide )
		{
			time_out_ctlbar ( vp, 500 );
			return;
		}
		get_obj ( vp,'controlbar' ).remove();
	};
	
	// ==============================
	// ==============================
	function time_out_ctlbar ( vp, delay )
	{
		setTimeout ( function() { try_hide_ctlbar(vp); }, delay );
	}

	// ==============================
	// Handle control bar showing/hiding
	// ==============================
	function make_button ( vp, nm, img, func )
	{
		if ( g_ipad )
		{
			get_obj ( vp,nm ).bind ( "touchstart", function() {
				$(this).css ( {'background':'transparent url('+img+') repeat scroll 0 0' } );
			} );
			get_obj ( vp,nm ).bind ( "touchend", function() {
				$(this).css ( {'background':'none' } );
				func(vp);
			} );
		}
		else
		{
			get_obj ( vp,nm ).bind ( "mousedown", function() {
				$(this).css ( {'background':'transparent url('+img+') repeat scroll 0 0' } );
			} );
			get_obj ( vp,nm ).bind ( "mouseout", function() {
				$(this).css ( {'background':'none' } );
			} );
			get_obj ( vp,nm ).bind ( "mouseup", function() {
				$(this).css ( {'background':'none' } );
				func(vp);
			} );
		}
	}
	
	// ==============================
	// ==============================
	function display_seek_hint ( vp, pageX )
	{
		get_obj(vp,'seek_hint').remove();

		// hint to %100*d/w*dur
		var d = pageX - get_obj(vp,'player_posbar_cont').offset().left;
		var w = get_obj(vp,'player_posbar_cont').width();
		
		var str = '00:00';
		var vid = get_vid(vp);
		if ( vid && vid.duration>0 && w>0 )
			str = time_fmt(Math.round(vid.duration*d/w));

		var font_wid = 6;
		var box_wid = str.length * font_wid;
		
		var hs = '<div id="'+safe_id(vp,'seek_hint')+'" style="position:absolute;width:'+box_wid+'px;border:1px solid black;background:#441;color:black;left:'+(d-box_wid/2-2)+'px;padding:2px;font-size: 10px;font-weight: bold;bottom:11px">'+
				 '</div>';

		get_obj(vp, 'player_posbar_cont').append ( hs );
		write_digits ( vp, 'seek_hint', str );
	}
	
	// ==============================
	// ==============================
	function move_seek_hint ( vp, pageX )
	{
		// hint to %100*d/w*dur
		var d = pageX - get_obj(vp,'player_posbar_cont').offset().left;
		var w = get_obj(vp,'player_posbar_cont').width();

		var str = '00:00';
		var vid = get_vid(vp);
		if ( vid && w>0 )
			str = time_fmt(Math.round(vid.duration*d/w));

		var font_wid = 6;
		var box_wid = str.length * font_wid;

		get_obj(vp,'seek_hint').css ( { 'left' : (d-box_wid/2-2) } );
		write_digits ( vp, 'seek_hint', str );
	}
	
	// ==============================
	// ==============================
	function seek_player ( vp, pageX )
	{
		// hint to %100*d/w*dur
		var d = pageX - get_obj(vp,'player_posbar_cont').offset().left;
		var w = get_obj(vp,'player_posbar_cont').width();
		
		var vid = get_vid(vp);
		if ( vid && w>0 && !vid.seeking )
		{
			var pos = Math.round ( vid.duration * d / w );
			
			vid.currentTime = pos;
		}
	}
	
	// ==============================
	// ==============================
	function remove_seek_hint ( vp )
	{
		get_obj(vp,'seek_hint').remove();
	}
	
	// ==============================
	// ==============================
	function display_ctlbar ( vp )
	{
		// show the controlbar
		get_obj ( vp,'controlbar' ).remove();
		
		var font_ht = 8;
		var font_wid = 6;
		var deco_wid = 10;
		var deco_ht = 32;
		var ctlbar_pad = 4;
		var ctlbar_bsz = 30;
		var btn_shift = -(deco_ht - ctlbar_bsz)/2;
		var hs = 
			'<div id="'+safe_id(vp,'controlbar')+'" style="position:absolute;width:100%;bottom:0px;left:0px;">'+
			'	<div style="position:absolute;left:0px;bottom:0px;width:100%;height:'+(deco_ht+2*ctlbar_pad)+'px">'+
			'		<div style="padding:'+ctlbar_pad+'px">'+
			'			<table style="width:100%;border:0px none;border-collapse:collapse" cellspacing="0" cellpadding="0">'+
			'				<tr>'+
			'					<td style="width:'+deco_wid+'px"><img style="display:inline;" src="'+vp.g_pars.skinpath+'/ctlbar_left.png" ></td>'+
			'					<td><img src="'+vp.g_pars.skinpath+'/ctlbar_back.png" style="display:inline;width:100%;height:'+deco_ht+'px"></td>'+
			'					<td style="width:'+deco_wid+'px"><img style="display:inline;" src="'+vp.g_pars.skinpath+'/ctlbar_right.png" ></td>'+
			'				</tr>'+
			'			</table>'+
			'		</div>'+
			'	</div>'+
			'	<div style="position:absolute;left:0px;bottom:'+btn_shift+'px;width:100%;height:'+(deco_ht+2*ctlbar_pad)+'px">'+
			'		<div style="padding:'+ctlbar_pad+'px">'+
			'			<table style="width:100%;border:0px none;border-collapse:collapse" cellspacing="0" cellpadding="0">'+
			'				<tr>'+
			'					<td style="width:'+ctlbar_bsz+'px"><div id="'+safe_id(vp,'play_pause_button')+'"><img style="display:inline;" src="'+vp.g_pars.skinpath+'/PlayBtn_En.png"></div></td>'+
			'					<td style="padding-right:4px">'+
			'						<div id="'+safe_id(vp,'player_posbar_cont')+'" style="background:#bbb;width:100%;height:10px;position:relative">'+
			'							<div id="'+safe_id(vp,'player_posbar')+'" style="background:yellow;width:0%;height:100%"></div>'+
			'						</div>'+
			'					</td>'+
			'					<td style="width:'+(11*font_wid)+'px;height:8px;overflow:hidden;padding:8px 0" id="'+vp.idp+'player_pos_cont">'+
			'						<div style="height:8px" id="'+safe_id(vp,'player_pos')+'"></div>'+
			'					</td>';
		if ( !g_ipad )
		{
			hs += '					<td style="width:'+ctlbar_bsz+'px"><div id="'+safe_id(vp,'volume_button')+'"><img style="display:inline;" src="'+vp.g_pars.skinpath+'/VolumeButton_En.png" ></div></td>';
		}
		hs += 
			'				</tr>'+
			'			</table>'+
			'		</div>'+
			'	</div>'+
			'</div>';
		
		get_obj ( vp,'container' ).append ( hs );
		
		// init values and button states
		vp.g_last_digits = '';
		player_timeupdate ( vp, get_vid(vp) );
		if ( get_vid(vp).paused )
			get_obj ( vp, 'play_pause_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/PlayBtn_En.png">' );
		else
			get_obj ( vp, 'play_pause_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/PauseBtn_En.png">' );
		
		// Hook up the buttons
		make_button ( vp, 'volume_button', ''+vp.g_pars.skinpath+'/Btn_Flash.png', mute_unmute );
		make_button ( vp, 'play_pause_button', ''+vp.g_pars.skinpath+'/Btn_Flash.png', play_pause );
		
		if ( g_ipad )
		{
			/*
			document.getElementById ( safe_id(vp,'player_posbar_cont') ).addEventListener ( "touchstart", function(event) 
					{
				$('#yourlogs').html ( (event.targetTouches[0].pageX) + ' : ' + (get_obj(vp,'player_posbar_cont').offset().left+document.body.scrollLeft+document.documentElement.scrollLeft)+'<br>'+$('#yourlogs').html() );
						//display_seek_hint(vp, event.targetTouches[0].screenX-document.body.scrollLeft-document.documentElement.scrollLeft); 
					}, false );
			document.getElementById ( safe_id(vp,'player_posbar_cont') ).addEventListener ( "touchmove", function(event) 
					{
						//move_seek_hint(vp, event.targetTouches[0].screenX);
					}, false );
			document.getElementById ( safe_id(vp,'player_posbar_cont') ).addEventListener ( "touchend", function(event) 
					{ 
						//seek_player ( vp, event.targetTouches[0].screenX );
						//remove_seek_hint(vp); 
					}, false );
			*/
		}
		else
		{
			get_obj ( vp, 'player_posbar_cont' ).mouseenter ( function(event) { display_seek_hint(vp, event.pageX); } );
			get_obj ( vp, 'player_posbar_cont' ).mouseleave ( function() { remove_seek_hint(vp); } );
			get_obj ( vp, 'player_posbar_cont' ).mousemove ( function(event) { move_seek_hint(vp, event.pageX); } );
			get_obj ( vp, 'player_posbar_cont' ).click ( function(event) { seek_player(vp, event.pageX); } );
		}
		
		// this is a child of the posbar so jquery still treats it as part of mousemove 
		get_obj ( vp, 'seek_hint' ).mouseenter ( function() { remove_seek_hint(vp); } );
		
		vp.g_schedule_ctlbar_hide = new Date().getTime() + 3000;
		time_out_ctlbar ( vp, 3100 );
	};
	
	// ==============================
	// ==============================
	function video_clicked ( vp )
	{
		display_ctlbar ( vp );
	}
	
	// =========================
	//
	// Event callbacks
	//
	// =========================
	// TODO: seeking is not guaranteed to fire. standard says "seek operation is taking long enough that the user agent has time to fire the event"
	// So if seeking does not fire, but seeked fires, we may remove the loading anim that was started by someone else. 
	function player_seeking ( vp, vid )
	{
		busy_loading ( vp, "Seeking..." );
	}
	function player_seeked ( vp, vid )
	{
		done_loading ( vp );
	}
	function player_loadstart ( vp )
	{
		busy_loading ( vp, "Loading "+vp.g_video_title );
	}
	function player_loaderror ( vp )
	{
		done_loading ( vp );
	}
	function player_play ( vp, vid )
	{
		force_done_loading ( vp );
		get_obj ( vp, 'play_pause_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/PauseBtn_En.png">' );
	}
	function player_pause ( vp, vid )
	{
		get_obj ( vp, 'play_pause_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/PlayBtn_En.png">' );
	}
	function player_timeupdate ( vp, vid )
	{
		var str = time_fmt(Math.round(vid.currentTime))+"/"+time_fmt(Math.round(vid.duration));
		
		// This is a relatively expensive operation, so we limit it to once per second.
		if ( str != vp.g_last_digits )
		{
			write_digits ( vp, 'player_pos', str );
			vp.g_last_digits = str;
		}

		var cur = vid.currentTime;
		var dur = vid.duration;
		var perc = 0;
		if ( dur>0 )
		{
			perc = 100 * cur/dur;
		}
		if ( perc > 100 )
		{
			perc = 100;
		}
		perc = Math.round (perc*1000)/1000;
		get_obj(vp,'player_posbar').css ( {'width': perc+'%'} );
		
		// adjust the TD that holds the timestamp/duration
		get_obj(vp,'player_pos_cont').css ( {'width': (6*str.length)+'px'} );
	}
	
	function player_volchange ( vp, vid )
	{
		if ( vid.muted || vid.volume < 0.02 )
		{
			get_obj ( vp, 'volume_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/VolumeButtonOff_En.png">' );
		}
		else
		{
			get_obj ( vp, 'volume_button').html ( '<img style="display:inline;" src="'+vp.g_pars.skinpath+'/VolumeButton_En.png">' );
		}
	}
	
	function player_canplaythrough ( vp, vid )
	{
		force_done_loading ( vp );
	}
	function player_durchange ( vp, vid )
	{
		write_digits ( vp, 'player_pos', time_fmt(Math.round(vid.currentTime))+"/"+time_fmt(Math.round(vid.duration)) );
	}
	function player_ended (  vp, vid )
	{
		// show splash with the replay button, this removes the player
		if ( vp.g_cur_playlist.items.length > 0 )
			load_splash ( vp, vp.g_cur_playlist.items[0] );
		
		/*
		var pos = find_cur_playlist_idx ( vp );
		if ( pos != -1 && pos != vp.g_cur_playlist.items.length-1 )
		{
			// will not clear the playlist
			load_video_internal ( vp, vp.g_cur_playlist.items[pos+1] );
			return;
		}

		// If the playlist didnt pick up anything we reach here:			
		vp.find('.anv_replay_mode').show ();
		vp.find('.anv_pause_mode').hide ();
		vp.find('.anv_play_mode').hide ();
		*/
	}
	function player_progress ( vp, vid, event, cur_load_cnt )
	{
		/*
		if ( cur_load_cnt != vp.g_load_cnt )
		{
			return;
		}
		if ( event.lengthComputable && event.total )
		{
			var perc = Math.round ( 100*(event.loaded/event.total)*1000 ) / 1000;
			get_obj(vp, 'anvato_player_buffer').css ( {'width': perc+'%'} );
		}
		*/
	}
	
	// =========================
	//
	// ~Event callbacks
	//
	// =========================
	function hookup_player ( vp )
	{
		var vid = get_obj(vp,'avideo');
		if ( !vid )
			return;
		
		// TODO: What is the proper jquery way?
		vp.g_load_cnt++;
		var cur_load_cnt = vp.g_load_cnt;
		document.getElementById ( vid.attr('id') ).addEventListener ( "progress", function(event) { player_progress(vp, vid, event, cur_load_cnt);}, false );

		vid.bind ( "loadstart", function() {player_loadstart(vp);} );
		vid.bind ( "play", function() {player_play(vp, this);} );
		vid.bind ( "pause", function() {player_pause(vp, this);} );
		vid.bind ( "timeupdate", function() {player_timeupdate(vp, this);} );
		vid.bind ( "volumechange", function() {player_volchange(vp, this);} );
		vid.bind ( "durationchange", function() {player_durchange(vp, this);} );
		vid.bind ( "ended", function() {player_ended(vp, this);} );
		vid.bind ( "canplaythrough", function() {player_canplaythrough(vp, this);} );
		vid.bind ( "seeking", function() {player_seeking(vp, this);} );
		vid.bind ( "seeked", function() {player_seeked(vp, this);} );

		// the purpose following is to stop the loading animation started by loadstart
		vid.bind ( "suspend", function() {player_loaderror(vp);} );
		vid.bind ( "abort", function() {player_loaderror(vp);} );
		vid.bind ( "error", function() {player_loaderror(vp);} );
		vid.bind ( "emptied", function() {player_loaderror(vp);} );

		vid.click ( function() { video_clicked(vp); } );
	}

	// TODO: Escape
	// ======================
	// load_video_internal
	// ======================
	function load_video_internal ( vp, data )
	{
		var vid = get_vid ( vp );
		if ( vid )
			vid.pause();
		
		// todo: stop loading at this point as well
		vp.g_cur_video_url = data['video'];
		
		vp.g_video_title = data.title;
		
		// make the source objects.
		var sources = '';
		for ( var i=0;i<data['videos'].length;i++ )
		{
			sources += '<source type="'+data.videos[i].type+'" src="'+data.videos[i].url+'" />';
		}
		
		// forcing autoplay here
		get_obj ( vp,'container' ).html ( '<video id="'+safe_id(vp,'avideo')+'" style="height:100%;width:100%" preload autoplay">'+sources+'</video>' );
		hookup_player ( vp );
		
		busy_loading ( vp, "Loading "+vp.g_video_title );

		if ( vp.g_pars.begin_callback )
			vp.g_pars.begin_callback ( vp.g_pars.callback_par, safe_id(vp,'avideo'), data['video'], data['image'], data['title'] );
		
		// always autoplay:
		var vid = get_vid ( vp );
		if ( vid != null )
			vid.play ( );
		
		display_ctlbar ( vp );

		// Install ipad tap hooks.
		if ( g_ipad )
		{
			if ( vid != null )
			{
				get_obj ( vp,'avideo' ).bind ( "touchstart", function() {display_ctlbar(vp);}, false );
			}
		}
	}

	// ======================
	// ======================
	function load_playlist ( vp, playlist, autoplay )
	{
		var vid = get_vid ( vp );
		if ( vid )
			vid.pause();
		
		// remove everything and start over.
		get_obj ( vp,'container' ).html ( '' );

		reset_playlist ( vp );
		
		if ( typeof playlist == 'string' )
		{
			load_playlist_ajax ( vp, playlist, autoplay );
		}
		else
		{
			load_playlist_json ( vp, playlist, autoplay );
		}
	}
	
	// ======================
	// ======================
	function post_load_playlist ( vp, autoplay )
	{
		if ( vp.g_cur_playlist.items.length>0 )
		{
			// todo: this should be "current item", not splash item.
			vp.g_splash_item = vp.g_cur_playlist.items[0];
		}
		
		// Start the first item in the playlist
		if ( autoplay )
		{
			if ( vp.g_cur_playlist.items.length>0 )
			{
				load_video_internal ( vp, vp.g_cur_playlist.items[0] );
			}
		}
		else
		{
			if ( vp.g_cur_playlist.items.length>0 )
			{
				load_splash ( vp, vp.g_cur_playlist.items[0] );
			}
		}
		
		// move the carousel scroller to 0
		//get_obj(vp,'cur_playlist').css ( {'margin-left': '0px'} );
	}

	// ======================
	// ======================
	function load_playlist_json ( vp, new_pl, autoplay )
	{
		vp.g_cur_playlist = new_pl;
		
		post_load_playlist ( vp, autoplay );
	}

	// ======================
	// ======================
	function load_playlist_ajax ( vp, pl_url, autoplay )
	{
		$.ajax ({
					cache: false,
					url: pl_url,
					success: function ( xml )
					{
						// Parse the response
						vp.g_cur_playlist.info.title = $(xml).find("playlist>title").text();
						
						// todo: error control and reporting
						$(xml).find("track").each(function() {
							var iurl = $(this).find("image").text();
							var ttl = $(this).find("title").text();
			
							var vurls = [];
							$(this).find("location").each ( function ( ) {
								vurls.push ( {type:$(this).attr('type'), url:$(this).text()} );
							} );
							
							var vurl = ( vurls.length ? vurls[0].url : '' );
							
							vp.g_cur_playlist.items.push ( {video: vurl, image: iurl, title:ttl, videos:vurls} );
						} );
			
						post_load_playlist ( vp,autoplay );
					},
					error: function ()
					{
						alert ( "Failed to load the playlist" );
					},
					complete: function ( )
					{
						
					} 
				});
	}

	/*
	function vol_click ( vp, event )
	{
		var maxval = get_obj(vp,'vol_level_cont').height();
		if ( maxval < 0 )
			return;
		
		var selval = get_obj(vp,'vol_level_cont').offset().top + maxval - event.pageY;

		var vid = get_vid ( vp );
		if ( vid == null )
		{
			return;
		}

		var val = Math.round ( 100* (selval/maxval + 0.125) / 25 ) * 0.25;

		vid.muted = false;
		vid.volume = val;//selval / maxval;

		// We hope that the player will call back in 100msec. It is ok not to: 
		// the volume will be adjusted but the user feedback will be missing.
		g_schedule_vol_hide = new Date().getTime() + 100;
		time_out_vol_ctl ( vp, 200 );
	};
	*/

	
	/*
	// =======================
	// ~autohide volume ctl
	// =======================
	var try_hide_vol = function ( vp )
	{
		var now = new Date().getTime();

		if ( now < vp.g_schedule_vol_hide )
		{
			time_out_vol_ctl ( vp, 500 );
			return;
		}
		
		get_obj(vp,'vol_control_cont').hide ( );
	};
	function time_out_vol_ctl ( vp, delay )
	{
		setTimeout ( function() { try_hide_vol(vp); }, delay );
	}
	function display_volume_ctl ( vp )
	{
		get_obj(vp,'vol_control_cont').show ( );
		get_obj(vp,'vol_control_cont').css ( {'left': (get_obj(vp,'volume_btn').position().left + (vp.g_ctlbar_btnsz - vp.g_vollevel_wid)/2 ) } );
		
		vp.g_schedule_vol_hide = new Date().getTime() + 1500;

		time_out_vol_ctl ( vp, 1600 );
	};
	// =======================
	// ~autohide control bar
	// =======================
	*/
	function play_pause ( vp )
	{
		var vid = get_vid ( vp );
		if ( vid == null )
		{
			// avideo is not embedded, but we have the current item set. We must be waiting for the user to click the onscreenplay. 
			load_video_internal(vp,g_splash_item);
			return;
		}
		if ( vid.ended )
		{
			vid.currentTime = 0;
			vid.play ( );

			return;
		}
		
		( vid.paused ? vid.play ( ) : vid.pause ( ) );
	}

	function mute_unmute ( vp )
	{
		var vid = get_vid ( vp );
		if ( vid == null )
		{
			return;
		}
		if ( vid.muted )
		{
			vid.muted = false;
			vid.volume = 0.5;
		}
		else
		{
			vid.muted = true;
			vid.volume = 0.0;
		}
	}
	/*
	function playlist_next ( vp )
	{
		var pos = find_cur_playlist_idx ( vp );
		if ( pos != -1 && pos != vp.g_cur_playlist.items.length-1 )
		{
			// will not clear the playlist
			load_video_internal ( vp, vp.g_cur_playlist.items[pos+1] );
			return;
		}
	}

	function playlist_prev ( vp )
	{
		var pos = find_cur_playlist_idx ( vp );
		if ( pos != -1 && pos != 0 )
		{
			// will not clear the playlist
			load_video_internal ( vp, vp.g_cur_playlist.items[pos-1] );
			return;
		}
	}

	// =======================
	// =======================
	function play_playlist_item ( vp, idx )
	{
		if ( idx >=0 && idx < vp.g_cur_playlist.items.length )
		{
			close_sub_menu ( vp, 'playlist' );
			load_video_internal ( vp, vp.g_cur_playlist.items[idx] );
		}
	}
	*/
})(jQuery);


