/* 
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information 
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC. 
 */

using DXLib.Data;

namespace DXLib.Utils
{
	/*
	 * Provides utility methods for dealing with resource strings. Must be initialized with application and language
	 * specific resource table.
	 */
	public static class DXString
	{
		/* Constants */

		// Three levels of dynamic replacement keys
		public const string Replace1 = "[]";
		public const string Replace2 = "{}";
		public const string Replace3 = "()";

		/* Fields */
		private static Dictionary<string, string> stringTable;

		/* Methods */

		// Must be called at startup with preloaded string table
		public static void Init( Dictionary<string, string> table )
		{
			stringTable = table;
		}

		// Returns resource string corresponding to specified key
		public static string Get( string key )
		{
			string value = null;

			if ( key != null )
			{
				try
				{
					value = stringTable[ key ];
				}
				catch ( KeyNotFoundException )
				{
					return null;
				}
			}

			return value;
		}

		// Returns resource string with dynamic text values inserted
		public static string Get( string key, object insert1, object insert2 = null, object insert3 = null )
		{
			string str = Get( key );

			// Replace dynamic values
			if ( insert1 != null )
			{
				str = str.Replace( Replace1, insert1.ToString() );

				if ( insert2 != null )
				{
					str = str.Replace( Replace2, insert2.ToString() );

					if ( insert3 != null )
					{
						str = str.Replace( Replace3, insert3.ToString() );
					}
				}
			}

			return str;
		}

		// Returns specified resource string in all upper case
		public static string GetUpper( string key )
		{
			return Get( key ).ToUpper();
		}

		// Returns specified resource string in all lower case
		public static string GetLower( string key )
		{
			return Get( key ).ToLower();
		}

		// Returns singular or plural version of key string based on count
		public static string GetPlural( string key, int count )
		{
			return Get( (count == 1) ? $"{key}.singular" : $"{key}.plural" );
		}

		// Returns "X Foo" based on count and singular/plural key string
		public static string GetCount( string key, int count )
		{
			var plural = GetPlural( key, count );

			// 'No Foos', '1 Foo', or 'X Foos'
			return (count == 0)? $"{Get( "card.no" )} {plural}" : $"{count} {plural}";
		}

		// Returns resource string from list corresponding to specified key and index
		public static string GetIndex( string key, int index )
		{
			return Get( $"{key}.{index}" );
		}
		
		// Returns uppercase resource string from list for key and index
		public static string GetIndexUpper( string key, int index )
		{
			return GetIndex( key, index ).ToUpper();
		}

		/* LUT Methods */

		// Reads entire key-value lookup table for specified base key
		public static Dictionary<string, string> GetLookupTable( string baseKey )
		{
			// Allocate memory
			var table = new Dictionary<string, string>();

			int index = 0;
			string entry = GetIndex( baseKey, index );

			// Load all items in table
			while ( entry != null )
			{
				int delim = entry.IndexOf( '|' );

				string key = entry[ ..delim ];
				string value = entry[ (delim + 1).. ];

				// Add to LUT
				table.Add( key, value );

				index++;

				// Iterate
				entry = GetIndex( baseKey, index );
			}

			return table;
		}

		// Reads entire key-value lookup table as linear list for specified base key
		public static List<DXItem> GetLookupList( string baseKey )
		{
			// Allocate memory
			List<DXItem> list = [];

			int index = 0;
			string entry = GetIndex( baseKey, index );

			// Load all items in table
			while ( entry != null )
			{
				int delim = entry.IndexOf( '|' );

				// Item is 'key|value'
				DXItem item = new()
				{
					Index = index,
					Key = entry[ ..delim ],
					Value = entry[ (delim + 1).. ]
				};

				// Add to LUT
				list.Add( item );

				index++;

				// Iterate
				entry = GetIndex( baseKey, index );
			}

			return list;
		}

		// Returns item from base key lookup table matching specified key
		public static DXItem GetLookupItem( string baseKey, string key )
		{
			int index = 0;
			string entry = GetIndex( baseKey, index );

			// Search all items in table
			while ( entry != null )
			{
				int delim = entry.IndexOf( '|' );
				string entryKey = entry.Substring( 0, delim );

				// Match found, item is 'key|value'
				if ( entryKey.Equals( key ) )
				{
					DXItem item = new()
					{
						Index = index,
						Key = entryKey,
						Value = entry.Substring( delim + 1 )
					};

					return item;
				}

				index++;

				// Iterate
				entry = GetIndex( baseKey, index );
			}

			// No match found
			return null;
		}

		// Returns item at specified index from base key lookup table
		public static DXItem GetLookupItem( string baseKey, int index )
		{
			List<DXItem> list = GetLookupList( baseKey );

			// Bounds check index
			if ( (index >= 0) && (index < list.Count) )
			{
				return list[ index ];
			}

			return null;
		}

		// Returns value from base key lookup table matching specified key
		public static string GetLookupValue( string baseKey, string key )
		{
			return string.IsNullOrEmpty( key ) ? null : GetLookupItem( baseKey, key.ToLower() )?.Value;
		}

		// Returns index of specified key in base key lookup table
		public static int? GetLookupIndex( string baseKey, string key )
		{
			return GetLookupItem( baseKey, key )?.Index;
		}
	}
}

//
