<?php
	//
	// m85x -- a music server script
	//
	// A set of scripts that implement a music browser. Assuming access
	// to an earfull query server, m85x uses earlfull query APIs to
	// generate an interactive music browser.
	//
	
	require('m85query.php');
	
	$sitename = "www.pairoducks.com/music";
	$urlBase = 'https://www.pairoducks.com/music';
	$scriptBase = "$urlBase/m85x.php";
	$streamBase = 'https://musicstream.pairoducks.com:235';
	
	//
	// m85x commands
	//
	$m85ListGenre		= "$scriptBase?c=genre&p=";
	$m85ListArtist		= "$scriptBase?c=artist&p=";
	$m85ListVarious		= "$scriptBase?c=various&p=";
	$m85Podcasts		= "$scriptBase?c=podcasts&p=";
	$m85ListAlbum		= "$scriptBase?c=album&p=";
	$m85ListTeachAlbum	= "$scriptBase?c=teachalbum&p=";
	$m85ListTeach		= "$scriptBase?c=teach&p=";
	$m85ListTeachGenre	= "$scriptBase?c=teachgenre&p=";
	$m85ListTeachDisc	= "$scriptBase?c=teachdisc&p=";
	$m85ListDisc		= "$scriptBase?c=disc&p=";
	$m85PlayGenre		= "$scriptBase?c=playgenre&p=";
	$m85PlayTeachGenre	= "$scriptBase?c=playteachgenre&p=";
	$m85PlayArtist		= "$scriptBase?c=playartist&p=";
	$m85PlayAlbum		= "$scriptBase?c=playalbum&p=";
	$m85PlayDisc		= "$scriptBase?c=playdisc&p=";
	$m85PlaySong		= "$scriptBase?c=playsong&p=";
	
	//
	// Table format constants
	//
	$pageBackground = "#e0dde0";
    $darkTableColor = "#dddddd";
    $lightTableColor = "#cccccc";
    $bgcolor = $darkTableColor;


	//------------------------------------------------------------------------------
	//
	// "main"
	//
	
	// Potentially limited in future
	$maxQuality = 2;
	
	// Command and parameter for this instance
	if (isset($_GET['c']))
	{
		$command = $_GET['c'];
	}
	else
	{
		$command = "";
	}
	
	if (isset($_GET['p']))
	{
		$param = $_GET['p'];
	}
	else
	{
		$param = "";
	}
	
	// Quality: 0=ls, 1=nl, 2=hd
	$quality = 0;
	if (isset($_GET['q']))
	{
		$quality = $_GET['q'];
		if (!is_numeric($quality) || $quality < 0 || $quality > 2)
		{
			$quality = 0;
		}
	}
	
	$showQuality = false;
	if (isset($_GET['s']) && $_GET['s'] == 'y')
	{
		$showQuality = true;
	}
	
	// Checked-item support
	$checkbox_index = 0;
	
	// Height of top floater
	$floaterHeight = "75px";
	
	// Run the command for this session
	switch ($command)
	{
		case 'genre':
			genre($param);
			break;
		case 'artist':
			artist($param);
			break;
		case 'podcasts':
			podcasts($param);
			break;
		case 'album':
			album($param);
			break;
		case 'disc':
			disc($param);
			break;
		case 'teach':
			teach($param);
			break;
		case 'teachgenre':
			teachgenre($param);
			break;
		case 'teachalbum':
			teachalbum($param);
			break;
		case 'teachdisc':
			teachdisc($param);
			break;
		case 'various':
			various($param);
			break;
		case 'playgenre':
			playgenre($param, $quality, false);
			break;
		case 'playteachgenre':
			playteachgenre($param, $quality, false);
			break;
		case 'playartist':
			playartist($param, $quality, false);
			break;
		case 'playalbum':
			playalbum($param, $quality, false);
			break;
		case 'playdisc':
			playdisc($param, $quality, false);
			break;
		case 'playsong':
			playsong($param, $quality);
			break;
		case 'play':
			playchecked($param, $quality);
			break;
		default:
			$floaterHeight = "50px";
			genreList();
	}
	
	// end of main
	

	//------------------------------------------------------------------------------
	//
	// Convert seconds into a time string
	//
	function secondsToTime($seconds)
	{
		$hours = floor($seconds / 3600);
		$mins = floor($seconds / 60 % 60);
		$secs = floor($seconds % 60);
		
		$retval = "";
		
		if ($hours > 0)
		{
			$retval = "$hours".":";
		}
		if ($mins == 0 && $hours > 0)
		{
			$retval = "$retval"."00:";
		}
		else if ($mins > 0)
		{
			if ($mins > 9 || $hours == 0)
			{
				$retval = "$retval"."$mins".":";
			}
			else
			{
				$retval = "$retval"."0$mins".":";
			}
		}
		if ($secs == 0)
		{
			$retval = "$retval"."00";
		}
		else if ($secs > 9 || ($hours == 0 && $mins == 0))
		{
			$retval = "$retval"."$secs";
		}
		else
		{
			$retval = "$retval"."0$secs";
		}
		
		return $retval;
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of a single disc from the Teaching Company
	//
	function teachdisc($disc_id)
	{
		global $m85PlayDisc;
		global $m85PlaySong;
		global $m85ListTeachDisc;
		
		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryTeachDisc($disc_id);
		tableFooter();
		popupRowHeader();
		$disc = $query->disc_for_id($disc_id);
		$disc_list = $query->discs_for_album($disc->album_id);
		popupRowComplex('disc', "", $disc_list, $m85PlayDisc, $m85ListTeachDisc, $disc_id);
		popupRowFooter();

		mainTableHeader();
		
		$songs = $query->songs_for_disc($disc_id);
		foreach ($songs as $song)
		{
			$ask = "song/$song->title";
			$time = secondsToTime($song->duration);
			mainTableRow("$ask", "$m85PlaySong"."$song->song_id", "images/audio.png", "$song->title", "", "$time");
		}

		mainTableFooter('d', $disc_id);
		mainTableImages($query->images_for_disc($disc_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of a single disc
	//
	function disc($disc_id)
	{
		global $m85PlayDisc;
		global $m85PlaySong;
		global $m85ListDisc;
		
		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryDisc($disc_id);
		tableFooter();
		popupRowHeader();
		$disc = $query->disc_for_id($disc_id);
		$disc_list = $query->discs_for_album($disc->album_id);
		popupRowComplex('disc', "", $disc_list, $m85PlayDisc, $m85ListDisc, $disc_id);
		popupRowFooter();

		mainTableHeader();
		
		$songs = $query->songs_for_disc($disc_id);
		foreach ($songs as $song)
		{
			$ask = "song/$song->title";
			$time = secondsToTime($song->duration);
			mainTableRow("$ask", "$m85PlaySong"."$song->song_id", "images/audio.png", "$song->title", "", "$time");
		}

		mainTableFooter('d', $disc_id);
		mainTableImages($query->images_for_disc($disc_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Callback func for sorting dicts with 'title' fields
	//
	function sort_callback($a, $b)
	{
		return strcasecmp($a.title, $b.title);
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of the given album
	//
	function album($album_id)
	{
		global $m85PlaySong;
		global $m85ListAlbum;
		global $m85PlayAlbum;
		global $m85ListDisc;
		global $m85PlayDisc;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryAlbum($album_id);
		tableFooter();
		popupRowHeader();
		$album = $query->album_for_id($album_id);
		$response = $query->artists_for_album($album_id);
		$artist_id = $response[0];
		if ($album->title == 'Singles')
		{
			popupRowSimple();
		}
		else
		{
			$albums = $query->albums_for_artist($artist_id);
			popupRowComplex('album', "", $albums, $m85PlayAlbum, $m85ListAlbum, $album_id);
		}
		popupRowFooter();

		mainTableHeader();
		
		if ($album->multidisc == 't')
		{
			$discs = $query->discs_for_album($album_id);
			$count = $query->songs_for_album_top_count($album_id);
			if ($count > 0)
			{
				foreach ($discs as $disc)
				{
					$item['type'] = 'disc';
					$item['ref'] = $disc;
					$list[] = $item;
				}

				$songs = $query->songs_for_album_top($album_id);
				foreach ($songs as $song)
				{
					$item['type'] = 'song';
					$item['ref'] = $song;
					$list[] = $item;
				}

				usort($list, function ($ak, $bk) use ($array) {
					return strcasecmp($ak['ref']->title, $bk['ref']->title);
				});
				foreach ($list as $item)
				{
					if ($item['type'] == 'song')
					{
						$song = $item['ref'];
						$album_id = $song->album_id;
						$ask = "song/$song->title";
						$time = secondsToTime($song->duration);
						mainTableRow("$ask", "$m85PlaySong"."$song->song_id", "images/audio.png", "$song->title", "", "$time");
					}
					else
					{
						$disc = $item['ref'];
						mainTableRow(" ", "$m85PlayDisc"."$disc->disc_id", "images/folder.png", "$disc->title", "$m85ListDisc"."$disc->disc_id", "");
					}
				}
			}
			else
			{
				foreach ($discs as $disc)
				{
					mainTableRow("", "$m85PlayDisc"."$disc->disc_id", "images/folder.png", "$disc->title", "$m85ListDisc"."$disc->disc_id", "");
				}
			}
		}
		else
		{
			$songs = $query->songs_for_album($album_id);
			foreach ($songs as $song)
			{
				$album_id = $song->album_id;
				$ask = "song/$song->title";
				$time = secondsToTime($song->duration);
				mainTableRow("$ask", "$m85PlaySong"."$song->song_id", "images/audio.png", "$song->title", "", "$time");
			}
		}

		mainTableFooter('l', $album_id);
		mainTableImages($query->images_for_album($album_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of the given Teaching Company album
	//
	function teachalbum($album_id)
	{
		global $m85PlaySong;
		global $m85ListTeachAlbum;
		global $m85PlayAlbum;
		global $m85ListDisc;
		global $m85PlayDisc;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryTeachAlbum($album_id);
		tableFooter();
		popupRowHeader();
		$main_genre = "";
		foreach ($query->genres_for_album($album_id) as $genre)
		{
			if ($genre->title != 'Lecture')
			{
				$main_genre = $genre->genre_id;
				break;
			}
		}
		$album = $query->album_for_id($album_id);
		$albums = $query->albums_for_teach_genre($main_genre);
		popupRowComplex('album', "", $albums, $m85PlayAlbum, $m85ListTeachAlbum, $album_id);
		popupRowFooter();

		mainTableHeader();
		
		if ($album->multidisc == 't')
		{
			$discs = $query->discs_for_album($album_id);
			foreach ($discs as $disc)
			{
				mainTableRow("", "$m85PlayDisc"."$disc->disc_id", "images/folder.png", "$disc->title", "$m85ListDisc"."$disc->disc_id", "");
			}
		}
		else
		{
			$songs = $query->songs_for_album($album_id);
			foreach ($songs as $song)
			{
				$album_id = $song->album_id;
				$ask = "song/$song->title";
				$time = secondsToTime($song->duration);
				mainTableRow("$ask", "$m85PlaySong"."$song->song_id", "images/audio.png", "$song->title", "", "$time");
			}
		}

		mainTableFooter('l', $album_id);
		mainTableImages($query->images_for_album($album_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of the given album
	//
	function podcasts($genre_id)
	{
		global $m85PlayAlbum;
		global $m85ListAlbum;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
 		tableFooter();
		popupRowHeader();
		popupRowSimple();
		popupRowFooter();
		
		mainTableHeader();
		$response = $query->albums_in_genre($genre_id);
		foreach ($response as $album)
		{
			if ($album->multidisc == "t")
			{
				$count = 0;
				$discs = $query->discs_for_album($album->album_id);
				foreach ($discs as $disc)
				{
					$trackCount = $query->song_for_disc_count($disc->disc_id);
					$count = $count + $trackCount;
				}
			}
			else
			{
				$count = $query->songs_for_album_count($album->album_id);
			}
			$title = $album->title;
			if (!is_null($album->date))
			{
				$year = $album->date;
			}
			else
			{
				$year = $album->year;
			}
			
			$countText = "$count track";
			if ($count > 1)
			{
				$countText = $countText . "s";
			}
			$ask = "album/$album->title";
			mainTableRow("$ask", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "$year $title", "$m85ListAlbum"."$album->album_id", "$countText");
		}
		mainTableFooter('p', $genre_id);
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the albums for the given artist
	//
	function artist($artist_id)
	{
		global $m85PlayArtist;
		global $m85ListArtist;
		global $m85PlayAlbum;
		global $m85ListAlbum;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryArtist($artist_id);
		tableFooter();
		popupRowHeader();
		$artist = $query->artist_for_id($artist_id);
		$genres = $query->genres_for_artist($artist_id);
		$genre_id = $genres[0]->genre_id;
		$genre_artists = $query->artists_in_genre($genre_id);
		popupRowComplex('artist', "$artist->title", $genre_artists, $m85PlayArtist, $m85ListArtist, $artist_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = $query->albums_for_artist($artist_id);
		foreach ($response as $album)
		{
			if ($album->multidisc == "t")
			{
				$count = 0;
				$discs = $query->discs_for_album($album->album_id);
				foreach ($discs as $disc)
				{
					$trackCount = $query->songs_for_disc_count($disc->disc_id);
					$count = $count + $trackCount;
				}
			}
			else
			{
				$count = $album->count;
			}
			$title = $album->title;
			if (!is_null($album->date))
			{
				$year = $album->date;
			}
			else
			{
				$year = $album->year;
			}
			
			$countText = "$count track";
			if ($count > 1)
			{
				$countText = $countText . "s";
			}
			$ask = "album/$album->title";
			mainTableRow("$ask", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "$year $title", "$m85ListAlbum"."$album->album_id", "$countText");
		}
		mainTableFooter('r', $artist_id);
		mainTableImages($query->images_for_artist($artist_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the albums from Various Artists for the given genre
	//
	function various($genre_id)
	{
		global $m85PlayArtist;
		global $m85ListArtist;
		global $m85PlayAlbum;
		global $m85ListAlbum;

		$query = MusicQuery::Instance();
		
		$artist_id = $query->various_artists_id();
		
		htmlHeader();
		tableHeader();
		tableEntryVarious($genre_id);
		tableFooter();
		popupRowHeader();
		
		$artist = $query->artist_for_id($artist_id);
		$genre_artists = $query->artists_in_genre($genre_id);
		popupRowComplex('artist', "$artist->title", $genre_artists, $m85PlayArtist, $m85ListVarious, $genre_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = $query->albums_for_various_artists_genre($genre_id);
		foreach ($response as $album)
		{
			if ($album->multidisc == "t")
			{
				$count = 0;
				$discs = $query->discs_for_album($album->album_id);
				foreach ($discs as $disc)
				{
					$trackCount = $query->songs_for_disc_count($disc->disc_id);
					$count = $count + $trackCount;
				}
			}
			else
			{
				$count = $album->count;
			}
			$title = $album->title;
			if (!is_null($album->date))
			{
				$year = $album->date;
			}
			else
			{
				$year = $album->year;
			}
			
			$countText = "$count track";
			if ($count > 1)
			{
				$countText = $countText . "s";
			}
			$ask = "album/$album->title";
			mainTableRow("$ask", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "$year $title", "$m85ListAlbum"."$album->album_id", "$countText");
		}
		mainTableFooter('r', $artist_id);
		mainTableImages($query->images_for_artist($artist_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the genres for the teaching company
	//
	function teach($artist_id)
	{
		global $m85PlayArtist;
		global $m85ListArtist;
		global $m85ListTeachGenre;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryTeach($artist_id);
		tableFooter();
		popupRowHeader();
		$artist = $query->artist_for_id($artist_id);
		$genres = $query->genres_for_artist($artist_id);
		$genre_id = $genres[0]->genre_id;
		$genre_artists = $query->artists_in_genre($genre_id);
		popupRowComplex('artist', "$artist->title", $genre_artists, $m85PlayArtist, $m85ListArtist, $artist_id);
		popupRowFooter();
		
		mainTableHeader();
		foreach ($genres as $genre)
		{
			if ($genre->title != 'Lecture')
			{
				$count = $query->albums_for_teach_genre_count($genre->genre_id);
				$countText = "$count artist";
				if ($count > 1)
				{
					$countText = $countText . "s";
				}
				mainTableRow("", "$m85PlayTeachGenre"."$genre->genre_id", "images/folder.png", "$genre->title", "$m85ListTeachGenre"."$genre->genre_id", "$countText");
			}
		}
		mainTableFooter('r', $artist_id);
		mainTableImages($query->images_for_artist($artist_id));
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the artists in the given genre
	//
	function teachgenre($genre_id)
	{
		global $m85ListTeachGenre;
		global $m85PlayGenre;
		global $m85PlayTeachGenre;
		global $m85PlayAlbum;
		global $m85ListTeach;
		global $m85ListTeachAlbum;
		global $m85ListArtist;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableEntryTeachGenre($genre_id);
		tableFooter();
		popupRowHeader();
		$genres = $query->genres_for_artist($query->teach_artist_id());
		popupRowComplex('genre', 'teach', $genres, $m85PlayTeachGenre, $m85ListTeachGenre, $genre_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = $query->albums_for_teach_genre($genre_id);
		foreach ($response as $album)
		{
			$title = $album->title;			
			mainTableRow("", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "$title", "$m85ListTeachAlbum"."$album->album_id", "");
		}
		mainTableFooter('g', $genre_id);
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the artists in the given genre
	//
	function genre($genre_id)
	{
		global $m85ListGenre;
		global $m85PlayGenre;
		global $m85PlayArtist;
		global $m85ListArtist;
		global $m85ListVarious;
		global $m85ListTeach;

		$query = MusicQuery::Instance();
		
		$various_id = $query->various_artists_id();
		
		htmlHeader();
		tableHeader();
		tableEntryGenre($genre_id);
		tableFooter();
		popupRowHeader();
		$genres = $query->genre_list();
		popupRowComplex('genre', "", $genres, $m85PlayGenre, $m85ListGenre, $genre_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = $query->artists_in_genre($genre_id);
		foreach ($response as $artist)
		{
			if ($artist->artist_id == $various_id)
				$count = $query->albums_for_various_artists_genre_count($genre_id);
			else
				$count = $artist->count;
			$title = $artist->title;
			$countText = "$count album";
			if ($count > 1)
			{
				$countText = $countText . "s";
			}
			$ask = "artist/$title";
			$listParam = $artist->artist_id;
			if ($title == 'Teaching Company')
			{
				$listCmd = "$m85ListTeach";
			}
			else
			{
				if ($artist->artist_id == $various_id)
				{
					$listParam = $genre_id;
					$listCmd = "$m85ListVarious";
				}
				else
				{
					$listCmd = "$m85ListArtist";
				}
			}
			
			mainTableRow("$ask", "$m85PlayArtist"."$artist->artist_id", "images/folder.png", "$title", "$listCmd"."$listParam", "$countText");
		}
		mainTableFooter('g', $genre_id);
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display a list of genres
	//
	function genreList()
	{
		global $m85PlayGenre;
		global $m85ListGenre;
		global $m85Podcasts;
		global $m85PlayAlbum;
		global $m85ListAlbum;

		$query = MusicQuery::Instance();
		
		htmlHeader();
		tableHeader();
		tableFooter();
		popupRowHeader();
		popupRowSimple();
		popupRowFooter();
		
		mainTableHeader();
		
		// List all the music genres
		$response = $query->genre_list();
		$acceptable = array("Ambient", "New Age", "Blues", "Classical", "Comedy", "Country", "Electronic", "Folk", "Funk", "R&B", "Hip-Hop", "Indian", "Jazz", "Pop", "Reggae", "Rock", "Seasonal", "Soundtrack", "Trip-Hop", "World");
		foreach ($response as $genre)
		{
			if (in_array($genre->title, $acceptable))
			{
				$count = $query->artists_in_genre_count($genre->genre_id);
				$countText = "$count artist";
				if ($count > 1)
				{
					$countText = $countText . "s";
				}
				mainTableRow("", "$m85PlayGenre"."$genre->genre_id", "images/folder.png", "$genre->title", "$m85ListGenre"."$genre->genre_id", "$countText");
			}
		}
		
		// Singles are kind of special
		$count = $query->singles_songs_count();
		$countText = "$count track";
		if ($count > 1)
		{
			$countText = $countText . "s";
		}
		$singles_id = $query->singles_album_id();
		mainTableRow("", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "Singles", "$m85ListAlbum"."$singles_id", "$countText");
		
		// Spoken Word genres
		$acceptable = array("Podcast", "Audiobook", "Lecture", "Interview", "Radio Drama");
		foreach ($response as $genre)
		{
			if (in_array($genre->title, $acceptable))
			{
				if ($genre->title == 'Podcast')
				{
					$count = $query->albums_in_genre_count($genre->genre_id);
					$countText = "$count podcast";
				}
				else
				{
					$count = $query->artists_in_genre_count($genre->genre_id);
					$countText = "$count artist";
				}
				
				if ($count > 1)
				{
					$countText = $countText . "s";
				}
				
				if ($genre->title == 'Podcast')
				{
					mainTableRow("", "$m85PlayGenre"."$genre->genre_id", "images/folder.png", "$genre->title", "$m85Podcasts"."$genre->genre_id", "$countText");
				}
				else
				{
					mainTableRow("", "$m85PlayGenre"."$genre->genre_id", "images/folder.png", "$genre->title", "$m85ListGenre"."$genre->genre_id", "$countText");
				}
			}
		}
		mainTableFooter('0', "0");
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the HTML output
	//
	function htmlHeader()
	{
		global $siteName;
		global $pageBackground;
		global $floaterHeight;

		print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
		print "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";
		print "<head>\n";
		print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n";
		print "<link rel=\"icon\" type=\"image/png\" href=\"https://www.pairoducks.com/music/pdm.png\">";
		print "<title>music</title>\n";
		
		print "<style type=\"text/css\">\n";

		print ".topbar {\n";
  		print "\tposition: fixed;\n";
  		print "\tmargin-left: 8px;\n";
  		print "\ttop: 0;\n";
  		print "\tleft: 0;\n";
		print "\theight: $floaterHeight;\n";
 		print "\twidth: 100%;\n";
 		print "\tz-index: 10;\n";
 		print "\tbackground: $pageBackground;\n";
		print "\ta:link { color: #3333ee; text-decoration: none; ! important }\n";
		print "\ta:hover { color: navy; text-decoration: none; ! important }\n";
		print "\ta:visited { color: ee3333; text-decoration: none; ! important }\n";
		print "}\n";

		print ".tablebody {\n";
  		print "\ttop: $floaterHeight;\n";
 		print "\twidth: 100%;\n";
 		print "\tposition: relative;\n";
 		print "\tz-index: 1;\n";
		print "\ta:link { color: #3333ee; text-decoration: none; ! important }\n";
		print "\ta:hover { color: navy; text-decoration: none; ! important }\n";
		print "\ta:visited { color: ee3333; text-decoration: none; ! important }\n";
		print "}\n";
		print "</style>\n";

		print "</head>\n";
		print "<body bgcolor=\"$pageBackground\">\n";
		
		print "<div class=\"topbar\">\n";
		print "<table align=\"center\" id=\"header\" height=8 width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
		print "</table>\n";
		print "<table align=\"center\" id=\"header\" width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the "path" bar
	//
	function tableHeader()
	{
		global $scriptBase;

		print "<tr style=\"text-align:center\" align=\"char\">\n";
		print "<td width=\"80%\" align=\"left\" valign=\"bottom\">\n";
		print "<a href=\"$scriptBase\">music</a>";
	}
	
	//------------------------------------------------------------------------------
	//
	// Path Bar for discs
	//
	function tableEntryDisc($disc_id)
	{
		global $m85ListGenre;
		global $m85ListArtist;
		global $m85ListAlbum;
		global $m85ListDisc;
		
		$query = MusicQuery::Instance();
		
		$disc = $query->disc_for_id($disc_id);
		$album_id = $disc->album_id;
		$genres = $query->genres_for_album($album_id);
		$sep = ' / ';
		foreach ($genres as $genre)
		{
			print "$sep<a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
			$sep = ', ';
		}
		
		$album = $query->album_for_id($album_id);
		$album_title = $album->title;
		$artistList = $query->artists_for_album($album_id);
		foreach ($artistList as $artist_id)
		{
			$artist = $query->artist_for_id($artist_id);
			$title = $artist->title;
			print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
		}
		print " / <a href=\"$m85ListAlbum$album_id\">$album_title</a>";
		print " / <a href=\"$m85ListDisc$disc_id\">$disc->title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for discs
	//
	function tableEntryTeachDisc($disc_id)
	{
		global $m85ListTeachGenre;
		global $m85ListTeach;
		global $m85ListTeachAlbum;
		global $m85ListTeachDisc;
		
		$query = MusicQuery::Instance();
		
		$lecture = $query->lecture_genre_id();
		print " / <a href=\"$m85ListGenre$lecture\">Lecture</a>";
		
		$artist_id = $query->teach_artist_id();
		$title = $artist->title;
		print " / <a href=\"$m85ListTeach$artist_id\">Teaching Company</a>";

		$disc = $query->disc_for_id($disc_id);
		$album_id = $disc->album_id;
		$genres = $query->genres_for_album($album_id);
		$sep = ' / ';
		foreach ($genres as $genre)
		{
			if ($genre->title != 'Lecture')
			{
				print "$sep<a href=\"$m85ListTeachGenre$genre->genre_id\">$genre->title</a>";
				$sep = ', ';
			}
		}
		
		$album = $query->album_for_id($album_id);
		$album_title = $album->title;
		print " / <a href=\"$m85ListTeachAlbum$album_id\">$album_title</a>";

		print " / <a href=\"$m85ListTeachDisc$disc_id\">$disc->title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for albums
	//
	function tableEntryAlbum($album_id)
	{
		global $m85ListGenre;
		global $m85ListArtist;
		global $m85ListVarious;
		global $m85ListAlbum;
		
		$query = MusicQuery::Instance();
		
		$genres = $query->genres_for_album($album_id);
		$sep = ' / ';
		foreach ($genres as $genre)
		{
			print "$sep<a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
			$sep = ', ';
		}
		
		$genre_id = $genres[0]->genre_id;
		
		$album = $query->album_for_id($album_id);
		$album_title = $album->title;
		$response = $query->artists_for_album($album_id);
		$artist_id = $response[0];
		$artist = $query->artist_for_id($artist_id);
		$title = $artist->title;
		if ($title == 'Various Artists')
		{
			print " / <a href=\"$m85ListVarious$genre_id\">$title</a>";
		}
		else if ($album->title != 'Singles')
		{
			print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
		}

		print " / <a href=\"$m85ListAlbum$album_id\">$album_title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for albums
	//
	function tableEntryTeachAlbum($album_id)
	{
		global $m85ListGenre;
		global $m85ListTeachGenre;
		global $m85ListArtist;
		global $m85ListTeachAlbum;
		
		$query = MusicQuery::Instance();
		
		$lecture = $query->lecture_genre_id();
		print " / <a href=\"$m85ListGenre$lecture\">Lecture</a>";
		
		$artist_id = $query->teach_artist_id();
		$title = $artist->title;
		print " / <a href=\"$m85ListArtist$artist_id\">Teaching Company</a>";

		$genres = $query->genres_for_album($album_id);
		$sep = ' / ';
		foreach ($genres as $genre)
		{
			if ($genre->title != 'Lecture')
			{
				print "$sep<a href=\"$m85ListTeachGenre$genre->genre_id\">$genre->title</a>";
				$sep = ', ';
			}
		}
		
		$album = $query->album_for_id($album_id);
		$album_title = $album->title;
		print " / <a href=\"$m85ListTeachAlbum$album_id\">$album_title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for artists
	//
	function tableEntryArtist($artist_id)
	{
		global $m85ListGenre;
		global $m85ListArtist;
		
		$query = MusicQuery::Instance();
		
		$genres = $query->genres_for_artist($artist_id);
		$sep = ' / ';
		foreach ($genres as $genre)
		{
			print "$sep<a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
			$sep = ', ';
		}
		
		$artist = $query->artist_for_id($artist_id);
		$title = $artist->title;
		print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for the Teaching Company
	//
	function tableEntryTeach($artist_id)
	{
		global $m85ListGenre;
		global $m85ListArtist;
		
		$query = MusicQuery::Instance();
		
		$lecture = $query->lecture_genre_id();
		print " / <a href=\"$m85ListGenre$lecture\">Lecture</a>";
		
		$artist = $query->artist_for_id($artist_id);
		$title = $artist->title;
		print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for genres
	//
	function tableEntryVarious($genre_id)
	{
		global $m85ListVarious;

		$query = MusicQuery::Instance();
		
		$genre = $query->genre_for_id($genre_id);
		print " / <a href=\"$m85ListVarious$genre_id\">$genre->title</a>";
	}
	
	//------------------------------------------------------------------------------
	//
	// Path Bar for genres
	//
	function tableEntryGenre($genre_id)
	{
		global $m85ListGenre;

		$query = MusicQuery::Instance();
		
		$genre = $query->genre_for_id($genre_id);
		print " / <a href=\"$m85ListGenre$genre_id\">$genre->title</a>";
	}
	
	//------------------------------------------------------------------------------
	//
	// Path Bar for Teaching COmpany sub-genres
	//
	function tableEntryTeachGenre($genre_id)
	{
		global $m85ListGenre;
		global $m85ListTeach;
		global $m85ListTeachGenre;
		
		$query = MusicQuery::Instance();
		
		$lecture = $query->lecture_genre_id();
		print " / <a href=\"$m85ListGenre$lecture\">Lecture</a>";
		$tc_id = $query->teach_artist_id();
		print " / <a href=\"$m85ListTeach$tc_id\">Teaching Company</a>";
		$genre = $query->genre_for_id($genre_id);
		print " / <a href=\"$m85ListTeachGenre$genre_id\">$genre->title</a>";
	}
	
	//------------------------------------------------------------------------------
	//
	// Bottom of the Path bar
	//
	function tableFooter()
	{
		print "</td>\n";
		print "<td width=\"20%\" align=\"right\">\n";
//		DisplayRandomImage();
		print "</td>\n";
		print "</tr>\n</table>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the popup button row
	//
	function popupRowHeader()
	{
		print "<table align=\"center\" id=\"list\" height=4 width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
		print "</table>\n";
		print "<table align=\"center\" id=\"list\" width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
		print "<tr style=\"text-align:center\" align=\"char\">\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Simple popup button row: nothing there
	//
	function popupRowSimple()
	{
		print "<td width=\"2%\"></td><td width=\"2%\"></td><td width=\"78%\"></td>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Complex popup button row: something for everyone
	//
	function popupRowComplex($context, $ask_name, $list, $play_command, $list_command, $item_id)
	{
		// Ask button
		print "<td width=\"2%\">";
		if ($context == 'artist')
		{
			print "<a target=\"_blank\" href=\"http://allmusic.com/search/artist/$ask_name\">";
			print "<img src=\"images/ask.png\"></a>";
		}
		print "</td>\n";
		
		// Play button
		print "<td width=\"2%\">";
		print "<img align=\"top\" src=\"images/play.png\" onClick=\"javascript:window.location.href='$play_command$item_id'\">";
		print "</td>\n";
		
		// Popup
		print "<td align=\"left\" width=\"96%\">";
		print "<select name=f onChange=\"javascript:window.location.href='$list_command' + options[selectedIndex].value;\">\n";
		foreach ($list as $value)
		{
			// Skip 'Lecture' if we're doing a popup for a Teaching Company sub-genre
			if (!($context == 'genre' && $ask_name == 'teach' && $value->title == 'Lecture'))
			{
				print "<option value=\"";
				switch ($context)
				{
					case 'genre':
						$key = $value->genre_id;
						break;
					case 'artist':
						$key = $value->artist_id;
						break;
					case 'album':
						$key = $value->album_id;
						break;
					case 'disc':
						$key = $value->disc_id;
						break;
				}
				print "$key\"";
				if ($key == $item_id)
				{
					print " selected";
				}
				print ">$value->title</option>\n";
			}
		}
		print "</select></td>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Bottom of popup button row
	//
	function popupRowFooter()
	{
		print "</tr>\n";
		print "</table>\n";
		print "<hr>\n";
		print "</div>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// GetCheckboxName -- Given an integer, generate a name for that checkbox.
	//
	function GetCheckboxName($num)
	{
		return sprintf("c%d", $num);
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the main file/folder list
	//
	function mainTableHeader()
	{
		print "<div class=\"tablebody\">\n";
		print "<form id=\"list\" name=\"list\" method=\"get\" action=\"$scriptName\">\n";
		print "<table align=\"center\" id=\"list\" width=\"100%\" border=\"1\" rules=\"rows\" frame=\"box\" cellpadding=\"2\" cellspacing=\"0\" frame=\"above.below\">\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// File/Folder row
	//
	function mainTableRow($ask, $play, $itemImage, $name, $nameClick, $counts)
	{
		global $darkTableColor;
		global $lightTableColor;
		global $bgcolor;
		global $checkbox_index;
		
		$checkbox_index += 1;

		print "<tr bgcolor=\"$bgcolor\">";
		if ($ask == " ")
		{
			print "<td width=\"2%\">";
			print "</td>";
		}
		else if ($ask != "")
		{
			print "<td width=\"2%\">";
			$checkName = GetCheckboxName($checkbox_index);
			print "<input type=\"checkbox\" id=\"$checkName\" name=\"$checkName\" />";
			print "</td>";
		}
		print "<td width=\"2%\">";
		
		// Top-level "all genres" view has no checkboxes
		if (strlen($ask) > 1)
		{
			print "<a target=\"_blank\" href=\"http://allmusic.com/search/$ask\">";
			print "<img src=\"images/ask.png\"></a>";
		}
		
		print "</td><td align=\"right\" width=\"2%\"><a href=\"$play\"><img src=\"images/play.png\"></a></td>";
		print "<td width=\"2%\"><img src=\"$itemImage\"></td>\n";
		if ($nameClick == "")
		{
			print "<td width=\"79%\" align=\"left\">$name</td>";
		}
		else
		{
			print "<td width=\"79%\" align=\"left\"><a href=\"$nameClick\">$name</a></td>";
		}
		print "<td align=\"right\" width=\"15%\"><font size=\"-2\">$counts</font></td><td></td>";
		print "</tr>";

		// toggle color
		if ($bgcolor == $darkTableColor)
		{
			$bgcolor = $lightTableColor;
		}
		else
		{
			$bgcolor = $darkTableColor;
		}
	}
	
	//------------------------------------------------------------------------------
	//
	// Bottom of the main file/folder list
	//
	function mainTableFooter($item_type, $item_id)
	{
		print "</table>\n";

		if ($item_type != '0')
		{
			print "<input type=\"hidden\" id=\"c\" name=\"c\" value=\"play\"/>\n";
			print "<input type=\"hidden\" id=\"p\" name=\"p\" value=\"$item_id\"/>\n";
			print "<input type=\"hidden\" id=\"t\" name=\"t\" value=\"$item_type\"/>\n";
		
			print "<table>\n<tr><td width=\"100%\" align=\"left\">";
			print "<input type=\"submit\" id=\"pl\" name=\"pl\" value=\"play checked\"/>";
			print "</td></tr>\n</table>\n";
		}
		print "</form>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Add Images
	//
	function mainTableImages($list)
	{
		global $streamBase;
	
		foreach ($list as $image)
		{
			list($img_width, $img_height) = getimagesize("$streamBase/$image->path"); 
			if ($img_width < 600)
			{
				$width = $image_width;
			}
			else
			{
				$width = 600;
			}
			print "<br>\n";
			print "<a href=\"$streamBase/$image->path\">";
			print "<img width=\"$width\" src=\"$streamBase/$image->path\"></a>\n";
		}
	}
	
	//------------------------------------------------------------------------------
	//
	// Bottom of the HTML output
	//
	function htmlFooter()
	{
		print "</div>\n";
		print "</body>\n";
		print "</html>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// EncodeString -- perform URL-encoding of potentially-offending characters
	//
	function EncodeString($str)
	{
		$tmp = rawurlencode($str);
		
		$tmp = str_replace("%2D", "-", $tmp);
		$tmp = str_replace("%2E", ".", $tmp);
		$tmp = str_replace("%2F", "/", $tmp);
		$tmp = str_replace("%5F", "_", $tmp);
	
		return $tmp;
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the playlist output
	//
	function m3uHeader($album_url, $album_title, $album_artist, $quality)
	{
		global $showQuality;
		
		// We're sending an m3u file, not an HTML document
		Header("Content-type: audio/x-mpegurl");
		Header("Content-Disposition: inline; filename=playlist.m3u");
		
		// Print ext Header
		print "#extm3u+\n";
		print "# AlbumURL: $album_url\n";
		
		if (strlen($album_title) > 0)
		{
			print "# AlbumTitle: " . html_entity_decode($album_title);
			if ($showQuality)
			{
				if ($quality == 0)
				{
					print " (cell)\n";
				}
				else if ($quality == 1)
				{
					print " (broadband)\n";
				}
				else
				{
					print " (lan)\n";
				}
			}
			else
			{
				print "\n";
			}
		}
		if (strlen($album_artist) > 0)
		{
			print "# AlbumArtist: " . html_entity_decode($album_artist) . "\n";
		}
	}
	
	//------------------------------------------------------------------------------
	//
	// Generate a playlist for an entire genre
	//
	// Response to m85x?c=playgenre&p=genre_id
	//
	function playgenre($genre_id, $quality, $checked)
	{
		global $checkbox_index;
		global $m85PlayGenre;
		
		m3uHeader("$m85PlayGenre$genre_id&q=$quality", "", "", $quality);
		
		$artists = MusicQuery::Instance()->artists_in_genre($genre_id);
		if ($checked)
		{
			foreach ($artists as $artist)
			{
				$checkbox_index += 1;
				$checkName = GetCheckboxName($checkbox_index);
				$checkVal = $_GET[$checkName];
				if ($checkVal <> '')
				{			
					artistTrackList($artist>artist_id, $artist, $quality, false);
				}
			}
		}
		else
		{
			foreach ($artists as $artist)
			{
				artistTrackList($artist>artist_id, $artist, $quality, false);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist for an entire genre of teaching company stuff
	//
	// Response to m85x?c=playteachgenre&p=genre_id
	//
	function playteachgenre($genre_id, $quality, $checked)
	{
		global $checkbox_index;
		global $m85PlayTeachGenre;
		
		m3uHeader("$m85PlayTeachGenre$genre_id&q=$quality", "", "", $quality);
		
		$albums = MusicQuery::Instance()->albums_for_teach_genre($genre_id);
		if ($checked)
		{
			foreach ($albums as $album)
			{
				$checkbox_index += 1;
				$checkName = GetCheckboxName($checkbox_index);
				$checkVal = $_GET[$checkName];
				if ($checkVal <> '')
				{			
					albumTrackList($artist>artist_id, $artist, $quality, false);
				}
			}
		}
		else
		{
			foreach ($artists as $artist)
			{
				albumTrackList($artist>artist_id, $artist, $quality, false);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// List track info & links for an artist
	//
	function artistTrackList($artist_id, $artist, $quality, $checked)
	{
		global $checkbox_index;
		
		$query = MusicQuery::Instance();

		if (is_null($artist))
		{
			$artist = $query->artist_for_id($artist_id);
		}
		$albums = $query->albums_for_artist($artist_id);
		if ($checked)
		{
			foreach ($albums as $album)
			{
				$checkbox_index += 1;
				$checkName = GetCheckboxName($checkbox_index);
				$checkVal = $_GET[$checkName];
				if ($checkVal <> '')
				{			
					albumTrackList($album->album_id, $album, $artist, $quality, false);
				}
			}
		}
		else
		{
			foreach ($albums as $album)
			{
				albumTrackList($album->album_id, $album, $artist, $quality, false);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist of all albums by a particular artist
	//
	// Response to m85x?c=playartist&p=artist_id
	//
	function playartist($artist_id, $quality, $checked)
	{
		global $m85PlayArtist;
		
		$query = MusicQuery::Instance();

		$artist = $query->artist_for_id($artist_id);

		// If we're playing the whole artist folder but there's only one
		// album, treat it as though we're just playing that album.
		$count = $query->albums_for_artist_count($artist_id);
		if ($count == 1)
		{
			$albums = $query->albumes_for_artist($artist_id);
			$album = $albums[0];
			m3uHeader("$m85PlayArtist$artist_id&q=$quality", "$album->title", "$artist->title", $quality);
		}
		else
		{
			m3uHeader("$m85PlayArtist$artist_id&q=$quality", "", "$artist->title", $quality);
		}
		
		artistTrackList($artist_id, NULL, $quality, $checked);
	}

	//------------------------------------------------------------------------------
	//
	// List track info & links for 'Various Artists' in a particular genre
	//
	function variousTrackList($genre_id, $quality, $checked)
	{
		global $checkbox_index;
		
		$query = MusicQuery::Instance();

		$artist = $query->artist_for_id($query->various_artists_id());
		$albums = $query->albums_for_various_artists_genre($genre_id);
		if ($checked)
		{
			foreach ($albums as $album)
			{
				$checkbox_index += 1;
				$checkName = GetCheckboxName($checkbox_index);
				$checkVal = $_GET[$checkName];
				if ($checkVal <> '')
				{			
					albumTrackList($album->album_id, $album, $artist, $quality, false);
				}
			}
		}
		else
		{
			foreach ($albums as $album)
			{
				albumTrackList($album->album_id, $album, $artist, $quality, false);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist of all albums by 'Various Artists' in a particular genre
	//
	// Response to m85x?c=playvarious&p=genre_id
	//
	function playvarious($genre_id, $quality, $checked)
	{
		global $m85PlayVarious;
		
		$query = MusicQuery::Instance();

		$artist = $query->artist_for_id($artist_id);

		// If we're playing the whole artist folder but there's only one
		// album, treat it as though we're just playing that album.
		$count = $query->albums_for_various_artists_genre_count($genre_id);
		if ($count == 1)
		{
			$albums = $query->albums_for_various_artists_genre($genre_id);
			$album = $albums[0];
			m3uHeader("$m85PlayVarious$genre_id&q=$quality", "$album->title", "$artist->title", $quality);
		}
		else
		{
			m3uHeader("$m85PlayVarious$genre_id&q=$quality", "", "$artist->title", $quality);
		}
		
		variousTrackList($genre_id, NULL, $quality, $checked);
	}

	//------------------------------------------------------------------------------
	//
	// List track info & links for an album
	//
	function albumTrackList($album_id, $album, $artist, $quality, $checked)
	{
		global $checkbox_index;
		
		$query = MusicQuery::Instance();

		if (is_null($album))
		{
			$album = $query->album_for_id($album_id);
		}
		if (is_null($artist))
		{
			$artists = $query->artists_for_album($album_id);
			$artist_id = $artists[0];
			$artist = $query->artist_for_id($artist_id);
		}
		if ($album->multidisc == 't')
		{
			$discs = $query->discs_for_album($album_id);
			if ($checked)
			{
				foreach ($discs as $disc)
				{
					$checkbox_index += 1;
					$checkName = GetCheckboxName($checkbox_index);
					$checkVal = $_GET[$checkName];
					if ($checkVal <> '')
					{			
						discTrackList($disc->disc_id, $disc, $album, $artist, $quality, false);
					}
				}
			}
			else
			{
				foreach ($discs as $disc)
				{
					discTrackList($disc->disc_id, $disc, $album, $artist, $quality, false);
				}
			}
		}
		else
		{
			$songs = $query->songs_for_album($album_id);
			if ($checked)
			{
				foreach ($songs as $song)
				{
					$checkbox_index += 1;
					$checkName = GetCheckboxName($checkbox_index);
					$checkVal = $_GET[$checkName];
					if ($checkVal <> '')
					{			
						songTrackList($song->song_id, $song, $album, $artist->title, null, $quality, false);
					}
				}
			}
			else
			{
				foreach ($songs as $song)
				{
					songTrackList($song->song_id, $song, $album, $artist->title, null, $quality, false);
				}
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist for the given album
	//
	// Response to m85x?c=playalbum&p=album_id
	//
	function playalbum($album_id, $quality, $checked)
	{
		global $m85PlayAlbum;
		
		$query = MusicQuery::Instance();

		$album = $query->album_for_id($album_id);
		$artists = $query->artists_for_album($album_id);
		$artist_id = $artists[0];
		$artist = $query->artist_for_id($artist_id);
		m3uHeader("$m85PlayAlbum$album_id&q=$quality", $album->title, $artist->title, $quality);
		
		albumTrackList($album_id, $album, $artist, $quality, $checked);
	}

	//------------------------------------------------------------------------------
	//
	// List track info & links for a disc
	//
	function discTrackList($disc_id, $disc, $album, $artist, $quality, $checked)
	{
		global $checkbox_index;
				
		$query = MusicQuery::Instance();

		if (is_null($disc))
		{
			$disc = $query->disc_for_id($disc_id);
		}
		$songs = $query->songs_for_disc($disc_id);
		if ($checked)
		{
			foreach ($songs as $song)
			{
				$checkbox_index += 1;
				$checkName = GetCheckboxName($checkbox_index);
				$checkVal = $_GET[$checkName];
				if ($checkVal <> '')
				{			
					if (is_null($album))
					{
						$album = $query->album_for_id($song->album_id);
					}
					if (is_null($artist))
					{
						$artists = $query->artists_for_album($album_id);
						$artist_id = $artists[0];
						$artist = $query->artist_for_id($artist_id);
					}
					songTrackList($song->song_id, $song, $album, $artist->title, $disc, $quality);
				}
			}
		}
		else
		{
			foreach ($songs as $song)
			{
				if (is_null($album))
				{
					$album = $query->album_for_id($song->album_id);
				}
				if (is_null($artist))
				{
					$artists = $query->artists_for_album($album_id);
					$artist_id = $artists[0];
					$artist = $query->artist_for_id($artist_id);
				}
				songTrackList($song->song_id, $song, $album, $artist->title, $disc, $quality);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist for a single disc of a multi-disc set
	//
	// Response to m85x?c=playdisc&p=disc_id
	//
	function playdisc($disc_id, $quality, $checked)
	{
		global $m85PlayDisc;

		$query = MusicQuery::Instance();

		$disc = $query->disc_for_id($disc_id);
		$album_id = $disc->album_id;
		$album = $query->album_for_id($album_id);
		$artists = $query->artists_for_album($album_id);
		$artist_id = $artists[0];
		$artist = $query->artist_for_id($artist_id);
		m3uHeader("$m85PlayDisc$disc_id&q=$quality", "$album->title - $disc->title", $artist->title, $quality);
		
		discTrackList($disc_id, $disc, $album, $artist, $quality, $checked);
	}

	//------------------------------------------------------------------------------
	//
	// Given a song, return an album-relative path to the file
	// with a quality as close to the requested as possible.
	//
	function songPathForQuality($song, $quality)
	{
		global $maxQuality;
		
		$name = "";
		
		if ($quality == 2 && $maxQuality > 1 && strlen($song->hd_name) > 0)
		{
			$name = "hd/$song->hd_name";
		}
		if (strlen($name) == 0 && $quality > 0 && $maxQuality > 0 && strlen($song->nl_name) > 0)
		{
			$name = "nl/$song->nl_name";
		}
		if (strlen($name) == 0 && $quality >= 0)
		{
			$name = "ls/$song->ls_name";
		}
		
		return $name;
	}
	
	//------------------------------------------------------------------------------
	//
	// Generate tag info header lines and URL line for this track.
	// Parameters for song, album & artist may be NULL but song_id and
	// $quality are expected to be valid.
	//
	function songTrackList($song_id, $song, $album, $artist_title, $disc, $quality)
	{
		global $streamBase;
		
		$query = MusicQuery::Instance();

		if (is_null($song))
		{
			$song = $query->song_for_id($song_id);
		}
		$album_id = $song->album_id;
		if (is_null($album))
		{
			$album = $query->album_for_id($album_id);
		}
		$album_path = $album->path;
		
		$path = songPathForQuality($song, $quality);

		print "# Title: " . "$song->title" . "\n";
		print "# Artist: " . "$artist_title" . "\n";
		if ($album->multidisc == 't')
		{
			print "# Album: " . "$album->title - $disc->title" . "\n";
		}
		else
		{
			print "# Album: " . "$album->title" . "\n";
		}
		print "# Duration: " . "$song->duration" . "\n";
		print "$streamBase/";
		
		print EncodeString("$album_path/");
		if ($album->multidisc == 't')
		{
			print EncodeString("$disc->name/");
		}
		print EncodeString("$path") . "\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Generate a playlist for a single track.
	//
	// Response to m85x?c=playsong&p=song_id
	//
	function playsong($song_id, $quality)
	{
		global $m85PlaySong;
		
		$query = MusicQuery::Instance();

		$song = $query->song_for_id($song_id);
		if ($song->disc_id == 0)
		{
			$disc_name = "";
		}
		else
		{
			$disc = $query->disc_for_id($song->disc_id);
			$disc_name = $disc->name;
		}
		$artists = $query->artists_for_song($song_id);
		foreach ($artists as $artist)
		{
			$artist_title = "$artist_title $artist->title";
		}
		$artist_title = trim($artist_title);
		$album_id = $song->album_id;
		$album = $query->album_for_id($album_id);
		m3uHeader("$m85PlaySong$song_id&q=$quality", $album->title, $artist->title, $quality);
		
		songTrackList($song_id, $song, $album, $artist_title, $disc, $quality);
	}
	
	//------------------------------------------------------------------------------
	//
	// Generate a playlist from checked items
	//
	function playchecked($item_id, $quality)
	{
		global $checkbox_index;
		
		$checkbox_index = 0;

		$item_type = $_GET['t'];
		switch ($item_type)
		{
			case 'g':
				playgenre($item_id, $quality, true);
				break;
			case 'd':
				playdisc($item_id, $quality, true);
				break;
			case 'l':
				playalbum($item_id, $quality, true);
				break;
			case 'r':
				playartist($item_id, $quality, true);
				break;
			case 'p':
//				playpodcast($item_id, $quality, true);
				break;
			default:
				http_response_code(404);
				break;
		}
	}
	
?>
