
/*
         ,--------------------------------------------------------.
        /   Toutes les fonctions JS communes aux 3 pages vidéos    )
       (            Ioan Sameli - 2006, 2007                      /
        `--\   /-------------------------------------------------´
           |  /
            \|
             \

           (")-''-(").___..--''"`-._
            \O_ O  )   `-.  (     ).`-.__.´)
            (_Y_.)/  ._   )  `._ `. ``-..-´
          _..`--'_..-_/  /--'_.' ,'
         (il).-''  (li).'  ((!.-'
*/

	// TODO: in the HTML of the static pages, the titles of lists are in another litle list. Would be better to have simply a H2 or so.

	// Disable the drop down menu, so it won't be behind the video if opened
	//$('headerTSR').className = 'disableDropDown';
	// Display the fullscreen button only on MSIE
	//if (navigator.appVersion.indexOf('MSIE') != -1) $('fsButton').style.display = 'block'; 

  /************************/
 /***   entry points   ***/
/************************/

	/* Defined here because it will be used soon */




	// the player can be opened on specific pages, using parameters in hash.
	// TODO: it's a bit of a mess arround here...
	entryPoints = function() {

		// remove the # at the beggining of the hash
		var hash = window.location.hash.substring(1,window.location.hash.length);
	//alert(hash);
		var loadParams = getParam(null, hash, ';');

		// If there's a vid in the hash, load and play this video
		// If not, play the default jingle !
		if (loadParams.vid) {
		//	alert( loadParams.vid);
			trace('entryPoints: Load video ' + loadParams.vid,'info');
			
		
			loadVideoAndPlay(loadParams.vid);
			
			if (loadParams.page) {
				panels.load(''+loadParams.page+'');
			} else {
				panels.load('weekchoice');
			}
			
		} else {

			// Going to a particular page or default page
			if (loadParams.page) {
				panels.load(loadParams.page);
				
			} else {

				
				
				if (loadParams.bcid) {
					trace('entryPoints: Load broadcast ' + loadParams.bcid,'info');
					loadProgramsAndProgramPlaylist(loadParams.bcid, 'xobix_broadcast_id');
				} else if (loadParams.search) {
					trace('entryPoints: Go to search ' + loadParams.search,'info');
					panels.load('search');
				} else if (loadParams.program) {
					trace('entryPoints: Load program ' + loadParams.program,'info');					
					loadProgramsAndProgramPlaylist(loadParams.program);
				} else {
					//alert("foo");
					// Trick: No error message has to be displayed if flash has not been detected, so
					//        temporarly empty the error message (contained in noAvailableFile variable)
					var saveTruc = noAvailableFile;
					noAvailableFile = '';

					// load the jingle. Needs to be loaded before we call the PlayVideo
					
					if (Get_Cookie('introplayed') != 1 )
					{
					loadJingle();
					mainPlayer.playVideo();
					Set_Cookie( 'introplayed', 1, '', '/', '', '' );
					}
					// Set back the error message in the noAvailableFile variable
					noAvailableFile = saveTruc;
					
					if (mainPlayer.channel == 'election') panels.load('election_lastvideos');
					else panels.load('weekchoice');
                   // else panels.load('search');  
				}
			}
		}
	}
	
  /**************************/
 /***   panels gestion   ***/
/**************************/
    var ran_number= Math.random()*5;       
	var panels = {
       
		//basePath:     './download/static/video_2007_panel_',
		basePath:     './content_wrapper.php?file=',
		// Used to fight cache
		
		//suffix:       '?d=22-05-2007-11-10&rand='+ran_number,
		suffix : '',
		// All the files of the panels that we can load, in an object

		// channel emission
		weekchoice:     'weekchoice.xml', 
		programs:     'programs.xml',
		programOpen:  'program_open.xml',
	//	top50:        'top50.xml',
		config:       'config.xml',
		help:         'help.xml',
		lastvideos:   'lastvideos.xml',
		search:       'search.xml',
		test:         'test.xml',
		weekchoice:   'weekchoice.xml' ,
		pacte2010:    'pacte2010.xml' ,
		
		// static nav 
		demo:   'demo.xml' ,
		newsletter:   'newsletter.xml' ,
		tellafriend:   'tellafriend.xml' ,
		concours:   'concours.xml' ,
		top10:   'top10.xml' ,
		top10_de:   'top10_de.xml' ,
		top10_fr:   'top10_fr.xml' ,
		top10_it:   'top10_it.xml' ,
		top10_rm:   'top10_rm.xml' ,
		
		// wettbewerb from http://www.tsr.ch/tsr/index.html?siteSect=650100&rubricId=1401&fromPriority=1&toPriority=1
		wettbewerb: 'wettbewerb.xml',
		derprixmultimedia:   'derprixmultimedia.xml',
		projektausschreibung:  'projektausschreibung.xml',
		vorselektionderprojekte:  'vorselektionderprojekte.xml',
		selektionderprojekte:  'selektionderprojekte.xml',
		anmeldung:  'anmeldung.xml',
		jury:  'jury.xml',
		
		
		rss: 'rss.xml',
		podcast: 'podcast.xml',
        partner: 'partner.xml', 
		blog: 'blog.xml', 
		installation: 'installation.xml', 
		
		impressum: 'impressum.xml',
		contact: 'contact.xml',
		agb: 'agb.xml',
		concoursite1 : 'concoursite1.xml',
		concoursite2 : 'concoursite2.xml',
		
		wasgeworden2007 : 'wasgeworden2007.xml',
		wasgeworden2008 : 'wasgeworden2008.xml',		
		
		// channel sport
		s_programs:     'programs_sport.xml',
		s_keyword:     'sport_keyword.xml',
		

		// channel info
		info_live:    'info_live.xml',
		info_continu: 'continu.xml',
		info_1245:    'program_open.xml',
		info_1900:    'program_open.xml',
		info_1930:    'program_open.xml',
	//	top10:        'top50.xml',
		info_search:  'search.xml',
		
		// channel election
		election_lastvideos:    'lastvideos_event.xml',
		election_classepo:      'program_open.xml',
		election_desperate:     'program_open.xml',
		election_vendredi:      'program_open.xml',
		election_search:        'search.xml',
        
        // dynav
        dyn_navigation:        'dyn_navigation.xml',

		// Load a panel, with really cool effects and a callback function
		// The callback function will be called after the panel is loaded.
		load: function(panel, target, callBack) {
            // alert(target);
           
           if (!target) {
          // alert('no Target defined!');
           target = 'navapp';
           
           } 
            
            
            
           // alert(target);   
           // var target = 'navapp';
			// Change a class, so we can highlight the right button with CSS !
			$('navigation').className = panel;

            
			// Build the full path
			var panelUrl = this.basePath + this[panel] + this.suffix;

			// Start everything, unload the panel and the callback function will make a chain reaction !
			new Effect.Opacity(target, {
				duration:0.3,
				from:1,
				to:0,
				afterFinish: function() {

					// Loading the new panel, executed after the current one is hidden
					new tsrkit_ahahLoad(panelUrl, target, function() {

						// debug for Windows Media on Firefox
						debugVideoWM();

						// Function executed after the panel is loaded
						new Effect.Opacity(target, {
							duration:0.3,
							from:0,
							to:1,
							afterFinish:callBack,
							queue: {
								position: 'end',
								scope: 'switchPanel'
							}
						});
					});
				},
				queue: {
					position: 'end',
					scope: 'switchPanel'
				}
			});
		}
	}


  /*********************************/
 /***   player initialization   ***/
