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

// PickerClass.cpp : implementation file
//

#include "stdafx.h"
#include "leveledit.h"
#include "picker.h"
#include "utils.h"
#include "filemgr.h"


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


///////////////////////////////////////////////////////////
//	Local constants
///////////////////////////////////////////////////////////
const int BUTTON_WIDTH		= 22;
const int BUTTON_ID			= 101;
const int EDIT_ID				= 102;


///////////////////////////////////////////////////////////
//
//	PickerClass
//
///////////////////////////////////////////////////////////
PickerClass::PickerClass (void)
	:	m_BrowseButton (NULL),
		m_Icon (NULL),
		CStatic ()
{
	//
	//	By default load the folder icon
	//
	m_Icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_FOLDER_TINY), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
	return ;
}


///////////////////////////////////////////////////////////
//
//	~PickerClass
//
///////////////////////////////////////////////////////////
PickerClass::~PickerClass (void)
{
	return ;
}


BEGIN_MESSAGE_MAP(PickerClass, CStatic)
	//{{AFX_MSG_MAP(PickerClass)
	ON_WM_SIZE()
	ON_WM_DRAWITEM()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


///////////////////////////////////////////////////////////
//
//	Create_Picker
//
///////////////////////////////////////////////////////////
bool
PickerClass::Create_Picker
(
	DWORD				style,
	const RECT &	rect,
	CWnd *			parent,
	UINT				id
)
{
	//
	//	Create the outer window
	//
	BOOL success = CreateEx (	WS_EX_CLIENTEDGE,
									  "STATIC",
									  "",
									  (style | SS_WHITERECT | WS_CLIPCHILDREN) & (~WS_BORDER),
									  rect,
									  parent,
									  id);
	if (success) {
		Initialize_Control ();
	}

	// Return the true/false result code
	return bool(success == TRUE);
}


///////////////////////////////////////////////////////////
//
//	WindowProc
//
///////////////////////////////////////////////////////////
LRESULT
PickerClass::WindowProc
(
	UINT		message,
	WPARAM	wParam,
	LPARAM	lParam
)
{
	//
	// Should we just pass this onto the edit control?
	//
	if ((message == WM_GETTEXT) ||
		 (message == WM_GETTEXTLENGTH) ||
		 (message == WM_SETTEXT))
	{
		return SendDlgItemMessage (EDIT_ID, message, wParam, lParam);

	} else if ((message == WM_COMMAND) && (LOWORD (wParam) == EDIT_ID)) {

		//
		//	Translate the message so the dialog thinks it came from an
		// edit control
		//
		LONG id = ::GetWindowLong (m_hWnd, GWL_ID); 
		return ::SendMessage (::GetParent (m_hWnd),
									 message,
									 MAKEWPARAM (id & 0xFFFF, HIWORD (wParam)),
									 (LPARAM)m_hWnd);

	} else if (message == WM_SETFOCUS) {
		::SetFocus (::GetDlgItem (m_hWnd, EDIT_ID));
	}

	return CStatic::WindowProc (message, wParam, lParam);
}


///////////////////////////////////////////////////////////
//
//	Initialize_Control
//
///////////////////////////////////////////////////////////
void
PickerClass::Initialize_Control (void)
{
	//
	// Set the font for this control
	//
	HFONT hfont = (HFONT)GetParent()->SendMessage (WM_GETFONT);
	SendMessage (WM_SETFONT, (WPARAM)hfont);

	//
	//	Determine how tall to make the edit control
	//
	HDC hdc			= ::GetDC (m_hWnd);
	HFONT holdfont	= (HFONT)::SelectObject (hdc, hfont);
	CSize size;
	::GetTextExtentPoint32 (hdc, "XgW", 3, &size);
	::SelectObject (hdc, holdfont);
	::ReleaseDC (m_hWnd, hdc);
	
	//
	// Create the edit control
	//
	CRect rect;
	GetClientRect (&rect);
	m_EditCtrl = ::CreateWindowEx ( 0,
											  "EDIT",
											  "",
											  WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
											  2,
											  (rect.Height () >> 1) - ((size.cy) >> 1),
											  rect.Width () - BUTTON_WIDTH - 3,
											  size.cy,
											  m_hWnd,
												(HMENU)EDIT_ID,
											  ::AfxGetInstanceHandle (),
											  NULL);	
		CRect rect2;
		GetWindowRect (&rect2);


	::SendMessage (m_EditCtrl, WM_SETFONT, (WPARAM)hfont, 0L);
	
	//
	// Create the picker button
	//
	m_BrowseButton = ::CreateWindow ("BUTTON",
												 "",
												 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW,
												 rect.Width () - BUTTON_WIDTH,
												 0,
												 BUTTON_WIDTH,
												 rect.Height (),
												 m_hWnd,
												 (HMENU)BUTTON_ID,
												 ::AfxGetInstanceHandle (),
												 NULL);
	
	ASSERT (m_BrowseButton != NULL);
	return ;
}


