using System.IO;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Metadata;
using Aaru.DiscImages;
using Aaru.Filters;
namespace RedBookPlayer.Common.Discs
{
public static class OpticalDiscFactory
{
///
/// Generate an OpticalDisc from an input path
///
/// Path to load the image from
/// Generate a TOC if the disc is missing one [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
public static OpticalDisc GenerateFromPath(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
{
try
{
// Validate the image exists
if(string.IsNullOrWhiteSpace(path) || !File.Exists(path))
return null;
// Load the disc image to memory
// TODO: Assumes Aaruformat right now for all
var image = new AaruFormat();
var filter = new ZZZNoFilter();
filter.Open(path);
image.Open(filter);
// Generate and instantiate the disc
return GenerateFromImage(image, generateMissingToc, loadDataTracks, autoPlay);
}
catch
{
// All errors mean an invalid image in some way
return null;
}
}
///
/// Generate an OpticalDisc from an input IOpticalMediaImage
///
/// IOpticalMediaImage to create from
/// Generate a TOC if the disc is missing one [CompactDisc only]
/// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
{
// If the image is not usable, we don't do anything
if(!IsUsableImage(image))
return null;
// Create the output object
OpticalDisc opticalDisc;
// Create the proper disc type
switch(GetMediaType(image))
{
case "Compact Disc":
case "GD":
opticalDisc = new CompactDisc(generateMissingToc, loadDataTracks);
break;
default:
opticalDisc = null;
break;
}
// Null image means we don't do anything
if(opticalDisc == null)
return opticalDisc;
// Instantiate the disc and return
opticalDisc.Init(image, autoPlay);
return opticalDisc;
}
///
/// Gets the human-readable media type from an image
///
/// Media image to check
/// Type from the image, empty string on error
/// TODO: Can we be more granular with sub types?
private static string GetMediaType(IOpticalMediaImage image)
{
// Null image means we don't do anything
if(image == null)
return string.Empty;
(string type, string _) = MediaType.MediaTypeToString(image.Info.MediaType);
return type;
}
///
/// Indicates if the image is considered "usable" or not
///
/// Aaruformat image file
/// True if the image is playble, false otherwise
private static bool IsUsableImage(IOpticalMediaImage image)
{
// Invalid images can't be used
if(image == null)
return false;
// Determine based on media type
return GetMediaType(image) switch
{
"Compact Disc" => true,
"GD" => true, // Requires TOC generation
_ => false,
};
}
}
}