/*********************************/

	// This will probably be the only player we use
	var mainPlayer = new tsrkit('mainPlayer');

	// Set the channel to the player, what data are loaded depends on this property
	var q = window.location.search.substring(1, window.location.search.length);
	var c = varChannel || getParam('channel', q);
	mainPlayer.channel = c || 'emission';
	
	// Link it to the HTML element in the page
	// TODO: kind of useless, the target is already defined with defaultVideoTarget
	mainPlayer.videoTarget = 'playerDynamicContent';
	mainPlayer.videoTitleTarget = 'playerTitle';

	// Initialize the player, and then load the right page/video
	addToStart(function() {mainPlayer.init(entryPoints);});

	// Load the right theme if there's a cookie, and if we're in "emission" channel, otherwise, the theme will be info
	if (mainPlayer.channel == 'emission') {
		var t = getCookie('playerTheme');
		if (t) switchTheme(t);
	} else {
		switchTheme('info', 1)
	}

	var currentProgramId = null;

	// Launch a request to count the videos
//	addToStart(countVideo);

	// Make the count request each 10 minutes (600 seconds)
	//setInterval(countVideo,600*1000);

	// Create a video and load the media of the default jingle.
	function loadJingle() {

		// Create a video in the parent player, and save all the properties
		var newVideo = mainPlayer.addvideo(1);
		newVideo.title = '';
		newVideo.xobix_program_id = '';
		newVideo.xobix_program_name = '';
		newVideo.parsed_broadcast_date = '';

		// Adding the flash 450
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '450';
		newMedium.mCodec = 'swf';
		newMedium.mUrl = 'http://www.pactemultimedia.ch/intro.swf';
		newMedium.mWidth = '480';
		newMedium.mHeight = '300';

		// Adding the flash 160
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '160';
		newMedium.mCodec = 'swf';
		newMedium.mUrl = 'http://www.pactemultimedia.ch/intro.swf';
		newMedium.mWidth = '480';
		newMedium.mHeight = '300';

		// Adding the flash 80
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '80';
		newMedium.mCodec = 'swf';
		newMedium.mUrl = 'http://www.pactemultimedia.ch/intro.swf';
		newMedium.mWidth = '480';
		newMedium.mHeight = '300';

		// Adding the static image
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '100';
		newMedium.mCodec = 'jpeg';
		newMedium.mUrl = 'images/previewDefaultLarge.png';
		newMedium.mWidth = '480';
		newMedium.mHeight = '300';

		mainPlayer.currentVideoID = 1;

	}
	
	function loadJECplaylist() {
		
		// Create a video in the parent player, and save all the properties
		var newVideo = mainPlayer.addvideo(2);
		newVideo.title = 'Le journal en continu (tous les sujets)';
		newVideo.xobix_program_id = '150070';
		newVideo.xobix_program_name = 'Le Journal en continu';
		newVideo.parsed_broadcast_date = '';

		// Adding the Real Media 450
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '450';
		newMedium.mCodec = 'realMedia';
		newMedium.mUrl = 'http://www3.tsr.ch/snippets/journal_continu_real.ram';
		newMedium.mWidth = '480';
		newMedium.mHeight = '360';
		
		// Adding the Real Media 160
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '160';
		newMedium.mCodec = 'realMedia';
		newMedium.mUrl = 'http://xml.tsr.ch/xml/index.xml?siteSect=502401&bitrate=160000&isSnippet=true';
		newMedium.mWidth = '320';
		newMedium.mHeight = '240';
		
		// Adding the Real Media 80
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '80';
		newMedium.mCodec = 'realMedia';
		newMedium.mUrl = 'http://xml.tsr.ch/xml/index.xml?siteSect=502401&bitrate=80000&isSnippet=true';
		newMedium.mWidth = '192';
		newMedium.mHeight = '144';
		
		// Adding the Windows Media 450
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '450';
		newMedium.mCodec = 'windowsMedia';
		newMedium.mUrl = 'http://www3.tsr.ch/snippets/journal_continu_wmv.asx';
		newMedium.mWidth = '480';
		newMedium.mHeight = '360';
		
		// Adding the Windows Media 160
		var newMedium = newVideo.addMedium();
		newMedium.mBitrate = '160';
		newMedium.mCodec = 'windowsMedia';
		newMedium.mUrl = 'http://xml.tsr.ch/xml/index.xml?siteSect=502400&bitrate=160000&isSnippet=true';
		newMedium.mWidth = '320';
		newMedium.mHeight = '240';
		
	}   

	// TODO: can be deleted
	
	/*function makePlayerFitWindow(){

		// HAHAHA... I killed this function !
		return;

		// for MSIE and other browsers, get the window's height
		if (window.innerHeight) var totalHeight = window.innerHeight;
		else var totalHeight = document.documentElement.offsetHeight;

		var navapp = $('navappContainer');
		if (navapp.innerHeight) var navHeight = navapp.innerHeight;
		else var navHeight = navapp.offsetHeight;

		// And make the player the same height.
		var addSize = totalHeight - $('player').scrollHeight;

		var newSize = (navHeight + addSize);
		if (newSize > 270) navapp.style.height = newSize+'px';

		if (addSize) trace('change navapp dimension of '+addSize+'px');
	}*/

