/*
**	Command & Conquer Renegade(tm)
**	Copyright 2025 Electronic Arts Inc.
**
**	This program is free software: you can redistribute it and/or modify
**	it under the terms of the GNU General Public License as published by
**	the Free Software Foundation, either version 3 of the License, or
**	(at your option) any later version.
**
**	This program is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**	GNU General Public License for more details.
**
**	You should have received a copy of the GNU General Public License
**	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*****************************************************************************
*   C O N F I D E N T I A L --- W E S T W O O D   A S S O C I A T E S		 *
******************************************************************************
*
* FILE
*     $Archive: /Commando/Code/Tools/WWConfig/Locale_API.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
*     $Author: Ian_l $
*
* VERSION INFO
*     $Modtime: 1/09/02 11:02a $
*     $Revision: 2 $
*
*****************************************************************************/

#include <Windows.h>
#include <wtypes.h>
#include "locale.h"
#include "locale_api.h"
#include "rawfile.h"
#include "wwconfig_ids.h"


/****************************************************************************/
/* DEFINES			                                                        */
/****************************************************************************/

//----------------------------------------------------------------------------
// NOTE:	if USE_MULTI_FILE_FORMAT is "true", then a .lOC file must be in 
//			the same directory as this file.
//----------------------------------------------------------------------------
#define		USE_MULTI_FILE_FORMAT		FALSE

#define		LANGUAGE_IS_DBCS(l)	(((l)==IDL_JAPANESE)||((l)==IDL_KOREAN)||((l)==IDL_CHINESE))		// [OYO]
#define		CODEPAGE_IS_DBCS(C)	((C==932)||(C==949)||(C==950))										// [OYO]


/****************************************************************************/
/* GLOBAL VARIABLES                                                         */
/****************************************************************************/
CHAR		LanguageFile[ _MAX_PATH ];
void *	LocaleFile		= NULL;
int		CodePage			= GetACP();
int		LanguageID		= 0;

/****************************************************************************/
/* LOCALE API                                                               */
/****************************************************************************/
WCHAR *		Remove_Quotes_Around_String ( WCHAR *old_string );
void *	 	Load_File ( const CHAR *filename, long *filesize );

//=============================================================================
// These are wrapper functions around the LOCALE_ functions.  I made these to 
// make using the single vs. multi language files more transparent to the program.
//=============================================================================

bool Locale_Use_Multi_Language_Files ( void )
{
#if( USE_MULTI_FILE_FORMAT )
	return true;
#else
	return false;
#endif
}


/****************************************************************************/
/* initialization															*/
/****************************************************************************/

