<?php
	//
	// m85x -- a music server script
	//
	// A single script that implements a music browser. Assuming access
	// to an earfull query server, m85x uses earlfull query APIs to
	// generate an interactive music browser.
	//
	
	$debugSQL = false;
	
	$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=";
	$m85Podcasts		= "$scriptBase?c=podcasts&p=";
	$m85ListAlbum		= "$scriptBase?c=album&p=";
	$m85ListDisc		= "$scriptBase?c=disc&p=";
	$m85PlayGenre		= "$scriptBase?c=playgenre&p=";
	$m85PlayArtist		= "$scriptBase?c=playartist&p=";
	$m85PlayAlbum		= "$scriptBase?c=playalbum&p=";
	$m85PlayDisc		= "$scriptBase?c=playdisc&p=";
	$m85PlaySong		= "$scriptBase?c=playsong&p=";
	
	//
	// earfull query rest commands
	//
	$queryBase					= "https://musicquery.pairoducks.com:236";
	$cmdGenreList 				= "$queryBase/genrelist";
	$cmdGenreCount 				= "$queryBase/genrecount";
	$cmdArtistsInGenre			= "$queryBase/artistsingenre?genre_id=";
	$cmdAlbumsInGenre			= "$queryBase/albumsingenre?genre_id=";
	$cmdAlbumsInGenreCount		= "$queryBase/albumsingenrecount?genre_id=";
	$cmdArtistsInGenreCount		= "$queryBase/artistsingenrecount?genre_id=";
	$cmdGenresForArtist			= "$queryBase/genresforartist?artist_id=";
	$cmdAlbumsForArtist			= "$queryBase/albumsforartist?artist_id=";
	$cmdAlbumsForArtistCount	= "$queryBase/albumsforartistcount?artist_id=";
	$cmdGenresForAlbum			= "$queryBase/genresforalbum?album_id=";
	$cmdDiscsForAlbum			= "$queryBase/discsforalbum?album_id=";
	$cmdDiscsForAlbumCount		= "$queryBase/discsforalbumcount?album_id=";
	$cmdSongsForDisc			= "$queryBase/songsfordisc?disc_id=";
	$cmdSongsForDiscCount		= "$queryBase/songsfordisccount?disc_id=";
	$cmdSongsForAlbum			= "$queryBase/songsforalbum?album_id=";
	$cmdSongsForAlbumCount		= "$queryBase/songsforalbumcount?album_id=";
	$cmdGenreForId				= "$queryBase/genreforid?genre_id=";
	$cmdArtistForId				= "$queryBase/artistforid?artist_id=";
	$cmdAlbumForId				= "$queryBase/albumforid?album_id=";
	$cmdDiscForId				= "$queryBase/discforid?disc_id=";
	$cmdSongForId				= "$queryBase/songforid?song_id=";
	$cmdImagesForArtist			= "$queryBase/imagesforartist?artist_id=";
	$cmdImagesForAlbum			= "$queryBase/imagesforalbum?album_id=";
	$cmdImagesForDisc			= "$queryBase/imagesfordisc?disc_id=";
	$cmdArtistsForAlbum			= "$queryBase/artistsforalbum?album_id=";
	$cmdArtistsForSong			= "$queryBase/artistsforsong?song_id=";
	$cmdSinglesSongs			= "$queryBase/singlessongs";
	$cmdSinglesSongsCount		= "$queryBase/singlessongscount";
	$cmdSinglesAlbumId			= "$queryBase/singlesalbumid";
	
	//
	// 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;
	
	// 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 'playgenre':
			playgenre($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:
			genreList();
	}
	
	// end of main
	

	//------------------------------------------------------------------------------
	//
	// Use curl to make a rest call to the query server,
	// decode the JSON that's returned
	//
	function restCall($url)
	{
		global $debugSQL;
		
		if ($debugSQL)
			print "restCall($url)\n";
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$jsonstr = curl_exec($curl);
		curl_close($curl);
		if ($debugSQL)
			print "restCall result:$jsonstr\n";
		
		return json_decode($jsonstr);
	}
	
	//------------------------------------------------------------------------------
	//
	// 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
	//
	function disc($disc_id)
	{
		global $cmdDiscForId;
		global $cmdAlbumForId;
		global $cmdSongsForDisc;
		global $cmdImagesForDisc;
		global $cmdDiscsForAlbum;
		global $m85PlayDisc;
		global $m85PlaySong;
		global $m85ListDisc;
		
		htmlHeader();
		tableHeader();
		tableEntryDisc($disc_id);
		tableFooter();
		popupRowHeader();
		$disc = restCall("$cmdDiscForId"."$disc_id");
		$album_id = $disc->album_id;
		popupRowComplex('disc', "", "$cmdDiscsForAlbum$album_id", $m85PlayDisc, $m85ListDisc, $disc_id);
		popupRowFooter();

		mainTableHeader();
		
		$songs = restCall("$cmdSongsForDisc"."$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("$cmdImagesForDisc$disc_id");
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of the given album
	//
	function album($album_id)
	{
		global $m85PlaySong;
		global $m85ListAlbum;
		global $m85PlayAlbum;
		global $m85ListDisc;
		global $m85PlayDisc;
		global $cmdAlbumsForArtist;
		global $cmdSongsForAlbum;
		global $cmdAlbumForId;
		global $cmdImagesForAlbum;
		global $cmdDiscsForAlbum;
		global $cmdArtistsForAlbum;

		htmlHeader();
		tableHeader();
		tableEntryAlbum($album_id);
		tableFooter();
		popupRowHeader();
		$album = restCall("$cmdAlbumForId"."$album_id");
		$response = restCall("$cmdArtistsForAlbum"."$album_id");
		$artist_id = $response[0];
		if ($album->title == 'Singles')
		{
			popupRowSimple();
		}
		else
		{
			popupRowComplex('album', "", "$cmdAlbumsForArtist$artist_id", $m85PlayAlbum, $m85ListAlbum, $album_id);
		}
		popupRowFooter();

		mainTableHeader();
		
		if ($album->multidisc == 't')
		{
			$discs = restCall("$cmdDiscsForAlbum"."$album_id");
			foreach ($discs as $disc)
			{
				mainTableRow("", "$m85PlayDisc"."$disc->disc_id", "images/folder.png", "$disc->title", "$m85ListDisc"."$disc->disc_id", "");
			}
		}
		else
		{
			$songs = restCall("$cmdSongsForAlbum"."$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("$cmdImagesForAlbum$album_id");
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display the contents of the given album
	//
	function podcasts($genre_id)
	{
		global $m85PlayAlbum;
		global $m85ListAlbum;
		global $cmdAlbumsInGenre;
		global $cmdArtistsInGenre;
		global $cmdDiscsForAlbum;
		global $cmdSongsForDiscCount;
		global $cmdSongsForAlbumCount;

		htmlHeader();
		tableHeader();
 		tableFooter();
		popupRowHeader();
		popupRowSimple();
		popupRowFooter();
		
		mainTableHeader();
		$response = restCall("$cmdAlbumsInGenre"."$genre_id");
		foreach ($response as $album)
		{
			if ($album->multidisc == "t")
			{
				$count = 0;
				$discs = restCall("$cmdDiscsForAlbum"."$album->album_id");
				foreach ($discs as $disc)
				{
					$trackCount = restCall("$cmdSongsForDiscCount"."$disc->disc_id");
					$count = $count + $trackCount->count;
				}
			}
			else
			{
				$response2 = restCall("$cmdSongsForAlbumCount"."$album->album_id");
				$count = $response2->count;
			}
			$title = $album->title;
			if (!is_null($album->date))
			{
				$year = $album->date;
			}
			else
			{
				$year = $album->year;
			}
			
			$countText = "$count tracks";
			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;
		global $cmdAlbumsForArtist;
		global $cmdArtistsInGenre;
		global $cmdDiscsForAlbum;
		global $cmdSongsForDiscCount;
		global $cmdSongsForAlbumCount;
		global $cmdGenresForArtist;
		global $cmdArtistForId;
		global $cmdImagesForArtist;

		htmlHeader();
		tableHeader();
		tableEntryArtist($artist_id);
		tableFooter();
		popupRowHeader();
		$genres = restCall("$cmdGenresForArtist"."$artist_id");
		$genre_id = 0;
		foreach ($genres as $genre)
		{
			$genre_id = $genre->genre_id;
		}
		$artist = restCall("$cmdArtistForId"."$artist_id");
		popupRowComplex('artist', "$artist->title", "$cmdArtistsInGenre$genre_id", $m85PlayArtist, $m85ListArtist, $artist_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = restCall("$cmdAlbumsForArtist"."$artist_id");
		foreach ($response as $album)
		{
			if ($album->multidisc == "t")
			{
				$count = 0;
				$discs = restCall("$cmdDiscsForAlbum"."$album->album_id");
				foreach ($discs as $disc)
				{
					$trackCount = restCall("$cmdSongsForDiscCount"."$disc->disc_id");
					$count = $count + $trackCount->count;
				}
			}
			else
			{
				$response2 = restCall("$cmdSongsForAlbumCount"."$album->album_id");
				$count = $response2->count;
			}
			$title = $album->title;
			if (!is_null($album->date))
			{
				$year = $album->date;
			}
			else
			{
				$year = $album->year;
			}
			
			$countText = "$count tracks";
			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("$cmdImagesForArtist$artist_id");
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display all of the artists in the given genre
	//
	function genre($genre_id)
	{
		global $m85ListGenre;
		global $m85PlayGenre;
		global $m85PlayArtist;
		global $m85ListArtist;
		global $cmdArtistsInGenre;
		global $cmdAlbumsForArtistCount;
		global $cmdGenreList;

		htmlHeader();
		tableHeader();
		tableEntryGenre($genre_id);
		tableFooter();
		popupRowHeader();
		popupRowComplex('genre', "", $cmdGenreList, $m85PlayGenre, $m85ListGenre, $genre_id);
		popupRowFooter();
		
		mainTableHeader();
		$response = restCall("$cmdArtistsInGenre"."$genre_id");
		foreach ($response as $artist)
		{
			$count = $artist->count;
			$title = $artist->title;
			$countText = "$count album";
			if ($count > 1)
			{
				$countText = $countText . "s";
			}
			$ask = "artist/$title";
			mainTableRow("$ask", "$m85PlayArtist"."$artist->artist_id", "images/folder.png", "$title", "$m85ListArtist"."$artist->artist_id", "$countText");
		}
		mainTableFooter('g', $genre_id);
		htmlFooter();
	}
	
	//------------------------------------------------------------------------------
	//
	// Display a list of genres
	//
	function genreList()
	{
 		global $cmdGenreList;
		global $m85PlayGenre;
		global $m85ListGenre;
		global $cmdGenreList;
		global $cmdArtistsInGenreCount;
		global $cmdAlbumsInGenreCount;
		global $m85Podcasts;
		global $cmdSinglesSongsCount;
		global $m85PlayAlbum;
		global $m85ListAlbum;
		global $cmdSinglesAlbumId;

		htmlHeader();
		tableHeader();
		tableFooter();
		popupRowHeader();
		popupRowSimple();
		popupRowFooter();
		
		mainTableHeader();
		
		// List all the music genres
		$response = restCall($cmdGenreList);
		$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))
			{
				$countResult = restCall("$cmdArtistsInGenreCount"."$genre->genre_id");
				$count = $countResult->count;
				$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
		$countResult = restCall("$cmdSinglesSongsCount");
		$count = $countResult->count;
		$countText = "$count tracks";
		$album = restCall("$cmdSinglesAlbumId");
		mainTableRow("", "$m85PlayAlbum"."$album->album_id", "images/folder.png", "Singles", "$m85ListAlbum"."$album->album_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')
				{
					$countResult = restCall("$cmdAlbumsInGenreCount"."$genre->genre_id");
					$count = $countResult->count;
					$countText = "$count podcast";
				}
				else
				{
					$countResult = restCall("$cmdArtistsInGenreCount"."$genre->genre_id");
					$count = $countResult->count;
					$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 $cmdGenreList;

		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://music.pairoducks.com/pdm.png\">";
		print "<title>music</title>\n";
		print "<style>\n";
		print "a:link { color: #3333ee; text-decoration: none; ! important }\n";
		print "a:hover { color: navy; text-decoration: none; ! important }\n";
		print "a:visited { color: ee3333; text-decoration: none; ! important }\n";
		print "</style>\n";

		print "</head>\n";
		print "<body bgcolor=\"$pageBackground\">\n";
		
		print "<table align=\"center\" id=\"header\" width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the "path" bar
	//
	function tableHeader()
	{
		global $cmdGenreList;
		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 $cmdGenresForAlbum;
		global $cmdArtistsForAlbum;
		global $m85ListGenre;
		global $m85ListArtist;
		global $m85ListAlbum;
		global $m85ListDisc;
		global $cmdAlbumForId;
		global $cmdArtistForId;
		global $cmdDiscForId;
		
		$disc = restCall("$cmdDiscForId"."$disc_id");
		$album_id = $disc->album_id;
		$genres = restCall("$cmdGenresForAlbum"."$album_id");
		foreach ($genres as $genre)
		{
			print " / <a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
		}
		
		$album = restCall("$cmdAlbumForId"."$album_id");
		$album_title = $album->title;
		$artistList = restCall("$cmdArtistsForAlbum"."$album_id");
		foreach ($artistList as $artist_id)
		{
			$artist = restCall("$cmdArtistForId"."$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 albums
	//
	function tableEntryAlbum($album_id)
	{
		global $cmdGenresForAlbum;
		global $m85ListGenre;
		global $m85ListArtist;
		global $m85ListAlbum;
		global $cmdAlbumForId;
		global $cmdArtistForId;
		global $cmdArtistsForAlbum;
		
		$genres = restCall("$cmdGenresForAlbum"."$album_id");
		foreach ($genres as $genre)
		{
			print " / <a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
		}
		
		$album = restCall("$cmdAlbumForId"."$album_id");
		$album_title = $album->title;
		$response = restCall("$cmdArtistsForAlbum"."$album_id");
		$artist_id = $response[0];
		$artist = restCall("$cmdArtistForId"."$artist_id");
		$title = $artist->title;
		if ($album->title != 'Singles')
		{
			print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
		}
		print " / <a href=\"$m85ListAlbum$album_id\">$album_title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for artists
	//
	function tableEntryArtist($artist_id)
	{
		global $cmdGenresForArtist;
		global $m85ListGenre;
		global $m85ListArtist;
		global $cmdArtistForId;
		
		$genres = restCall("$cmdGenresForArtist"."$artist_id");
		foreach ($genres as $genre)
		{
			print " / <a href=\"$m85ListGenre$genre->genre_id\">$genre->title</a>";
		}
		
		$artist = restCall("$cmdArtistForId"."$artist_id");
		$title = $artist->title;
		print " / <a href=\"$m85ListArtist$artist_id\">$title</a>";
	}
			
	//------------------------------------------------------------------------------
	//
	// Path Bar for genres
	//
	function tableEntryGenre($genre_id)
	{
		global $m85ListGenre;
		global $cmdGenreForId;
		
		$genre = restCall("$cmdGenreForId$genre_id");
		print " / <a href=\"$m85ListGenre$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";
		print "<hr>\n";
	}
	
	//------------------------------------------------------------------------------
	//
	// Top of the popup button row
	//
	function popupRowHeader()
	{
		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_top_command, $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";
		$response = restCall($list_top_command);
		foreach ($response as $value)
		{
			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";
	}
	
	//------------------------------------------------------------------------------
	//
	// 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 "<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%\">";
			$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) > 0)
		{
			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($cmd)
	{
		global $streamBase;
	
		$response = restCall($cmd);
		foreach ($response 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 "</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 $cmdArtistsInGenre;
		global $checkbox_index;
		
		m3uHeader("$m85PlayGenre$genre_id&q=$quality", "", "", $quality);
		
		$artists = restCall("$cmdArtistsInGenre"."$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);
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// List track info & links for an artist
	//
	function artistTrackList($artist_id, $artist, $quality, $checked)
	{
		global $cmdArtistForId;
		global $cmdAlbumsForArtist;
		global $checkbox_index;

		if (is_null($artist))
		{
			$artist = restCall("$cmdArtistForId"."$artist_id");
		}
		$albums = restCall("$cmdAlbumsForArtist"."$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;
		global $cmdAlbumsForArtistCount;
		global $cmdAlbumsForArtist;
		global $cmdArtistForId;
		
		$artist = restCall("$cmdArtistForId"."$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.
		$response = restCall("$cmdAlbumsForArtistCount"."$artist_id");
		$count = $response->count;
		if ($count == 1)
		{
			$albums = restCall("$cmdAlbumsForArtist"."$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 an album
	//
	function albumTrackList($album_id, $album, $artist, $quality, $checked)
	{
		global $cmdAlbumForId;
		global $cmdDiscsForAlbum;
		global $cmdSongsForAlbum;
		global $cmdArtistForId;
		global $checkbox_index;
		
		if (is_null($album))
		{
			$album = restCall("$cmdAlbumForId"."$album_id");
		}
		if (is_null($artist))
		{
			$artist = restCall("$cmdArtistForId"."$album->artist_id");
		}
		if ($album->multidisc == 't')
		{
			$discs = restCall("$cmdDiscsForAlbum"."$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 = restCall("$cmdSongsForAlbum"."$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, "", $quality, false);
					}
				}
			}
			else
			{
				foreach ($songs as $song)
				{
					songTrackList($song->song_id, $song, $album, $artist, "", $quality, false);
				}
			}
		}
	}

	//------------------------------------------------------------------------------
	//
	// Generate a playlist for the given album
	//
	// Response to m85x?c=playalbum&p=album_id
	//
	function playalbum($album_id, $quality, $checked)
	{
		global $cmdAlbumForId;
		global $cmdArtistForId;
		global $cmdArtistsForAlbum;
		global $m85PlayAlbum;
		
		$album = restCall("$cmdAlbumForId"."$album_id");
		$artists = restCall("$cmdArtistsForAlbum"."$album_id");
		$artist_id = $artists[0];
		$artist = restCall("$cmdArtistForId"."$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 $cmdSongsForDisc;
		global $cmdAlbumForId;
		global $cmdArtistForId;
		global $cmdDiscForId;
		global $checkbox_index;
				
		if (is_null($disc))
		{
			$disc = restCall("$cmdDiscForId"."$disc_id");
		}
		$songs = restCall("$cmdSongsForDisc"."$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 = restCall("$cmdAlbumForId"."$song->album_id");
					}
					if (is_null($artist))
					{
						$artist = restCall("$cmdArtistForId"."$song->artist_id");
					}
					songTrackList($song->song_id, $song, $album, $artist, $disc->name, $quality);
				}
			}
		}
		else
		{
			foreach ($songs as $song)
			{
				if (is_null($album))
				{
					$album = restCall("$cmdAlbumForId"."$song->album_id");
				}
				if (is_null($artist))
				{
					$artist = restCall("$cmdArtistForId"."$song->artist_id");
				}
				songTrackList($song->song_id, $song, $album, $artist, $disc->name, $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;
		global $cmdDiscForId;
		global $cmdAlbumForId;
		global $cmdArtistForId;

		$disc = restCall("$cmdDiscForId"."$disc_id");
		$album_id = $disc->album_id;
		$album = restCall("$cmdAlbumForId"."$album_id");
		$artist_id = $album->artist_id;
		$artist = restCall("$cmdArtistForId"."$artist_id");
		m3uHeader("$m85PlayDisc$disc_id&q=$quality", $album->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, $disc_name, $quality)
	{
		global $streamBase;
		global $cmdSongForId;
		global $cmdAlbumForId;
		global $cmdArtistForId;
		global $cmdArtistsForSong;
		
		if (is_null($song))
		{
			$song = restCall("$cmdSongForId"."$song_id");
		}
		$album_id = $song->album_id;
		if (is_null($album))
		{
			$album = restCall("$cmdAlbumForId"."$album_id");
		}
		$album_path = $album->path;
		$artist_id = $artist->artist_id;
		if (is_null($artist))
		{
			$artist = restCall("$cmdArtistForId"."$artist_id");
		}
		
		$path = songPathForQuality($song, $quality);

		print "# Title: " . "$song->title" . "\n";
		print "# Artist: " . "$artist->title" . "\n";
		print "# Album: " . "$album->title" . "\n";
		print "# Duration: " . "$song->duration" . "\n";
		print "$streamBase/";
		
		print EncodeString("$album_path/");
		if (strlen($disc_name) > 0)
		{
			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;
		global $cmdAlbumForId;
		global $cmdSongForId;
		
		$song = restCall("$cmdSongForId"."$song_id");
		$album_id = $song->album_id;
		$artist_id = $song->artist_id;
		$album = restCall("$cmdAlbumForId"."$album_id");
		$artist = restCall("$cmdArtistForId"."$artist_id");
		m3uHeader("$m85PlaySong$song_id&q=$quality", $album->title, $artist->title, $quality);
		
		songTrackList($song_id, $song, $album, $artist, "", $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;
		}
	}
	
?>