/*
	function switchTheme(themeKey, nocookie) {
		document.getElementById('player').parentNode.className = themeKey;
		if (!nocookie) setCookie('playerTheme', themeKey);
		return false;
	}*/

	// Load the search page and search something
	function searchShortcut(v) {
  //  alert(v);  
		var hash = window.location.hash.substring(1,window.location.hash.length);
		window.location.hash = addParam('search', v, hash, ';');
		panels.load('search');
		return false; 
	}

	// Set the video in FullScreen. Only works on MSIE.
	// The codec of the video has to be shown in the "title" attribute
	function DoFullScreen() {

	//	var err = 'Veuillez lancer une vidéo avant de passer en plein écran !';
		var err = str_novideo;
		var err2 = str_waitforvideo;
		var vObj = $('embedVideo');

		if (vObj) {

			// realMedia
			if (vObj.title == 'realMedia' ) {
				if (vObj.CanStop()) vObj.SetFullScreen();
				else alert(err2);
			}
			

			// windowsMedia
			if (vObj.title == 'windowsMedia') {
				if (vObj.playState == 3) vObj.fullScreen = true;
				else alert(err2);
			}
		} else {
			alert(err);
		}
	}


  /**************************/
 /***   HTML templates   ***/
/**************************/

	// The HTML templates are stored here, because the <> characters are annoying in XML files.

	// The open program's playlist template
	var templateVideoListProgramWithRollover = '$broadcast_separator<li class="line2">\n'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);" '
		+ 'onmouseover="displayVideoDetail($player.videos[this.name]);">'
		+ '<span class="main">$title <em>$parsed_duration</em>\n'
		+ '</span></a></li>\n';

	// The open program's playlist template
	var playlistTemplateSearchResult = '<li class="line$line">\n'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);">'
		+ '<span class="main">$title <em>$parsed_duration</em>\n'
		+ '</span></a></li>\n';

	// The week choice's playlist template
	var playlistTemplateWeekChoice = 
		
		 '<a href="#" name="$id" rel="video" onclick="document.getElementById(\'currentVideoInfo\').style.visibility=\'visible\';return $player.playVideo(this.name);document.getElementById(\'currentVideoInfo\').style.visibility=\'visible\';"> '
		+ '<div class="homeentry">'
	   // + ' onmouseover="document.getElementById(\'videoDetail\').style.display=\'block\';displayVideoDetail($player.videos[this.name]);">\n'
	    + '$previewImage'
		+ '<div class="hometext"><h2 class="homeh2">$titleshortened</h2>\n'
		+ '<p class="homep">$descriptionshortened </p><p class="homep">$program | $parsed_duration  <br />$parsed_broadcast_notime_date</p><table style="width:120px;"><tr><td>$type</td><td>$station</td><td >$ownimg</td></tr></table>   \n'
		
		+ '</div></div></a>\n';
		
		/*var playlistTemplateWeekChoice = '<li>'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);">\n'
		+ '$img'
		+ '<strong>$boxTitle</strong>\n'
		+ '<span>$boxText $parsed_duration</span>\n'
		+ '<em>$xobix_program_name</em>'
		+ '</a></li>\n';	*/

	var playlistTemplateWeekChoiceSport = '<li>'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);">\n'
		+ '$img'
		+ '<span style="font-size:11px;">$title $parsed_duration</span>\n'
		+ '<em>$xobix_program_name, $parsed_broadcast_date</em>'
		+ '</a></li>\n';

	// Journal en continu playlist template
	var playlistTemplateContinu = '<div class="homeentry">'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);">\n'
		+ '$img'
		+ '<strong><em>$broadcast_time</em> $title</strong>\n'
		+ '<span> $parsed_duration</span>\n'
		+ '</a></div>\n';