int Locale_Init	( int language, char *file )
{
	int	result = 0;

	//-------------------------------------------------------------------------
	// Check for a file passed in.
	//-------------------------------------------------------------------------
	if( file == NULL || file[0] == '/0' ) {
		return 0;
	}

	//-------------------------------------------------------------------------
	// Initialize settings.
	//-------------------------------------------------------------------------
	strcpy( LanguageFile, file );
	LanguageID = language;

	//-------------------------------------------------------------------------
	// If language == -1, then set based on CodePage.
	//-------------------------------------------------------------------------
	if( LanguageID == -1 ) {

		switch( CodePage ) {

			// Japanese
			case 932:
				LanguageID	= IDL_JAPANESE;
				break;

			// Korean
			case 949:
				LanguageID	= IDL_KOREAN;
				break;

			// Chinese
			case 950:
				LanguageID	= IDL_CHINESE;
				break;

			// English, French, and German
			case 1252:
				{
					LANGID	langid	= GetSystemDefaultLangID();
					WORD	plangid = PRIMARYLANGID( langid );

					switch( plangid ) {

						// German
						case 0x07:
							LanguageID 	= IDL_GERMAN;
							break;

						// French
						case 0x0c:
							LanguageID 	= IDL_FRENCH;
							break;

						// English
						case 0x09:
						default:
							LanguageID	= IDL_ENGLISH;
							break;
					}
				}
				break;
							
			default:
				LanguageID	= IDL_ENGLISH;
				break;
		}
	}

	//-------------------------------------------------------------------------
	// Check for valid LanguageID range.
	//-------------------------------------------------------------------------
	if( LanguageID < 0 || LanguageID >= LOCALE_LANGUAGE_COUNT ) {
		LanguageID = 0;
	}

	//-------------------------------------------------------------------------
	// Use English in the situation where Chinese, Korean, or Japanese was 
	// requested but not available.
	//-------------------------------------------------------------------------
	if( LANGUAGE_IS_DBCS( LanguageID ) && !CODEPAGE_IS_DBCS( CodePage )) {
		LanguageID = IDL_ENGLISH;
	}

	//-------------------------------------------------------------------------
	// Initialize the lx object.
	//-------------------------------------------------------------------------
	LOCALE_init();

	#if( USE_MULTI_FILE_FORMAT )

		//---------------------------------------------------------------------
		// Set bank to use and load the appropriate table.
		//---------------------------------------------------------------------
		LOCALE_setbank(0);
		result = LOCALE_loadtable( LanguageFile, LanguageID );

	#else

		//---------------------------------------------------------------------
		// Create a file buffer that holds all the strings in the file.
		//---------------------------------------------------------------------
		long		filesize;
		HRSRC 		hRsrc;
		HGLOBAL		hGlobal;
		int			PrimaryLanguage = LANG_NEUTRAL;
		int			SubLanguage		= SUBLANG_DEFAULT;
		HMODULE		module			= GetModuleHandle( NULL );

		//-------------------------------------------------------------------------
		// Find the string file in this program's resources.
		//-------------------------------------------------------------------------
		switch( LanguageID ) {

			// Japanese
			case IDL_JAPANESE:
				PrimaryLanguage = LANG_JAPANESE;
				SubLanguage		= SUBLANG_DEFAULT;
				break;

			// Korean
			case IDL_KOREAN:
				PrimaryLanguage = LANG_KOREAN;
				SubLanguage		= SUBLANG_DEFAULT;
				break;

			// Chinese
			case IDL_CHINESE:
				PrimaryLanguage = LANG_CHINESE;
				SubLanguage		= SUBLANG_DEFAULT;
				break;

			// German
			case IDL_GERMAN:
				PrimaryLanguage = LANG_GERMAN;
				SubLanguage		= SUBLANG_GERMAN;
				break;

			// French
			case IDL_FRENCH:
				PrimaryLanguage = LANG_FRENCH;
				SubLanguage		= SUBLANG_FRENCH;
				break;

			// English
			case IDL_ENGLISH:
				PrimaryLanguage = LANG_ENGLISH;
				SubLanguage		= SUBLANG_ENGLISH_US;
				break;

			default:
				PrimaryLanguage = LANG_ENGLISH;
				SubLanguage		= SUBLANG_ENGLISH_US;
				break;
		}

		hRsrc = FindResourceEx( module, RT_RCDATA, "STRINGS", MAKELANGID( PrimaryLanguage, SubLanguage ));
		if ( hRsrc == NULL ) {
			hRsrc = FindResourceEx( module, RT_RCDATA, "STRINGS", MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ));
		}
		if ( hRsrc ) {

			//---------------------------------------------------------------------
			// Load the resource, lock the memory, grab a DC.
			//---------------------------------------------------------------------
			hGlobal		= LoadResource( module, hRsrc );
			filesize	= SizeofResource( module, hRsrc );

			LocaleFile = (void*)malloc( filesize + 1 );
			memset( LocaleFile, '\0', filesize + 1 );
			memcpy( LocaleFile, (const void *)hGlobal, filesize );

			//---------------------------------------------------------------------
			// Free DS and memory used.
			//---------------------------------------------------------------------
			UnlockResource( hGlobal );
			FreeResource( hGlobal );
		}

		if( LocaleFile == NULL ) {
			LocaleFile = Load_File( LanguageFile, &filesize );
		}

		if( LocaleFile != NULL ) {
			result = 1;
		}

	#endif

	return result;	
}

/************************************************************************/
/* restore	 															*/
/************************************************************************/

void Locale_Restore ( void )
{
	#if( USE_MULTI_FILE_FORMAT )
		LOCALE_freetable();
		LOCALE_restore();
	#else
		if( LocaleFile ) {
			free( LocaleFile );
			LocaleFile = NULL;
		}
	#endif
}


/********************************************************************************
 * Load_File -- Allocates a buffer and loads the file into it.					*
 *																				*
 *		Get a string usine Resource ID and a buffer.							*
 *																				*
 * INPUT:   int StringID  -- The resource number of the string.					*
 *          CHAR *String  -- The buffer to place the text in.					*
 *																				*
 * OUTPUT:  Returns with a pointer to the buffer.								*
 *																				*
 * WARNINGS:   none																*
 *																				*
 * HISTORY:																		*
 *   12/10/2001  MML : Created.													*
 *==============================================================================*/

const CHAR* Locale_GetString( int StringID, CHAR *String )
{
	static	CHAR		buffer[ _MAX_PATH ];
	static	WCHAR		wide_buffer[ _MAX_PATH ];

	memset( buffer,		 '\0', _MAX_PATH );
	memset(	wide_buffer, '\0', _MAX_PATH );

	#if( USE_MULTI_FILE_FORMAT )
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
	#else									  
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
	#endif

	Remove_Quotes_Around_String( wide_buffer );
	WideCharToMultiByte( CodePage, 0, wide_buffer, _MAX_PATH, buffer, _MAX_PATH, NULL, NULL );

	if( String != NULL ) {
		strncpy( String, buffer, _MAX_PATH );
	}
	return buffer;
}