///////////////////////////////////////////////////////////
//
//	Initialize_Control
//
///////////////////////////////////////////////////////////
void
PickerClass::OnSize
(
	UINT	nType,
	int	cx,
	int	cy
)
{

	//
	// Set the font for this control
	//
	HFONT hfont = (HFONT)GetParent()->SendMessage (WM_GETFONT);
	SendMessage (WM_SETFONT, (WPARAM)hfont);

	//
	//	Determine how tall to make the edit control
	//
	HDC hdc			= ::GetDC (m_hWnd);
	HFONT holdfont	= (HFONT)::SelectObject (hdc, hfont);
	CSize size;
	::GetTextExtentPoint32 (hdc, "XgW", 3, &size);
	::SelectObject (hdc, holdfont);
	::ReleaseDC (m_hWnd, hdc);

	CRect client_rect;
	GetClientRect (&client_rect);
	
	//
	// Resize the edit control
	//
	::SetWindowPos (	m_EditCtrl,
							NULL, 
							2,
							(client_rect.Height () >> 1) - ((size.cy) >> 1),
							client_rect.Width () - BUTTON_WIDTH - 3,
							size.cy,
							SWP_NOZORDER);

	//
	// Reposition the file button
	//
	::SetWindowPos (	m_BrowseButton, 
							NULL,
							client_rect.Width () - BUTTON_WIDTH,
							0,
							BUTTON_WIDTH,
							client_rect.Height (),
							SWP_NOZORDER);

	CStatic::OnSize (nType, cx, cy);	
	return ;	
}


///////////////////////////////////////////////////////////
//
//	OnCommand
//
///////////////////////////////////////////////////////////
BOOL
PickerClass::OnCommand
(
	WPARAM wParam,
	LPARAM lParam
)
{
	//
	// Did the user click the 'picker' button?
	//
	if ((LOWORD (wParam) == BUTTON_ID) &&
	    (HIWORD (wParam) == BN_CLICKED))
	{
		On_Pick ();
	}

	// Allow the base class to process this message
	return CStatic::OnCommand (wParam, lParam);
}


///////////////////////////////////////////////////////////
//
//	OnDrawItem
//
///////////////////////////////////////////////////////////
void
PickerClass::OnDrawItem
(
	int nIDCtl,
	LPDRAWITEMSTRUCT pDrawItemStruct
) 
{	
	CRect rect;
	::GetClientRect (m_BrowseButton, &rect);

	//
	// Draw the button frame
	//
	UINT type = (pDrawItemStruct->itemState & ODS_SELECTED) ? (DFCS_SCROLLDOWN | DFCS_PUSHED) : DFCS_SCROLLDOWN;
	::DrawFrameControl (pDrawItemStruct->hDC, &rect, DFC_SCROLL, type);

	//
	//	Calculate the icon's position
	//
	int xpos = (rect.Width () / 2) - 8;
	int ypos = (rect.Height () / 2) - 8;

	if (pDrawItemStruct->itemState & ODS_SELECTED) {
		xpos ++;
		ypos ++;
	}

	//
	// Paint the icon
	//
	::DrawIconEx (pDrawItemStruct->hDC,
					  xpos,
					  ypos,
					  m_Icon,
					  16,
					  16,
					  0,
					  NULL,
					  DI_NORMAL);

	CStatic::OnDrawItem (nIDCtl, pDrawItemStruct);
	return ;
}


///////////////////////////////////////////////////////////
//
//	Set_Read_Only
//
///////////////////////////////////////////////////////////
void
PickerClass::Set_Read_Only (bool readonly)
{
	::SendMessage (m_EditCtrl, EM_SETREADONLY, (WPARAM)readonly, 0L);
	return ;
}


///////////////////////////////////////////////////////////
//
//	OnEraseBkgnd
//
///////////////////////////////////////////////////////////
BOOL
PickerClass::OnEraseBkgnd (CDC *pDC)
{
	CRect rect;
	::GetClientRect (m_hWnd, &rect);

	//
	// Use the 'grayed' brush if this control is read-only
	//
	HBRUSH brush = HBRUSH(COLOR_WINDOW+1);
	if (::GetWindowLong (m_EditCtrl, GWL_STYLE) & ES_READONLY) {
		brush = HBRUSH(COLOR_3DFACE+1);
	}

	//
	//	Erase the background
	//
	::FillRect (*pDC, &rect, brush);
	return TRUE;
}


///////////////////////////////////////////////////////////
//
//	OnPaint
//
///////////////////////////////////////////////////////////
void
PickerClass::OnPaint (void)
{
	//
	//	Force the child windows to be repainted
	//
	::InvalidateRect (m_EditCtrl, NULL, TRUE);
	::InvalidateRect (m_BrowseButton, NULL, TRUE);

	CPaintDC dc (this);
	return ;
}