// TODO: rename this, it's actually used by search and top50 !
	var unused_template_with_rollovers = '<li class="line$line">'
		+ '<a href="#" name="$id" rel="video" onclick="document.getElementById(\'currentVideoInfo\').style.visibility=\'visible\';$onclick;" '
		+ 'onmouseover="this.style.cursor=\'pointer\';document.getElementById(\'videoDetail\').style.display=\'block\';displayVideoDetail($player.videos[this.name]);" onmouseout="document.getElementById(\'videoDetail\').style.display=\'none\'">\n'
		+ '<div class="count">$position.</div>'
		+ '<div class="title"><span class="blue">$titleshortened</span> | $program | $parsed_duration</div></a>'
		+ '<div class="station"><span class="blue uppercase">$station</span> |  $parsed_broadcast_notime_date | <span class="lang">$lang</span></div>$ownimg $type</li>\n';
 
        
     var dyn_nav_template = '<li class="dynnav">'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);" '
		+ 'onmouseover="displayVideoDetail($player.videos[this.name]);">\n'
		+ '<span class="num">$index.</span>\n'
		+ '<span class="title"><span>$title | $description_shortened | $parsed_duration\n'
		+ '</span></span><span class="program"><span>$station |  $parsed_broadcast_notime_date | $lang</span> $owner $type</span></a></li>\n';
   
               
        
	var searchResultsTemplate = '<li class="line$line">'
		+ '<a href="$test_url">$img<strong>$title</strong>'
		+ '<em style="color:#999999;">$subtitle</em></a></li>';

	// The detail of a video
	var playlistTemplateOpenVideo = '<div>\n'
		+ '<a href="#" name="$id" rel="video" onclick="return $player.playVideo(this.name);">$previewImage<br />'
		+ '<h3>$videotitle</h3>$ownimg $type<p class="description">$description</p><p class="duration">$parsed_duration | $parsed_broadcast_notime_date</p></a>\n'
		// + '<a class="send2friend" href="javascript:void(window.open(\'index.html?siteSect=200004&lastUrl=http%3A%2F%2Fwww.tsr.ch%2Ftsr%2Findex.html%3FsiteSect%3D500000%26amp;channel=$channel_anchor_program=$xobix_program_id;vid=$id\',\'send2friend\',\'toolbar=no,location=no,status=no,menubar=no,width=360,height=260\'));">Envoyer à un ami</a>'
		+ '<p class="links">$extlinks</p>'
		+ '</div>\n';

	// template for the last videos list
	var lastVideosTemplate = '<li class="line$line">\n<a href="#" name="$id" rel="video"'
		+ ' onclick="return $player.playVideo(this.name);">$img<span>\n'
		+ '<strong>$xobix_program_name: </strong>$title <em>$parsed_duration</em></span></a></li>\n';

	// REDEFINED FOR STUPID MSIE !!1! JAVASCRIPT FIX ADDED !11!! OMG WTF !!!!
	// TODO: make this code only available to MSIE, serve decent code to other browsers
	var lastVideosTemplate = '<li class="line$lastVideoLine">\n<a href="#" name="$id" rel="video"'
		+ ' onclick="return $player.playVideo(this.name);">'
		+ '<img src="$preview" alt="" onmouseover="this.nextSibling.style.display=\'block\';" onmouseout="this.nextSibling.style.display=\'none\';"/>'
		+ '<span>'
		+ '<strong>$xobix_program_name: </strong>$title <em>$parsed_duration</em></span></a></li>\n';

	// For the programs list
	var programsListTemplate = '<li class="line$line"><a href="#program=$programVideoSource"'
		+ ' onmouseover="$(\'previewEmission\').src=(\'$pathimg\');"'
		+ ' onclick="loadProgramVideos($programVideoSource);" rel="program"><img src="$pathimg" alt=""/><span> $programName'
		+ '</span></a></li>\n';

	// Title of a video, with some details. Displayed next to the video at the top of the page.
	var titleTemplate = '<div onmouseover="document.getElementById(\'currentVideoInfo\').style.overflow=\'scroll\';document.getElementById(\'previewdescription\').style.display=\'block\';" >\n'
		+ '$previewImage<br />'
		+ '<h3>$videotitle</h3><p class="duration">$ownimg $type $blindimg $parsed_broadcast_notime_date | $parsed_duration</p><p class="tellafriend">$tellafriend</p> <p id="previewdescription">$description <br />$extlinks</p>\n'
		// + '<a class="send2friend" href="javascript:void(window.open(\'index.html?siteSect=200004&lastUrl=http%3A%2F%2Fwww.tsr.ch%2Ftsr%2Findex.html%3FsiteSect%3D500000%26amp;channel=$channel_anchor_program=$xobix_program_id;vid=$id\',\'send2friend\',\'toolbar=no,location=no,status=no,menubar=no,width=360,height=260\'));">Envoyer à un ami</a>'
	//	+ '<p class="links"></p>'
		+ '</div>\n'; 
		
		// Title of a video, with some details. Displayed next to the video at the top of the page.
	var titleTemplateOld = '<div>\n'
		+ '$previewImage<br />'
		+ '<h3>$videotitle</h3>$ownimg $type $blindimg<p class="description">$description</p><p class="duration">$parsed_duration | $parsed_creation_date</p>\n'
		// + '<a class="send2friend" href="javascript:void(window.open(\'index.html?siteSect=200004&lastUrl=http%3A%2F%2Fwww.tsr.ch%2Ftsr%2Findex.html%3FsiteSect%3D500000%26amp;channel=$channel_anchor_program=$xobix_program_id;vid=$id\',\'send2friend\',\'toolbar=no,location=no,status=no,menubar=no,width=360,height=260\'));">Envoyer à un ami</a>'
		+ '<p class="links">$extlinks</p>'
		+ '</div>\n';	
      
  /****************************/
 /***   Lot of functions   ***/
