/*
**	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/>.
*/

// StringPickerDialog.cpp : implementation file
//

#include "stdafx.h"
#include "leveledit.h"
#include "stringpickerdialog.h"
#include "stringscategoryviewdialog.h"
#include "translatedb.h"
#include "translateobj.h"
#include "utils.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
//	Contants
/////////////////////////////////////////////////////////////////////////////
static const int BORDER_X		= 10;
static const int BORDER_Y		= 10;
static const int SPACING_X		= 10;
static const int SPACING_Y		= 10;


/////////////////////////////////////////////////////////////////////////////
//
// StringPickerDialogClass
//
/////////////////////////////////////////////////////////////////////////////
StringPickerDialogClass::StringPickerDialogClass (CWnd *pParent)
	:	SelectedObjectID (0),
		CurrentTab (0),
		IsInitialized (false),
		CDialog(StringPickerDialogClass::IDD, pParent)
{
	//{{AFX_DATA_INIT(StringPickerDialogClass)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// ~StringPickerDialogClass
//
/////////////////////////////////////////////////////////////////////////////
StringPickerDialogClass::~StringPickerDialogClass (void)
{
	//
	//	Free the child dialog objects
	//
	for (int index = 0; index < CategoryPages.Count (); index ++) {
		delete CategoryPages[index];
	}

	CategoryPages.Delete_All ();
	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// DoDataExchange
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::DoDataExchange (CDataExchange *pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(StringPickerDialogClass)
	DDX_Control(pDX, IDC_TAB_CTRL, m_TabCtrl);
	//}}AFX_DATA_MAP
	return ;
}


BEGIN_MESSAGE_MAP(StringPickerDialogClass, CDialog)
	//{{AFX_MSG_MAP(StringPickerDialogClass)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_CTRL, OnSelchangeTabCtrl)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
//
// Create
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::Create (CWnd *parent_wnd)
{
	CDialog::Create (StringPickerDialogClass::IDD, parent_wnd);
	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// Resize_Controls
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::Resize_Controls (void)
{
	//
	//	Get the window and button bounding rectangles
	//
	CRect rect;
	CRect edit_rect;
	GetClientRect (&rect);
	::GetWindowRect (::GetDlgItem (m_hWnd, IDC_STRING_EDIT), &edit_rect);
	
	//
	//	Calculate some positions and widths
	//
	int width			= rect.Width ();
	int height			= rect.Height ();
	int edit_height	= edit_rect.Height ();

	int tab_width		= width;
	int tab_height		= height - (SPACING_Y + edit_height);

	int edit_y_pos		= tab_height + SPACING_Y;

	//
	//	Resize the tab control
	//
	m_TabCtrl.SetWindowPos (NULL, 0, 0, tab_width, tab_height, SWP_NOZORDER | SWP_NOCOPYBITS);

	//
	// Get the display rectangle of the tab control
	//
	CRect tab_rect;
	m_TabCtrl.GetWindowRect (&tab_rect);
	m_TabCtrl.AdjustRect (FALSE, &tab_rect);
	ScreenToClient (&tab_rect);

	//
	//	Resize all the category page controls
	//
	for (int index = 0; index < CategoryPages.Count (); index ++) {
		CategoryPages[index]->SetWindowPos (NULL, tab_rect.left + BORDER_X, tab_rect.top + BORDER_Y,
			tab_rect.Width () - BORDER_X * 2, tab_rect.Height () - BORDER_Y * 2, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);
	}

	//
	//	Reposition the edit control
	//
	::SetWindowPos (::GetDlgItem (m_hWnd, IDC_STRING_EDIT), NULL, 0, edit_y_pos,
		tab_width, edit_height, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);

	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// OnSelchangeTabCtrl
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::OnSelchangeTabCtrl
(
	NMHDR *		pNMHDR,
	LRESULT *	pResult
)
{
	(*pResult) = 0;
	Update_Page_Visibility ();

	//
	//	Update our cached selection ID
	//
	if (IsInitialized) {
		Get_Selection ();
		Update_Selected_String ();
	}

	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// Update_Page_Visibility
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::Update_Page_Visibility (void)
{
	//
	//	Check to see if the user has selected a new tab
	//
	int newtab = m_TabCtrl.GetCurSel ();
	if (CurrentTab != newtab) {
		
		//
		// Hide the old tab
		//
		if (CurrentTab < CategoryPages.Count () && CategoryPages[CurrentTab] != NULL) {
			CategoryPages[CurrentTab]->ShowWindow (SW_HIDE);
		}

		//
		// Show the new tab
		//
		if (CategoryPages[newtab] != NULL) {
			CategoryPages[newtab]->ShowWindow (SW_SHOW);
		}

		//
		// Remember what our new current tab is
		//
		CurrentTab = newtab;
	}

	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// OnSize
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::OnSize
(
	UINT	nType,
	int	cx,
	int	cy
) 
{
	CDialog::OnSize (nType, cx, cy);
	
	if (IsInitialized) {
		Resize_Controls ();
	}

	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
/////////////////////////////////////////////////////////////////////////////
BOOL
StringPickerDialogClass::OnInitDialog (void)
{
	CDialog::OnInitDialog ();
	
	//
	//	Loop over all the categories in the database
	//
	int count = TranslateDBClass::Get_Category_Count ();
	for (int index = 0; index < count; index ++) {
		
		//
		//	Lookup this category
		//
		TDBCategoryClass *category = TranslateDBClass::Get_Category (index);
		if (category != NULL) {
			Add_Category_Page (category);
		}
	}

	//
	//	Try to find the tab that the selected object is displayed on
	//
	for (index = 0; index < CategoryPages.Count (); index ++) {
		if (CategoryPages[index]->Get_Selection () == SelectedObjectID) {
			m_TabCtrl.SetCurSel (index);
			CurrentTab = index;
			break;
		}
	}

	//
	//	Display the first category page
	//
	if (CategoryPages.Count () > CurrentTab) {
		CategoryPages[CurrentTab]->ShowWindow (SW_SHOW);
	}
	
	Resize_Controls ();
	Update_Selected_String ();

	IsInitialized = true;
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
//
// Add_Category_Page
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::Add_Category_Page (TDBCategoryClass *category)
{
	//
	//	Add a tab to the dialog for this category
	//
	TC_ITEM tab_info	= { 0 };
	tab_info.mask		= TCIF_TEXT;
	tab_info.pszText	= (char *)(LPCTSTR)category->Get_Name ();
	m_TabCtrl.InsertItem (0xFF, &tab_info);

	//
	//	Create a page for this new category
	//
	StringsCategoryViewDialogClass *child_wnd = new StringsCategoryViewDialogClass;
	child_wnd->Set_Category_ID (category->Get_ID ());	
	child_wnd->Set_Edit_Mode (StringsCategoryViewDialogClass::EDIT_MODE_NONE);
	child_wnd->Set_Selection (SelectedObjectID);
	child_wnd->Set_Callback (this);
	child_wnd->Remove_Column (StringsCategoryViewDialogClass::COL_TEXT);
	child_wnd->Set_Column_Width (StringsCategoryViewDialogClass::COL_ID, 0.95F);
	child_wnd->Create (this);
	CategoryPages.Add (child_wnd);
	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// Get_Selection
//
/////////////////////////////////////////////////////////////////////////////
int
StringPickerDialogClass::Get_Selection (void)
{
	//
	//	Check to see if we need to update the cached selection ID
	//
	if (::IsWindow (m_hWnd)) {		
		SelectedObjectID = CategoryPages[CurrentTab]->Get_Selection ();
	}

	return SelectedObjectID;
}


/////////////////////////////////////////////////////////////////////////////
//
// On_Selection_Changed
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::On_Selection_Changed (int sel_object_id)
{
	SelectedObjectID = sel_object_id;
	Update_Selected_String ();
	return ;
}


/////////////////////////////////////////////////////////////////////////////
//
// Update_Selected_String
//
/////////////////////////////////////////////////////////////////////////////
void
StringPickerDialogClass::Update_Selected_String (void)
{
	StringClass english_text;
	if (SelectedObjectID != 0) {

		//
		//	Lookup the text associated with the new string
		//
		TDBObjClass *object = TranslateDBClass::Find_Object (SelectedObjectID);
		if (object != NULL) {
			english_text = object->Get_English_String ();
		}		
	}

	//
	//	Set the text of the selected string
	//
	SetDlgItemText (IDC_STRING_EDIT, english_text);
	return ;
}
