2023-07-30 11:50:09 -04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using SabreTools.Core ;
using SabreTools.DatItems ;
using SabreTools.DatItems.Formats ;
namespace SabreTools.DatFiles.Formats
{
/// <summary>
/// Represents writing a RomCenter INI file
/// </summary>
internal partial class RomCenter : DatFile
{
/// <inheritdoc/>
protected override ItemType [ ] GetSupportedTypes ( )
{
2024-02-28 19:19:50 -05:00
return
[
2023-07-30 11:50:09 -04:00
ItemType . Rom
2024-02-28 19:19:50 -05:00
] ;
2023-07-30 11:50:09 -04:00
}
/// <inheritdoc/>
2024-03-05 23:41:00 -05:00
protected override List < string > ? GetMissingRequiredFields ( DatItem datItem )
2023-07-30 11:50:09 -04:00
{
2024-03-05 23:41:00 -05:00
var missingFields = new List < string > ( ) ;
2023-07-30 11:50:09 -04:00
// Check item name
2024-02-28 22:54:56 -05:00
if ( string . IsNullOrEmpty ( datItem . GetName ( ) ) )
2024-03-05 23:41:00 -05:00
missingFields . Add ( Models . Metadata . Rom . NameKey ) ;
2023-07-30 11:50:09 -04:00
switch ( datItem )
{
case Rom rom :
2024-03-09 21:34:26 -05:00
if ( string . IsNullOrEmpty ( rom . GetFieldValue < string? > ( Models . Metadata . Rom . CRCKey ) ) )
2024-03-05 23:41:00 -05:00
missingFields . Add ( Models . Metadata . Rom . CRCKey ) ;
2024-03-09 21:34:26 -05:00
if ( rom . GetFieldValue < long? > ( Models . Metadata . Rom . SizeKey ) = = null )
2024-03-05 23:41:00 -05:00
missingFields . Add ( Models . Metadata . Rom . SizeKey ) ;
2023-07-30 11:50:09 -04:00
break ;
}
return missingFields ;
}
/// <inheritdoc/>
public override bool WriteToFile ( string outfile , bool ignoreblanks = false , bool throwOnError = false )
{
try
{
logger . User ( $"Writing to '{outfile}'..." ) ;
var metadataFile = CreateMetadataFile ( ignoreblanks ) ;
2023-09-11 01:20:21 -04:00
if ( ! ( new Serialization . Files . RomCenter ( ) . Serialize ( metadataFile , outfile ) ) )
2023-07-30 11:50:09 -04:00
{
logger . Warning ( $"File '{outfile}' could not be written! See the log for more details." ) ;
return false ;
}
}
catch ( Exception ex ) when ( ! throwOnError )
{
logger . Error ( ex ) ;
return false ;
}
2023-07-31 11:33:03 -04:00
logger . User ( $"'{outfile}' written!{Environment.NewLine}" ) ;
2023-07-30 11:50:09 -04:00
return true ;
}
#region Converters
/// <summary>
/// Create a MetadataFile from the current internal information
/// <summary>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
private Models . RomCenter . MetadataFile CreateMetadataFile ( bool ignoreblanks )
{
var metadataFile = new Models . RomCenter . MetadataFile
{
Credits = CreateCredits ( ) ,
Dat = CreateDat ( ) ,
Emulator = CreateEmulator ( ) ,
Games = CreateGames ( ignoreblanks ) ,
} ;
return metadataFile ;
}
/// <summary>
/// Create a Credits from the current internal information
/// <summary>
private Models . RomCenter . Credits CreateCredits ( )
{
var credits = new Models . RomCenter . Credits
{
2024-03-10 04:10:37 -04:00
Author = Header . GetFieldValue < string? > ( Models . Metadata . Header . AuthorKey ) ,
Version = Header . GetFieldValue < string? > ( Models . Metadata . Header . VersionKey ) ,
Email = Header . GetFieldValue < string? > ( Models . Metadata . Header . EmailKey ) ,
Homepage = Header . GetFieldValue < string? > ( Models . Metadata . Header . HomepageKey ) ,
Url = Header . GetFieldValue < string? > ( Models . Metadata . Header . UrlKey ) ,
Date = Header . GetFieldValue < string? > ( Models . Metadata . Header . DateKey ) ,
Comment = Header . GetFieldValue < string? > ( Models . Metadata . Header . CommentKey ) ,
2023-07-30 11:50:09 -04:00
} ;
return credits ;
}
/// <summary>
/// Create a Dat from the current internal information
/// <summary>
private Models . RomCenter . Dat CreateDat ( )
{
var dat = new Models . RomCenter . Dat
{
2024-03-10 04:10:37 -04:00
Version = Header . GetFieldValue < string? > ( Models . Metadata . Header . DatVersionKey ) ,
Plugin = Header . GetFieldValue < string? > ( Models . Metadata . Header . SystemKey ) ,
Split = ( Header . GetFieldValue < MergingFlag > ( Models . Metadata . Header . ForceMergingKey ) = = MergingFlag . Split ? "1" : "0" ) ,
Merge = ( Header . GetFieldValue < MergingFlag > ( Models . Metadata . Header . ForceMergingKey ) = = MergingFlag . Merged | | Header . GetFieldValue < MergingFlag > ( Models . Metadata . Header . ForceMergingKey ) = = MergingFlag . FullMerged ? "1" : "0" ) ,
2023-07-30 11:50:09 -04:00
} ;
return dat ;
}
/// <summary>
/// Create a Emulator from the current internal information
/// <summary>
private Models . RomCenter . Emulator CreateEmulator ( )
{
var emulator = new Models . RomCenter . Emulator
{
2024-03-10 04:10:37 -04:00
RefName = Header . GetFieldValue < string? > ( Models . Metadata . Header . NameKey ) ,
Version = Header . GetFieldValue < string? > ( Models . Metadata . Header . DescriptionKey ) ,
2023-07-30 11:50:09 -04:00
} ;
return emulator ;
}
/// <summary>
/// Create a Games from the current internal information
/// <summary>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
2023-08-10 23:22:14 -04:00
private Models . RomCenter . Games ? CreateGames ( bool ignoreblanks )
2023-07-30 11:50:09 -04:00
{
// If we don't have items, we can't do anything
if ( this . Items = = null | | ! this . Items . Any ( ) )
return null ;
// Create a list of hold the roms
var roms = new List < Models . RomCenter . Rom > ( ) ;
// Loop through the sorted items and create games for them
foreach ( string key in Items . SortedKeys )
{
var items = Items . FilteredItems ( key ) ;
if ( items = = null | | ! items . Any ( ) )
continue ;
// Loop through and convert the items to respective lists
2023-07-30 23:50:55 -04:00
for ( int index = 0 ; index < items . Count ; index + + )
2023-07-30 11:50:09 -04:00
{
2023-07-30 23:50:55 -04:00
// Get the item
var item = items [ index ] ;
// Check for a "null" item
item = ProcessNullifiedItem ( item ) ;
2023-07-30 11:50:09 -04:00
// Skip if we're ignoring the item
if ( ShouldIgnore ( item , ignoreblanks ) )
continue ;
switch ( item )
{
case Rom rom :
roms . Add ( CreateRom ( rom ) ) ;
break ;
}
}
}
2024-02-28 19:19:50 -05:00
return new Models . RomCenter . Games { Rom = [ . . roms ] } ;
2023-07-30 11:50:09 -04:00
}
/// <summary>
/// Create a Rom from the current Rom DatItem
/// <summary>
private static Models . RomCenter . Rom CreateRom ( Rom item )
{
var rom = new Models . RomCenter . Rom
{
2024-03-10 16:49:07 -04:00
ParentName = item . GetFieldValue < Machine > ( DatItem . MachineKey ) ! . GetFieldValue < string? > ( Models . Metadata . Machine . CloneOfKey ) ,
//ParentDescription = item.GetFieldValue<Machine>(DatItem.MachineKey)!.GetFieldValue<string?>(Models.Metadata.Machine.CloneOfDescription), // TODO: Add to internal model or find mapping
GameName = item . GetFieldValue < Machine > ( DatItem . MachineKey ) ! . GetFieldValue < string? > ( Models . Metadata . Machine . NameKey ) ,
GameDescription = item . GetFieldValue < Machine > ( DatItem . MachineKey ) ! . GetFieldValue < string? > ( Models . Metadata . Machine . DescriptionKey ) ,
2024-03-08 20:42:24 -05:00
RomName = item . GetName ( ) ,
2024-03-09 21:34:26 -05:00
RomCRC = item . GetFieldValue < string? > ( Models . Metadata . Rom . CRCKey ) ,
RomSize = item . GetFieldValue < long? > ( Models . Metadata . Rom . SizeKey ) ? . ToString ( ) ,
2024-03-10 16:49:07 -04:00
RomOf = item . GetFieldValue < Machine > ( DatItem . MachineKey ) ! . GetFieldValue < string? > ( Models . Metadata . Machine . RomOfKey ) ,
2024-03-09 21:34:26 -05:00
MergeName = item . GetFieldValue < string? > ( Models . Metadata . Rom . MergeKey ) ,
2023-07-30 11:50:09 -04:00
} ;
return rom ;
}
#endregion
}
}