/****************************/

  
  // Launch the live video, by appending a little iframe to the document
    function launchLiveVideo(urlVideo) {
        
        // Default video URL for the live feed
        urlVideo = urlVideo || ' http://akastreaming.tsr.ch/vp/chtsr/no_geo/live.asx?gjmf=live_2_1'
        
        // Create new DOM iframe element
        var iframe = document.createElement('iframe');
        iframe.src = urlVideo;
        iframe.width = 1;
        iframe.height = 1;
        iframe.style.border = 'none';
        
        // Add it to the document body
        var dbody = document.getElementsByTagName('body')[0];
        dbody.appendChild(iframe);
        
        // Stop to play the current video
        $(mainPlayer.videoTarget).innerHTML='<img src="http://www.tsr.ch/images/interactif/video_2007/jingle_intro_static.jpg" alt=""/>';
    }

	function loadProgramsAndProgramPlaylist(searchId,field){

		// If loading a telejournal, load the right page instead of the default page (will highligh the menu)
		// TODO: this could be improved because it's pretty creepy
		var pan = 'programOpen';
		if (! field) {
			if (searchId == 15) pan = 'info_1930';
			if (searchId == 25) pan = 'info_1245';
			if (searchId == 26) pan = 'info_1900';
			if (searchId == 167612) pan = 'election_classepo';
			if (searchId == 171691) pan = 'election_desperate';
			if (searchId == 171700) pan = 'election_vendredi';
		}
		
		mainPlayer.loadProgramsWithCallback(function(a) {
			panels.load(pan, function() {
				
				// If this is an info page, well, display a calendar, and let it load the videos!
				if (mainPlayer.channel == 'info') createCalendar(searchId, true);
				else loadProgramPlaylist(searchId,field);
			});
		});
	}

	loadProgramVideos = function(programVideoId, panelId) {
		
		panels.load(panelId || 'programOpen', function() {
		
			// If this is an info page, well, display a calendar, and let it load the videos!
			if (mainPlayer.channel == 'info') createCalendar(programVideoId, true);
			else loadProgramPlaylist(programVideoId);
				
		});
	}

	// Create an argument for Solr with the list of programs to load (actu, sport, etc. are ignored)
	createSolrAllProgramsArgument = function() {

		var requestPrograms = '';
		for (var i in mainPlayer.programs) {
			var currentProgram = mainPlayer.programs[i];
			requestPrograms += (requestPrograms ? ' ' : '') + i;
		}
		return '(' + requestPrograms + ')';
	}

	// Creates a Solr date range from very long time ago to right now, to avoid loading videos
	// that are in the future.
	// exemple: ["1900-01-01T00:00:00Z" TO "2006-12-31T23:59:59Z"]
	// TODO: minimum date set to 2005 because of storage problems
	createSolrDateRangePast = function() {

		var templateDateSolr = '["2005-01-01T00:00:00Z" TO "$year-$month-$dayT$hour:$minute:00Z"]';
		var now = new Date();

		// Create an object that will contain all the properties, for the template parsing later.
		var dateData = {};
		dateData.minute = now.getMinutes();
		dateData.hour = now.getHours();
		dateData.day = now.getDate();
		dateData.month = now.getMonth() + 1;
		dateData.year = now.getFullYear();


		// Pad values with 0 if there's only one character
		if (dateData.day.toString().length == 1) dateData.day = '0' + dateData.day;
		if (dateData.month.toString().length == 1) dateData.month = '0' + dateData.month;
		if (dateData.minute.toString().length == 1) dateData.minute = '0' + dateData.minute;
		if (dateData.hour.toString().length == 1) dateData.hour = '0' + dateData.hour;

		return parseTemplate(templateDateSolr, dateData);
	}


	// Standard search
	// Displays the first result's details
	// searchId can be either a string, associated with the field param, or an object containing several fields
	loadProgramPlaylist = function(searchId, field) {
		
		if (typeof searchId == 'object') {
			var param = searchId;
			
			// when the search is not on the whole program, display the "back to program" link
			if (searchId.title){
				$('backToProgram').style.display = 'none';
				$('searchInProgramInput').value = searchId.title;
			}
			else $('backToProgram').style.display = 'block';
				
		} else {

			// by default: search by xobix_program_id
			if (!field) field = 'xobix_program_id';
	
			// when the search is not on the whole program, display the "back to program" link
			if (field == 'xobix_program_id') $('backToProgram').style.display = 'none';
			else $('backToProgram').style.display = 'block';
	
			// Build the request for Solr
			var param = {};
			param[field] = searchId;
		}

		// Ignore the broadcasts in the future if there's no other field than xobix_program_id
		if (field == 'uid') param['broadcast_date:' + createSolrDateRangePast()] = null;
		
		var count = field == 'uid' ? 10 : 50;

		var newRequest = mainPlayer.searchOnSolr(param, 'broadcast_date desc, xobix_broadcast_position asc', count);

		newRequest.rTarget = 'programPlayList';
		newRequest.rPaginationTarget = 'programPaging';
		newRequest.rTemplate = templateVideoListProgramWithRollover;

		// display the detail of the first video
		newRequest.rCallback = function(){

			var v = mainPlayer.videos[newRequest.firstVideoId];
			
			//var progId = (field == 'xobix_program_id' ? searchId : '')
			var progId = (field == 'uid' ? searchId : '')    
			if (v) {

				// Display the detail of the first video
				displayVideoDetail(v);
	
				// Save the current program ID
				//currentProgramId = v.xobix_program_id;
	            currentProgramId = v.uid;      
				// Play first video if there's no video playing yet
				if (mainPlayer.currentVideoID <= 1) mainPlayer.playVideo(newRequest.firstVideoId);
				
				progId = v.uid;
				
			} else trace('The request did not return any video ?', 'warning');	

			// in order to display the program info even if there's no result, the xobix_program_id is required
			// use the original search field if we can't find the first result			
			var progData = mainPlayer.programs[progId];
			
			if (progData) {
				
				var programDetail = $('programDetail');
				programDetail.innerHTML = '<span>' + progData.programUrl + '</span>';
				programDetail.style.backgroundImage = 'url(' + progData.programIcon + ')';
				programDetail.href = progData.programUrl;
	
				$('backToProgram').innerHTML = 'Voir toutes les vidéos de ' + progData.programName;
				$('backToProgram').href = '#program=' + progData.programVideoSource;
	
				// Add the program name in the "searchInProgram" label
				$('searchInProgramLabel').innerHTML = progData.programName;
			
			} else trace('Error: no data loaded for this program', 'error');

		};

	//	newRequest.launch();		
		
	}

	searchInProgram = function(searchString, programId, dateRange) {

		// Create arguments for the search
		var p = {'xobix_program_id': programId || currentProgramId}

		// Ignore the broadcasts in the future
		var dr = dateRange || createSolrDateRangePast();
		if (dr) p['broadcast_date:' + dr] = null;

		// display the "see all videos" button if needed
		if (searchString){
			p.title = searchString;
			$('backToProgram').style.display = 'block';
		}
		else $('backToProgram').style.display = 'none';

		// If no searchString, empty the search field
		$('searchInProgramInput').value = searchString || '';

		// If a daterange is specified, display all results on one page
		var rc = dateRange ? 100 : null;

		// Create new request
	/*	var newRequest = mainPlayer.searchOnSolr(p, 'broadcast_date desc', rc);
		newRequest.rTarget = 'programPlayList';
		newRequest.rPaginationTarget = 'programPaging';
		newRequest.rTemplate = templateVideoListProgramWithRollover;
		newRequest.launch();*/

	}

	// Inject HTML code containing the details in the #videoDetail HTML element
	displayVideoDetail = function(vData) {
// trace(vData,'message');	
		
	//	alert();
	//	trace(vData,'message');
		var codeHTML = parseTemplate(playlistTemplateOpenVideo, vData);
		if ($('videoDetail')) $('videoDetail').innerHTML = codeHTML;
	}

	function countVideo() {

/*	mainPlayer.loadProgramsWithCallback(function() {
			
			var param = {
				'':''
				
			}

			param['broadcast_date:' + createSolrDateRangePast()] = null;
			
			// Hack election
			if (mainPlayer.channel == 'election') {
				var param = {};
				//param['(xobix_program_id'] = createSolrAllProgramsArgument();
				param['1) OR tag'] = 'evenement';
			}
			
			var newRequest = mainPlayer.searchOnSolr(param, null, 0);

			// Callback function will use the number of results
			newRequest.rCallback = function() {
				var n = mainPlayer.requests[newRequest.id].numFound;
				//alert(n);
				$('videoCount').innerHTML = '<strong>' + n + '</strong> Beitr&auml;ge gesamt';
				trace('On a compté les vidéos, il y en a '+n,'info');
			};

			newRequest.rTarget = '';

			// Launch request and set back the old results count
			newRequest.launch();
		});*/
	}

	// Load a video from Solr and play it, and load the programs from the video
	function loadVideoAndPlay(vid) {
		
		var searchParams = {'':''};
		var searchContent = 'term:%::uid:'+vid;
		
		searchParams.title = searchContent;
		var newRequest = mainPlayer.searchOnSolr(searchParams, ''); 
		//var newRequest = mainPlayer.searchOnSolr({'':'','title':'uid:'+vid});
		//alert(newRequest);
		newRequest.rCallback = function() {
		//	alert(vid);
		   
			mainPlayer.playVideo(vid);
			document.getElementById('currentVideoInfo').style.visibility='visible';
		//	var p = mainPlayer.videos[vid].xobix_program_id;
			//if (p) {
			//	loadProgramsAndProgramPlaylist(p);
			//	currentProgramId = p;
		//	}
		};
		newRequest.rTarget = '';
		newRequest.launch();
	}
	
	function loadJECvideos() {
		
		var n = new Date();
		var feedJEC = 'index.html?siteSect=500201&time=' + n.getDate() + n.getHours() + n.getMinutes();
		
		newRequest = mainPlayer.loadFromXML(feedJEC);
		newRequest.rTarget = 'infoContinuList';
		newRequest.rTemplate = playlistTemplateContinu;
		
		// debug for Windows Media on Firefox
		newRequest.rCallback = function() {
			debugVideoWM();
			
			loadJECplaylist();
			
			// Play first video of the resultset if there's no video playing yet 
			if (mainPlayer.currentVideoID <= 1) mainPlayer.playVideo(2);
				
		};
		
		newRequest.launch();
	}

	/* Switch on and off the little dropdown menu for the themes */
	var ThemeSelectOn = false;
	function displayThemeSelect() {

		ThemeSelectOn = true;

		var themeMenu = $('themeMenu');
		if (!themeMenu) return;

		var onMouseOutCode = function() {
			ThemeSelectOn = false;
			window.setTimeout(function() {
				if (ThemeSelectOn == false) $('themeMenu').style.display = 'none';
			},20);

		};
		var onMouseOverCode = function() {ThemeSelectOn = true;};

		$('themeMenuTrigger').onmouseout = onMouseOutCode;
		themeMenu.onmouseout = onMouseOutCode;
		themeMenu.onmouseover = onMouseOverCode;
		themeMenu.style.display = 'block';
	}


  /******************************************/
 /***   Player configuration functions   ***/
