using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.Decoders.CD;
using Aaru.Helpers;
using CSCore.Codecs.WAV;
using ReactiveUI;
using static Aaru.Decoders.CD.FullTOC;
namespace RedBookPlayer.Models.Discs
{
public class CompactDisc : OpticalDiscBase, IReactiveObject
{
#region Public Fields
///
public override int CurrentTrackNumber
{
get => _currentTrackNumber;
protected set
{
// Unset image means we can't do anything
if(_image == null)
return;
// Invalid value means we can't do anything
if (value > _image.Tracks.Max(t => t.TrackSequence))
return;
else if (value < _image.Tracks.Min(t => t.TrackSequence))
return;
// Cache the current track for easy access
Track track = GetTrack(value);
if(track == null)
return;
// Set all track flags and values
SetTrackFlags(track);
TotalIndexes = track.Indexes.Keys.Max();
CurrentTrackIndex = track.Indexes.Keys.Min();
CurrentTrackSession = track.TrackSession;
// Mark the track as changed
this.RaiseAndSetIfChanged(ref _currentTrackNumber, value);
}
}
///
public override ushort CurrentTrackIndex
{
get => _currentTrackIndex;
protected set
{
// Unset image means we can't do anything
if(_image == null)
return;
// Cache the current track for easy access
Track track = GetTrack(CurrentTrackNumber);
if(track == null)
return;
// Invalid value means we can't do anything
if (value > track.Indexes.Keys.Max())
return;
else if (value < track.Indexes.Keys.Min())
return;
this.RaiseAndSetIfChanged(ref _currentTrackIndex, value);
// Set new index-specific data
SectionStartSector = (ulong)track.Indexes[CurrentTrackIndex];
TotalTime = track.TrackEndSector - track.TrackStartSector;
}
}
///
public override ushort CurrentTrackSession
{
get => _currentTrackSession;
protected set => this.RaiseAndSetIfChanged(ref _currentTrackSession, value);
}
///
public override ulong CurrentSector
{
get => _currentSector;
protected set
{
// Unset image means we can't do anything
if(_image == null)
return;
// Invalid value means we can't do anything
if(value > _image.Info.Sectors)
return;
else if(value < 0)
return;
// Cache the current track for easy access
Track track = GetTrack(CurrentTrackNumber);
if(track == null)
return;
this.RaiseAndSetIfChanged(ref _currentSector, value);
// If the current sector is outside of the last known track, seek to the right one
if(CurrentSector < track.TrackStartSector || CurrentSector > track.TrackEndSector)
{
track = _image.Tracks.Last(t => CurrentSector >= t.TrackStartSector);
CurrentTrackNumber = (int)track.TrackSequence;
}
// Set the new index, if necessary
foreach((ushort key, int i) in track.Indexes.Reverse())
{
if((int)CurrentSector >= i)
{
CurrentTrackIndex = key;
return;
}
}
CurrentTrackIndex = 0;
}
}
///
public override int BytesPerSector => GetTrack(CurrentTrackNumber)?.TrackRawBytesPerSector ?? 0;
///
/// Readonly list of all tracks in the image
///
public List