2016-07-09 22:30:12 +00:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2017-05-12 04:34:18 +00:00
using System.Reflection ;
2016-07-09 22:30:12 +00:00
2017-01-08 07:54:09 +00:00
namespace PKHeX.Core
2016-07-09 22:30:12 +00:00
{
public partial class Util
{
2017-03-24 17:59:45 +00:00
private const string TranslationSplitter = " = " ;
2016-10-06 04:06:24 +00:00
#region String Lists
2016-08-08 20:11:02 +00:00
/// <summary>
/// Gets a list of all Pokémon species names.
/// </summary>
/// <param name="language">Language of the Pokémon species names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon species name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetSpeciesList ( string language )
2016-08-08 20:11:02 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "species" , language ) ;
2016-08-08 20:11:02 +00:00
}
/// <summary>
/// Gets a list of all move names.
/// </summary>
/// <param name="language">Language of the move names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each move name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetMovesList ( string language )
2016-08-08 20:11:02 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "moves" , language ) ;
2016-08-08 20:11:02 +00:00
}
/// <summary>
/// Gets a list of all Pokémon ability names.
/// </summary>
/// <param name="language">Language of the Pokémon ability names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon ability name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetAbilitiesList ( string language )
2016-08-08 20:11:02 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "abilities" , language ) ;
2016-08-08 20:11:02 +00:00
}
2016-10-06 04:06:24 +00:00
/// <summary>
/// Gets a list of all Pokémon nature names.
/// </summary>
/// <param name="language">Language of the Pokémon nature names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon nature name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetNaturesList ( string language )
2016-10-06 04:06:24 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "natures" , language ) ;
2016-10-06 04:06:24 +00:00
}
/// <summary>
/// Gets a list of all Pokémon form names.
/// </summary>
/// <param name="language">Language of the Pokémon form names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon form name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetFormsList ( string language )
2016-10-06 04:06:24 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "forms" , language ) ;
2016-10-06 04:06:24 +00:00
}
/// <summary>
/// Gets a list of all Pokémon type names.
/// </summary>
/// <param name="language">Language of the Pokémon type names to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon type name.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetTypesList ( string language )
2016-10-06 04:06:24 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "types" , language ) ;
2016-10-06 04:06:24 +00:00
}
/// <summary>
/// Gets a list of all Pokémon characteristic.
/// </summary>
/// <param name="language">Language of the Pokémon characteristic to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each Pokémon characteristic.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetCharacteristicsList ( string language )
2016-10-06 04:06:24 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "character" , language ) ;
2016-10-06 04:06:24 +00:00
}
/// <summary>
/// Gets a list of all items.
/// </summary>
/// <param name="language">Language of the items to select (e.g. "en", "fr", "jp", etc.)</param>
/// <returns>An array of strings whose indexes correspond to the IDs of each item.</returns>
2017-06-18 01:37:19 +00:00
public static string [ ] GetItemsList ( string language )
2016-10-06 04:06:24 +00:00
{
2017-06-18 01:37:19 +00:00
return GetStringList ( "items" , language ) ;
2016-10-06 04:06:24 +00:00
}
#endregion
2017-06-18 01:37:19 +00:00
public static string [ ] GetStringList ( string f )
2016-07-09 22:30:12 +00:00
{
2017-05-12 04:34:18 +00:00
var txt = Properties . Resources . ResourceManager . GetString ( f ) ; // Fetch File, \n to list.
2016-07-09 22:30:12 +00:00
if ( txt = = null ) return new string [ 0 ] ;
2017-05-12 04:34:18 +00:00
string [ ] rawlist = ( txt ) . Split ( '\n' ) ;
2016-07-09 22:30:12 +00:00
for ( int i = 0 ; i < rawlist . Length ; i + + )
rawlist [ i ] = rawlist [ i ] . Trim ( ) ;
return rawlist ;
}
2017-06-18 01:37:19 +00:00
public static string [ ] GetStringList ( string f , string l )
2016-07-09 22:30:12 +00:00
{
2017-05-12 04:34:18 +00:00
var txt = Properties . Resources . ResourceManager . GetString ( "text_" + f + "_" + l ) ; // Fetch File, \n to list.
2016-07-09 22:30:12 +00:00
if ( txt = = null ) return new string [ 0 ] ;
2017-05-12 04:34:18 +00:00
string [ ] rawlist = ( txt ) . Split ( '\n' ) ;
2016-07-09 22:30:12 +00:00
for ( int i = 0 ; i < rawlist . Length ; i + + )
rawlist [ i ] = rawlist [ i ] . Trim ( ) ;
return rawlist ;
}
2017-06-18 01:37:19 +00:00
public static string [ ] GetStringListFallback ( string f , string l , string fallback )
2016-09-10 21:30:07 +00:00
{
2017-06-18 01:37:19 +00:00
string [ ] text = GetStringList ( f , l ) ;
2016-09-10 21:30:07 +00:00
if ( text . Length = = 0 )
2017-06-18 01:37:19 +00:00
text = GetStringList ( f , fallback ) ;
2016-09-10 21:30:07 +00:00
return text ;
}
2017-06-18 01:37:19 +00:00
public static string [ ] GetNulledStringArray ( string [ ] SimpleStringList )
2016-07-09 22:30:12 +00:00
{
try
{
2016-07-17 17:06:52 +00:00
string [ ] newlist = new string [ ToInt32 ( SimpleStringList [ SimpleStringList . Length - 1 ] . Split ( ',' ) [ 0 ] ) + 1 ] ;
2016-07-09 22:30:12 +00:00
for ( int i = 1 ; i < SimpleStringList . Length ; i + + )
2016-07-17 17:06:52 +00:00
newlist [ ToInt32 ( SimpleStringList [ i ] . Split ( ',' ) [ 0 ] ) ] = SimpleStringList [ i ] . Split ( ',' ) [ 1 ] ;
2016-07-09 22:30:12 +00:00
return newlist ;
}
catch { return null ; }
}
2017-03-24 17:59:45 +00:00
2017-06-18 01:37:19 +00:00
public static byte [ ] GetBinaryResource ( string name )
2017-05-12 04:34:18 +00:00
{
using ( var resource = typeof ( Util ) . GetTypeInfo ( ) . Assembly . GetManifestResourceStream ( "PKHeX.Core.Resources.byte." + name ) )
{
var buffer = new byte [ resource . Length ] ;
resource . Read ( buffer , 0 , ( int ) resource . Length ) ;
return buffer ;
}
}
2017-03-25 01:23:39 +00:00
#region Non - Form Translation
2017-03-24 17:59:45 +00:00
/// <summary>
/// Gets the names of the properties defined in the given input
/// </summary>
/// <param name="input">Enumerable of translation definitions in the form "Property = Value".</param>
/// <returns></returns>
2017-06-18 01:37:19 +00:00
private static string [ ] GetProperties ( IEnumerable < string > input )
2017-03-24 17:59:45 +00:00
{
return input . Select ( l = > l . Substring ( 0 , l . IndexOf ( TranslationSplitter , StringComparison . Ordinal ) ) ) . ToArray ( ) ;
}
private static IEnumerable < string > DumpStrings ( Type t )
{
2017-06-18 01:37:19 +00:00
var props = ReflectUtil . GetPropertiesStartWithPrefix ( t , "V" ) ;
2017-03-24 17:59:45 +00:00
return props . Select ( p = > $"{p}{TranslationSplitter}{ReflectUtil.GetValue(t, p).ToString()}" ) ;
}
/// <summary>
/// Gets the current localization in a static class containing language-specific strings
/// </summary>
2017-06-18 01:37:19 +00:00
public static string [ ] GetLocalization ( Type t , string [ ] existingLines = null )
2017-03-24 17:59:45 +00:00
{
existingLines = existingLines ? ? new string [ 0 ] ;
var currentLines = DumpStrings ( t ) . ToArray ( ) ;
2017-06-18 01:37:19 +00:00
var existing = GetProperties ( existingLines ) ;
var current = GetProperties ( currentLines ) ;
2017-03-24 17:59:45 +00:00
var result = new string [ currentLines . Length ] ;
for ( int i = 0 ; i < current . Length ; i + + )
{
int index = Array . IndexOf ( existing , current [ i ] ) ;
result [ i ] = index < 0 ? currentLines [ i ] : existingLines [ index ] ;
}
return result ;
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
2017-03-25 01:23:39 +00:00
/// <param name="t">Type of the static class containing the desired strings.</param>
2017-03-24 17:59:45 +00:00
/// <param name="lines">Lines containing the localized strings</param>
2017-06-18 01:37:19 +00:00
private static void SetLocalization ( Type t , IEnumerable < string > lines )
2017-03-24 17:59:45 +00:00
{
if ( lines = = null )
return ;
foreach ( var line in lines . Where ( l = > l ! = null ) )
{
var index = line . IndexOf ( TranslationSplitter , StringComparison . Ordinal ) ;
if ( index < 0 )
continue ;
var prop = line . Substring ( 0 , index ) ;
var value = line . Substring ( index + TranslationSplitter . Length ) ;
try
{
ReflectUtil . SetValue ( t , prop . ToUpper ( ) , value ) ;
}
catch
{
Console . WriteLine ( $"Property not present: {prop} || Value written: {value}" ) ;
}
}
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
2017-03-25 01:23:39 +00:00
/// <param name="t">Type of the static class containing the desired strings.</param>
2017-03-24 17:59:45 +00:00
/// <param name="languageFilePrefix">Prefix of the language file to use. Example: if the target is legality_en.txt, <paramref name="languageFilePrefix"/> should be "legality".</param>
2017-05-12 16:33:12 +00:00
/// <param name="currentCultureCode">Culture information</param>
2017-06-18 01:37:19 +00:00
private static void SetLocalization ( Type t , string languageFilePrefix , string currentCultureCode )
2017-03-24 17:59:45 +00:00
{
2017-06-18 01:37:19 +00:00
SetLocalization ( t , GetStringList ( $"{languageFilePrefix}_{currentCultureCode}" ) ) ;
2017-03-24 17:59:45 +00:00
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
2017-03-25 01:23:39 +00:00
/// <param name="t">Type of the static class containing the desired strings.</param>
2017-03-24 17:59:45 +00:00
/// <remarks>The values used to translate the given static class are retrieved from [TypeName]_[CurrentLangCode2].txt in the resource manager of PKHeX.Core.</remarks>
2017-05-12 16:33:12 +00:00
/// <param name="currentCultureCode">Culture information</param>
2017-06-18 01:37:19 +00:00
public static void SetLocalization ( Type t , string currentCultureCode )
2017-03-24 17:59:45 +00:00
{
2017-06-18 01:37:19 +00:00
SetLocalization ( t , t . Name , currentCultureCode ) ;
2017-03-24 17:59:45 +00:00
}
2017-03-25 01:23:39 +00:00
#endregion
2017-03-24 17:59:45 +00:00
2016-10-06 04:06:24 +00:00
#region DataSource Providing
2017-06-18 01:37:19 +00:00
public static List < ComboItem > GetCBList ( string textfile , string lang )
2016-07-09 22:30:12 +00:00
{
// Set up
2017-06-18 01:37:19 +00:00
string [ ] inputCSV = GetStringList ( textfile ) ;
2016-07-09 22:30:12 +00:00
// Get Language we're fetching for
int index = Array . IndexOf ( new [ ] { "ja" , "en" , "fr" , "de" , "it" , "es" , "ko" , "zh" , } , lang ) ;
// Set up our Temporary Storage
string [ ] unsortedList = new string [ inputCSV . Length - 1 ] ;
int [ ] indexes = new int [ inputCSV . Length - 1 ] ;
// Gather our data from the input file
for ( int i = 1 ; i < inputCSV . Length ; i + + )
{
string [ ] countryData = inputCSV [ i ] . Split ( ',' ) ;
indexes [ i - 1 ] = Convert . ToInt32 ( countryData [ 0 ] ) ;
unsortedList [ i - 1 ] = countryData [ index + 1 ] ;
}
// Sort our input data
string [ ] sortedList = new string [ inputCSV . Length - 1 ] ;
Array . Copy ( unsortedList , sortedList , unsortedList . Length ) ;
Array . Sort ( sortedList ) ;
// Arrange the input data based on original number
2016-07-09 22:34:38 +00:00
return sortedList . Select ( s = > new ComboItem
2016-07-09 22:30:12 +00:00
{
Text = s ,
Value = indexes [ Array . IndexOf ( unsortedList , s ) ]
} ) . ToList ( ) ;
}
2017-06-18 01:37:19 +00:00
public static List < ComboItem > GetCBList ( string [ ] inStrings , params int [ ] [ ] allowed )
2016-07-09 22:30:12 +00:00
{
2016-07-09 22:34:38 +00:00
List < ComboItem > cbList = new List < ComboItem > ( ) ;
2016-07-09 22:30:12 +00:00
if ( allowed ? . First ( ) = = null )
allowed = new [ ] { Enumerable . Range ( 0 , inStrings . Length ) . ToArray ( ) } ;
foreach ( int [ ] list in allowed )
{
// Sort the Rest based on String Name
string [ ] unsortedChoices = new string [ list . Length ] ;
for ( int i = 0 ; i < list . Length ; i + + )
unsortedChoices [ i ] = inStrings [ list [ i ] ] ;
string [ ] sortedChoices = new string [ unsortedChoices . Length ] ;
Array . Copy ( unsortedChoices , sortedChoices , unsortedChoices . Length ) ;
Array . Sort ( sortedChoices ) ;
// Add the rest of the items
2016-07-09 22:34:38 +00:00
cbList . AddRange ( sortedChoices . Select ( s = > new ComboItem
2016-07-09 22:30:12 +00:00
{
Text = s ,
Value = list [ Array . IndexOf ( unsortedChoices , s ) ]
} ) ) ;
}
return cbList ;
}
2017-06-18 01:37:19 +00:00
public static List < ComboItem > GetOffsetCBList ( List < ComboItem > cbList , string [ ] inStrings , int offset , int [ ] allowed )
2016-07-09 22:30:12 +00:00
{
if ( allowed = = null )
allowed = Enumerable . Range ( 0 , inStrings . Length ) . ToArray ( ) ;
int [ ] list = ( int [ ] ) allowed . Clone ( ) ;
for ( int i = 0 ; i < list . Length ; i + + )
list [ i ] - = offset ;
// Sort the Rest based on String Name
string [ ] unsortedChoices = new string [ allowed . Length ] ;
for ( int i = 0 ; i < allowed . Length ; i + + )
unsortedChoices [ i ] = inStrings [ list [ i ] ] ;
string [ ] sortedChoices = new string [ unsortedChoices . Length ] ;
Array . Copy ( unsortedChoices , sortedChoices , unsortedChoices . Length ) ;
Array . Sort ( sortedChoices ) ;
2017-01-25 11:29:38 +00:00
var indices = new Dictionary < string , int > ( ) ;
foreach ( var str in unsortedChoices . Where ( str = > ! indices . ContainsKey ( str ) ) )
indices . Add ( str , 0 ) ;
2016-07-09 22:30:12 +00:00
// Add the rest of the items
2017-01-25 11:29:38 +00:00
foreach ( var s in sortedChoices )
2016-07-09 22:30:12 +00:00
{
2017-01-25 11:29:38 +00:00
var index = Array . IndexOf ( unsortedChoices , s , indices [ s ] ) ;
cbList . Add ( new ComboItem
{
Text = s ,
Value = allowed [ index ]
} ) ;
indices [ s ] = index + 1 ;
}
2016-07-09 22:30:12 +00:00
return cbList ;
}
2017-06-18 01:37:19 +00:00
public static List < ComboItem > GetVariedCBList ( string [ ] inStrings , int [ ] stringNum , int [ ] stringVal )
2016-07-09 22:30:12 +00:00
{
// Set up
2016-07-09 22:34:38 +00:00
List < ComboItem > newlist = new List < ComboItem > ( ) ;
2016-07-09 22:30:12 +00:00
for ( int i = 4 ; i > 1 ; i - - ) // add 4,3,2
{
// First 3 Balls are always first
2016-07-09 22:34:38 +00:00
ComboItem ncbi = new ComboItem
2016-07-09 22:30:12 +00:00
{
Text = inStrings [ i ] ,
Value = i
} ;
newlist . Add ( ncbi ) ;
}
// Sort the Rest based on String Name
string [ ] ballnames = new string [ stringNum . Length ] ;
for ( int i = 0 ; i < stringNum . Length ; i + + )
ballnames [ i ] = inStrings [ stringNum [ i ] ] ;
string [ ] sortedballs = new string [ stringNum . Length ] ;
Array . Copy ( ballnames , sortedballs , ballnames . Length ) ;
Array . Sort ( sortedballs ) ;
// Add the rest of the balls
2016-07-09 22:34:38 +00:00
newlist . AddRange ( sortedballs . Select ( s = > new ComboItem
2016-07-09 22:30:12 +00:00
{
Text = s ,
Value = stringVal [ Array . IndexOf ( ballnames , s ) ]
} ) ) ;
return newlist ;
}
2017-06-18 01:37:19 +00:00
public static List < ComboItem > GetUnsortedCBList ( string textfile )
2016-07-09 22:30:12 +00:00
{
// Set up
2016-07-09 22:34:38 +00:00
List < ComboItem > cbList = new List < ComboItem > ( ) ;
2017-06-18 01:37:19 +00:00
string [ ] inputCSV = GetStringList ( textfile ) ;
2016-07-09 22:30:12 +00:00
// Gather our data from the input file
for ( int i = 1 ; i < inputCSV . Length ; i + + )
{
string [ ] inputData = inputCSV [ i ] . Split ( ',' ) ;
2016-07-09 22:34:38 +00:00
ComboItem ncbi = new ComboItem
2016-07-09 22:30:12 +00:00
{
Text = inputData [ 1 ] ,
Value = Convert . ToInt32 ( inputData [ 0 ] )
} ;
cbList . Add ( ncbi ) ;
}
return cbList ;
}
2016-10-06 04:06:24 +00:00
#endregion
2016-07-09 22:30:12 +00:00
}
}