/******************************************/

	// For the context help
	var contextHelpOn = false;

	function displayContextHelp(trigger, dataId) {
	// Display a little help

		//trace('context help ' + dataId);
		contextHelpOn = true;
		hz = $('contextHelpZone');
		if (!hz) return;

		// Make the help to disappear just after the mouse left the element, but let enough time for
		// the mouse to go on the element before it disappear
		var onMouseOutCode = "contextHelpOn = false; window.setTimeout(\'if (contextHelpOn == false)$(\\\'contextHelpZone\\\').style.display=\\\'none\\\';',150)";
		var onMouseOverCode = "contextHelpOn = true;";

		hz.innerHTML = '<div onmouseout="' + onMouseOutCode + '" onmouseover="' + onMouseOverCode + '">'
			+ '<img src="/images/triangle-tip.gif" class="arrow"/>'
			+ $(dataId).innerHTML + '</div>';
		hz.style.display = 'block';
		hz.style.left = (findPos(trigger)[0] + 300) + 'px';
		hz.style.top = (findPos(trigger)[1] - 25) + 'px';
	}

	function findPos(obj) {
	// Return the position of the element in the page
	// Stolen from http://www.quirksmode.org/js/findpos.html
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			curleft = obj.offsetLeft
			curtop = obj.offsetTop
			while (obj = obj.offsetParent) {
				curleft += obj.offsetLeft
				curtop += obj.offsetTop
			}
		}
		return [curleft,curtop];
	}

	function hideContextHelp() {
	// We need to create a function for the onMouseOut, because that noob of MSIE doesn't understand the setAttribute property.
		contextHelpOn = false;
		window.setTimeout("if (contextHelpOn == false)if (d=$('contextHelpZone'))d.style.display='none';",250);
	}

	function showSolution(idSolution) {
	// For interactive help

		// Walk trough all the solutions to hide the solutions
		var solution = $('helpPanelDebug').childNodes[0];
		while(solution!=null) {
			if (solution.id)solution.style.display = 'none';
			solution = solution.nextSibling;
		}

		if (n = $('solutionTitle')) n.style.display = 'block';
		if (n = $(idSolution)) n.style.display = 'block';
	}

	function bugReportVarDump() {
	// Create a string with all the information we can gather about the client,
	// to try to identify what kind of problem he could have

		var debugVars = 'Rapport\n======= ';

		debugVars += '\n Titre video: ' + mainPlayer.videos[mainPlayer.currentVideoID].xobix_program_name + ' / ' + mainPlayer.videos[mainPlayer.currentVideoID].title;
		debugVars += '\n Id video: ' + mainPlayer.currentVideoID;
		debugVars += '\n URL: ' + window.location;
		debugVars += '\n OS: ' + navigator.platform;
		debugVars += '\n Browser: ' + navigator.appName + ' / ' + navigator.appVersion;
		debugVars += '\n user agent: ' + navigator.userAgent;

		var now = new Date();
		debugVars += '\n date: ' + now.toGMTString();

		// Output some test results$
		debugVars += '\n\nTests\n-----';
		debugVars += '\n test Windows Media: ' + mainPlayer.user.windowsMedia;
		debugVars += '\n test Real Player: ' + mainPlayer.user.realMedia;
		debugVars += '\n test Macromedia Flash: ' + mainPlayer.user.flash;

		// Dump all user cookies
		debugVars += '\n\nCookies\n-------';
		if (document.cookie) {
			var biscuits = ' ' + document.cookie;
			if (biscuits != "") {
				liste = biscuits.split(";");
				for (var i = 0; i < liste.length; i++) {
					temp = liste[i].split("=");
					debugVars += '\n' + temp[0] + ' = ' + temp[1];
				}
			}
		}

		// Dump the plugins list, don't display each more than once
		debugVars += '\n\nPlugins\n-------';
		if (navigator.plugins) {
			var t = null;
			for (var i = 0; i < navigator.plugins.length; i++) {
				t2 = t;
				t = '\n ' + navigator.plugins[i].name + '\n     ' + navigator.plugins[i].description;
				if (t != t2) debugVars += t;
			}
		}

		f = $('bugReportVarField');
		f.value = debugVars;
	}

	// relaunch all tests on the config panel
	retest = function() {
		clearConfigPanel();
		displayMessage('attendez un peu...');
		var callBack = function() {
			mainPlayer.user.init();
			mainPlayer.user.autoSetPrefs(1);
			mainPlayer.initializeConfigPanel();
			displayMessage();
			}
		mainPlayer.user.init(callBack,1);
	}


	function clearConfigPanel() {
		$('usrResultBW').innerHTML='';
		$('usrResultWM').innerHTML='';
		$('usrResultRP').innerHTML='';
		$('usrResultMF').innerHTML='';
	}

	// Fill the control panel with the test results
	// and select the fields according to the user's preference
	tsrkit.prototype.initializeConfigPanel = function() {

		// Refresh the properties
		mainPlayer.user.init();

		// If we don't have the results of the test, run it.
		if (!(this.user.bandWidth && this.user.realMedia && this.user.windowsMedia && this.user.flashMedia)) {
			retest();
			return;
		}

		// Fill the bandwidth field with the result and set a cool icon
		$('usrResultBW').innerHTML = this.user.bandWidth+' Kbps';
		var img = $('usrResultBWimg');
		if (this.user.bandWidth > 500) img.innerHTML = okayIcon;
		else if (this.user.bandWidth < 80) img.innerHTML = troubleIcon;
		else img.innerHTML = warningIcon;

		setUserDetect('WM', this.user.windowsMedia);
		setUserDetect('RP', this.user.realMedia);
		setUserDetect('MF', this.user.flashMedia);

		// Check the right Bitrate
		elmntId = 'favBitrate-' + this.user.favBitrate;
		var elementBitrate = $(elmntId);
		if (elementBitrate) elementBitrate.checked = 'true';
		else trace('Element ' + elmntId + ' not found', 'error');

		// Check the right codec
		elmntId = 'favCodec-'+this.user.favCodec;
		var elementCodec = $(elmntId);
		if (elementCodec) elementCodec.checked = 'true';
		else trace('Element '+elmntId+' not found', 'error');

		// Check the alternativePlay checkbox
		var chkBox = $('alternativePlay');
		chkBox.checked = this.user.alternativePlay ? true : false;

		// Display some debug
		trace('The favourite bitrate is <b>'+this.user.favBitrate+'</b>');
		trace('The favourite codec is <b>'+this.user.favCodec+'</b>');

		var elmtsToparse = document.getElementsByClassName('autoSave', 'input');

		var cPlayer = this;
		
		elmtsToparse.each(function(cht) {

			trace('adding functions to element '+cht.id, 'info', 2);

			// Add a blur, otherwise some browser won't execute the onchange event
			cht.onclick = function() {this.blur();};

			cht.onchange = function() {cPlayer.user.saveUserPref(this);};

			// Somehow, safari doesn't handle the .onchange property, so give him something onclick
			if (navigator.userAgent.toLowerCase().indexOf('safari') > 0) cht.onclick = function() {cPlayer.user.saveUserPref(this);};

		});

		// And finally, manage the fact that there's no windows media 56k medium
		// TODO: this shouldn't be here
		this.user.additionalSaveOps();
	}

  /****************************/
 /***   Play with flickr   ***/