/********************************************************************************
 * Load_File -- Allocates a buffer and loads the file into it.					*
 *																				*
 *		Get a string usine Resource ID and a buffer.							*
 *																				*
 * INPUT:   int StringID  -- The resource number of the string.					*
 *          WCHAR *String  -- The buffer to place the text in.					*
 *																				*
 * OUTPUT:  Returns with a pointer to the buffer.								*
 *																				*
 * WARNINGS:   none																*
 *																				*
 * HISTORY:																		*
 *   12/10/2001  MML : Created.													*
 *==============================================================================*/

const WCHAR* Locale_GetString( int StringID, WCHAR *String )
{
	static WCHAR wide_buffer[ _MAX_PATH ];

	memset(	wide_buffer, '\0', _MAX_PATH );

	#if( USE_MULTI_FILE_FORMAT )
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
	#else									  
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
	#endif

	Remove_Quotes_Around_String( wide_buffer );

	if( String != NULL ) {
		wcsncpy( String, wide_buffer, _MAX_PATH );
	}
	return wide_buffer;
}

/********************************************************************************
 * Load_File -- Allocates a buffer and loads the file into it.					*
 *																				*
 *		Get a string usine Resource ID and a buffer.							*
 *																				*
 * INPUT:   int StringID  -- The resource number of the string.					*
 *																				*
 * OUTPUT:  Returns with a pointer to the buffer.								*
 *																				*
 * WARNINGS:   none																*
 *																				*
 * HISTORY:																		*
 *   12/10/2001  MML : Created.													*
 *==============================================================================*/

const WCHAR* Locale_GetString( int StringID )
{
	static WCHAR wide_buffer[ _MAX_PATH ];

	memset(	wide_buffer, '\0', _MAX_PATH );

	#if( USE_MULTI_FILE_FORMAT )
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstring( StringID ));
	#else									  
		wcscpy( wide_buffer, (WCHAR *)LOCALE_getstr( LocaleFile, StringID ));
	#endif

	Remove_Quotes_Around_String( wide_buffer );

	return wide_buffer;
}


/****************************************************************************/
/* formating strings   														*/
/****************************************************************************/

WCHAR *Remove_Quotes_Around_String ( WCHAR *old_string )
{
	WCHAR	wide_buffer[ _MAX_PATH * 3 ];
	WCHAR * letter = old_string;
	int		length;

	//----------------------------------------------------------------------
	// If string is not NULL...
	//----------------------------------------------------------------------
	if ( *letter == '"' ) {

		letter++;
		wcscpy( wide_buffer, letter );

		length = wcslen( wide_buffer );

		if ( wide_buffer[ wcslen( wide_buffer )-1 ] == '"' ) {
			wide_buffer[ wcslen( wide_buffer )-1 ] = '\0';
		}
		wcscpy( old_string, wide_buffer );
	}

	return( old_string );
}


/********************************************************************************
 * Load_File -- Allocates a buffer and loads the file into it.					*
 *																				*
 *	This is the C++ replacement for the Load_Alloc_Data function. It will		*
 *	allocate the memory big enough to hold the file & read the file into it.	*
 *																				*
 * INPUT:   file  -- The file to read.											*
 *          mem   -- The memory system to use for allocation.					*
 *																				*
 * OUTPUT:  Returns with a pointer to the allocated and filled memory block.	*
 *																				*
 * WARNINGS:   none																*
 *																				*
 * HISTORY:																		*
 *   10/17/1994 JLB : Created.													*
 *==============================================================================*/

void * Load_File ( const char *filename, long *filesize )
{
	int					size, bytes_read;
	void				*ptr = NULL;
//	StandardFileClass	file;
	RawFileClass		file;

	if ( filename == NULL || filename[0] == '\0' ) {
		return( NULL );
	}

	//-------------------------------------------------------------------------
	// Open file in READ ONLY mode.  If fails, exit.
	//-------------------------------------------------------------------------
//	file.Open( filename, MODE_READ_ONLY );
	file.Open( filename, FileClass::READ );
//	if( !file.Query_Open()) {
	if( !file.Is_Open()) {
		return( NULL );
	}

	//-------------------------------------------------------------------------
	// Get filesize and create a buffer.
	//-------------------------------------------------------------------------
// 	size = file.Query_Size();
	size = file.Size();
	ptr = (void*)malloc(size + 1);
	if ( !ptr ) {
		return( NULL );
	}

	//-------------------------------------------------------------------------
	// Read data into the buffer, close the file.
	//-------------------------------------------------------------------------
	memset( ptr, '\0', size + 1 );
//  bytes_read = file.Read( ptr, size );
	bytes_read = file.Read( ptr, size );
// 	file.Close();
	file.Close();

	//-------------------------------------------------------------------------
	// Check return bytes.  It should match the file size.
	//-------------------------------------------------------------------------
	assert( bytes_read == size );
	if ( bytes_read != size ) {
		free(ptr);
		return( NULL );
	}

	if ( filesize != NULL ) {
		*filesize = (long)size;
	}
	return( ptr );
}