/****************************/

	getFlickrImagesByTag = function(tag) {
		var urlJSON = 'http://www.flickr.com/services/feeds/photos_public.gne?tags=' + tag + '&format=json';
		var newRequest = mainPlayer.getNewSearch(urlJSON, 'testElm');
		newRequest.setJSONCallbackFunctionName('jsonFlickrFeed');
		newRequest.handleResult = eatFlickrSandwish;
		newRequest.launch();
	}

	getFlickrLastImages = function() {
		var urlJSON = 'http://www.flickr.com/services/rest/?method=flickr.photos.getRecent&format=json&api_key=0ccebcda6054d57131dbaf407e50646f';
		var newRequest = mainPlayer.getNewSearch(urlJSON, 'testElm');
		newRequest.setJSONCallbackFunctionName('jsonFlickrApi');
		newRequest.handleResult = eatFlickrApiSandwish;
		newRequest.launch();
	}

	eatFlickrSandwish = function(result) {
		var p = this;
		p.injectToTarget('<h2>' + result.title + '</h2>');
		result.items.each(function(r) {
			p.injectToTarget('<a href="'+r.link+'"><img src="'+r.media.m.replace('_m.jpg', '_s.jpg')+'" alt=""/></a>',1);
		});
	}

	eatFlickrApiSandwish = function(result) {
		var p = this;
		p.injectToTarget('<h2>All recent photos</h2>');
		var t = '<a href="http://www.flickr.com/photos/$owner/$id/">'
			+'<img src="http://farm$farm.static.flickr.com/$server/$id_$secret_s.jpg" alt="$title"/>'
			+ '</a>';
		result.photos.photo.each(function(r) {
			var img = parseTemplate(t, r);
			p.injectToTarget(img,1);
		});
	}

  /******************/
 /***   TOP 50   ***/
/******************/

	function loadTop50() {

		// Load the cached XML data from wysistat
		var r = new tsrkit_ajaxRequest;
		r.rSource = 'index.html?siteSect=500204&isSnippet=true&channel='+mainPlayer.channel;
		r.rTarget = 'top50List';
		r.handleResult = handleTop50;
		r.launch();
	}


	// Handle the xml result with the top50, and merge it with a request from Solr
	var handleTop50 = function(answer){

		var xml = answer.request.responseXML;

		if (!xml)trace('Wysistat top50: the answer is not valid', 'error');

		var videos = xml.getElementsByTagName('video');

		// Loop trough all the videos to build the request that will load all the videos from Solr

		// Global variable here... Not the cleanest way, but i can't give argument to a callback later.
		requestVideos = '';

		var allVids = [];

		// for (var i in videos) {
		for (var i = 0; i < videos.length; i++) {

			var currentVideo = videos[i];
			
			trace(currentVideo.firstChild.data + ' / ' + currentVideo.firstChild.data.indexOf('le journal'));
			
			// dirty HACK: filter the items with "le journal" in them
			if (currentVideo.firstChild.data.indexOf('le journal') > 0) continue;

			// Somehow i got some numbers sometimes instead of objects... (prototype library ?)
			if (!currentVideo.attributes) continue;

			var rank = currentVideo.attributes[0].value;
			var bcidAndVid = currentVideo.attributes[1].value;
			var hits = currentVideo.attributes[2].value;

			// Get the vid without bcid
			var vid = bcidAndVid.split('-').pop();

			// To skip the videos that are twice in the file
			if(allVids[vid]) continue;
			else allVids[vid] = 1;

			requestVideos += (requestVideos ? ' ' : '') + vid + '^' + hits;
		}

		// This is the final argument to get all the videos.
		requestVideos = '(' + requestVideos + ')';

		// Call the loadLast function, but load the programs first if needed.
		mainPlayer.loadProgramsWithCallback(mergeTop50WithSolr);
		
	}

	// Launch a request on Solr to get all the videos from the top50 that are part of a program displayed in this application
	function mergeTop50WithSolr() {
		
		// Create the argument to get the programs
		var requestPrograms = createSolrAllProgramsArgument();

		// Create the JSON request
		var p = {};
		p.xobix_program_id = requestPrograms;
		p.xobix_video_id = requestVideos;

		// This is top50, so load only 50 results ! Or 10 for info and sport.
		var maxResultCount = (mainPlayer.channel == 'emission' ? 50 : 10);
		
		// Create request
		var newRequest = mainPlayer.searchOnSolr(p, null, maxResultCount);
		newRequest.rTarget = 'top50List';
		newRequest.rTemplate = unused_template_with_rollovers;
		
		// display the detail of the first video
		newRequest.rCallback = function(){
			var v = mainPlayer.videos[newRequest.firstVideoId];
			displayVideoDetail(v);
			
			// Set the number of result found
			if (n = $('top50Count')) n .innerHTML = newRequest.numLoaded;

			// debug for Windows Media on Firefox
			debugVideoWM();
		}

		// Launch request and set back the old results count
	//	newRequest.launch();
	}
	


  /***************************/
 /***   CALENDAR THINGS   ***/
/***************************/

	// Create a calendar
	createCalendar = function(progId, displayFirstDayVideos) {
		
		if (! $('calendar')) {
			// alert('Calendar not found :(');
			return;
		} else $('calendar').className = 'active'

		facetCal = new tsrCalendar;
		facetCal.cTarget = 'calendar';
		facetCal.progId = progId
		facetCal.dateClick = function(d) {
			loadVideosForDay(d);
			return false;
		}

		// Highlight some cells with different values
		facetCal.onRender = function() {
			
			// Display the videos if needed
			if (displayFirstDayVideos) {				
				loadLastBroadcast(progId);				
				displayFirstDayVideos = false;
			}
			
			mainPlayer.loadDateFacet(progId);
			this.removeHighlight();
		}

		facetCal.onRender();

	}

	function loadVideosForDay(dt) {
        
		// First, pad with 0
		dt.day = strpad(dt.day, 2, 0);
		dt.month = strpad(dt.month, 2, 0);
		
		// Create dateRange
		var templateDateSolr = '["$year-$month-$dayT00:00:00Z" TO "$year-$month-$dayT23:59:59Z"]';
		var dr = parseTemplate(templateDateSolr, dt);

		// Display all the results for that day.
		var param = {}
		param.broadcast_date = dr;
		if (facetCal.progId) param.xobix_program_id = facetCal.progId;
		
		var newRequest = mainPlayer.searchOnSolr(param, 'broadcast_date desc, xobix_broadcast_position asc', 50);

		newRequest.rTarget = 'programPlayList';
		newRequest.rPaginationTarget = 'programPaging';
		newRequest.rTemplate = templateVideoListProgramWithRollover;

		//newRequest.launch();

	}
	
	tsrkit.prototype.loadDateFacet = function(programId) {

		// Create a new empty request object
		var newRequest = this.getNewSearch();

		var tmpDateM = facetCal.cYear + '-' + strpad(facetCal.cMonth,2,0);

		newRequest.rSource = 'http://search2.tsr.ch/solr/select?q=role:video%20AND%20xobix_program_id:'+programId+'%20AND%20broadcast_date:%5B%22'+tmpDateM+'-01T00:00:00Z%22%20TO%20%22'+tmpDateM+'-31T23:59:59Z%22%5D'
			+'&rows=0&facet=true&facet.field=broadcast_date&wt=json&json.wrf=' + newRequest.setJSONCallbackFunctionName();

		// The function that will finally handle the results
		newRequest.handleResult = handleSolrDateFacetResult;

	//	newRequest.launch();
	}

	var handleSolrDateFacetResult = function(result) {

		// First, cancel the timeout warning, this is the answer !
		this.handleRequestTimeout = function(){};

		// Get two "parallel" objects, one with the ids, one with the names
		var dateFacets = result.facet_counts.facet_fields.broadcast_date;

		// Get the max value of the facets, to draw pretty colors on the calendar
		var maxFacetCount = 0;
		for (var i in dateFacets) if (dateFacets[i] > maxFacetCount) maxFacetCount = dateFacets[i];

		for (var i in dateFacets) {

			var k = dateFacets[i];

			if (k) {

				// Get date of this facet
				var d = parseDateSolrToHuman(i, 'dateobj');

				// Create a factor between 1 an 9 according to the count of items for this date
				var highlight = Math.round(9 * (k / maxFacetCount));

				// Highlight the day, and set the title !
				var d = d.getDate() + '-' + (d.getMonth() + 1) + '-' + d.getFullYear();
				facetCal.highLightDay(d, 'tj-' + highlight);

				facetCal.setDayTitle(d, k + ' videos');
			}
		}

		// Finally, render the calendar.
		facetCal.render();

	}
	
	// Pad the "str" string until "pLength" with the "padder" character
	// for example: strpad ('ab', 5, 'c') => 'cccab'
	function strpad (str, pLength, padder) {
		str = String(str);
		while (str.length < pLength) {str = padder + str;}
		return str;
	}
	
	// This function get the last broadcast for a given program, and displays it.
	function loadLastBroadcast(programId) {
		
		// Create a new empty request object
		var newRequest = mainPlayer.getNewSearch();

		// Create the URL
		newRequest.rSource = 'http://search2.tsr.ch/solr/select?q=role:video%20AND%20xobix_program_id:'+programId
			+';broadcast_date%20desc&rows=1&wt=json&json.wrf=' + newRequest.setJSONCallbackFunctionName();

		// The function that will finally handle the results
		newRequest.handleResult = function(r) {loadProgramPlaylist(r.response.docs[0].xobix_broadcast_id, 'xobix_broadcast_id')};

	//	newRequest.launch();
		
	}