/*
**	Command & Conquer Generals Zero Hour(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  S T U D I O S               ***
 ***********************************************************************************************
 *                                                                                             *
 *                 Project Name : Max2W3d                                                      *
 *                                                                                             *
 *                     $Archive:: /Commando/Code/Tools/max2w3d/GameMtlShaderDlg.cpp           $*
 *                                                                                             *
 *                       Author:: Greg Hjelstrom                                               *
 *                                                                                             *
 *                     $Modtime:: 2/26/99 7:23p                                               $*
 *                                                                                             *
 *                    $Revision:: 13                                                          $*
 *                                                                                             *
 *---------------------------------------------------------------------------------------------*
 * Functions:                                                                                  *
 *   GameMtlShaderDlg::GameMtlShaderDlg -- constructor                                         *
 *   GameMtlShaderDlg::~GameMtlShaderDlg -- destructor                                         *
 *   GameMtlShaderDlg::Dialog_Proc -- windows message handler                                  *
 *   GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls              *
 *   GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog                           *
 *   GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting                           *
 *   GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material        *
 *   GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader    *
 *   GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults              *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include "GameMtlShaderDlg.h"
#include "GameMtlDlg.h"
#include "GameMtl.h"
#include "resource.h"

/*
** Shader Blend Setting Presets
*/

// Note: the array has NUM_SHADER_BLEND_PRESETS + 1 entries (due to the 'Custom' entry).

#define NUM_SHADER_BLEND_PRESETS 8

static char * _ShaderBlendSettingPresetNames[NUM_SHADER_BLEND_PRESETS + 1] = 
{
	"Opaque",
	"Add",
	"Multiply",
	"Multiply and Add",
	"Screen",
	"Alpha Blend",
	"Alpha Test",
	"Alpha Test and Blend",
	"------ Custom -----"
};
struct ShaderBlendSettingPreset
{
	int	SrcBlend;
	int	DestBlend;
	bool	DepthMask;
	bool	AlphaTest;
};
static const ShaderBlendSettingPreset ShaderBlendSettingPresets[NUM_SHADER_BLEND_PRESETS] = {
	{W3DSHADER_SRCBLENDFUNC_ONE,			W3DSHADER_DESTBLENDFUNC_ZERO,						true,  false},	// Opaque
	{W3DSHADER_SRCBLENDFUNC_ONE,			W3DSHADER_DESTBLENDFUNC_ONE,						false, false},	// Add
	{W3DSHADER_SRCBLENDFUNC_ZERO,			W3DSHADER_DESTBLENDFUNC_SRC_COLOR,				false, false},	// Multiply
	{W3DSHADER_SRCBLENDFUNC_ONE,			W3DSHADER_DESTBLENDFUNC_SRC_COLOR,				false, false},	// Multiply and Add
	{W3DSHADER_SRCBLENDFUNC_ONE,			W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_COLOR,	false, false},	// Screen
	{W3DSHADER_SRCBLENDFUNC_SRC_ALPHA,	W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA,	false, false},	// Alpha Blend
	{W3DSHADER_SRCBLENDFUNC_ONE,			W3DSHADER_DESTBLENDFUNC_ZERO,						true,  true},	// Alpha Test
	{W3DSHADER_SRCBLENDFUNC_SRC_ALPHA,	W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA,	true,  true}	// Alpha Test and Blend
};


/***********************************************************************************************
 * GameMtlShaderDlg::GameMtlShaderDlg -- constructor                                           *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/23/98   GTH : Created.                                                                 *
 *=============================================================================================*/
GameMtlShaderDlg::GameMtlShaderDlg
(
	HWND				parent, 
	IMtlParams *	imp, 
	GameMtl *		mtl,
	int				pass
) :
	GameMtlFormClass(imp,mtl,pass)
{
	Create_Form(parent,IDD_GAMEMTL_SHADER);
}


/***********************************************************************************************
 * GameMtlShaderDlg::~GameMtlShaderDlg -- destructor                                           *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *=============================================================================================*/
GameMtlShaderDlg::~GameMtlShaderDlg()
{
}


/***********************************************************************************************
 * GameMtlShaderDlg::Dialog_Proc -- windows message handler                                    *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/23/98   GTH : Created.                                                                 *
 *=============================================================================================*/
BOOL GameMtlShaderDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam) 
{ 
	int cursel;
	int i;
	int id = LOWORD(wparam);
	int code = HIWORD(wparam);

	switch (message) 
	{

		case WM_INITDIALOG:
			for(i = 0; i <= NUM_SHADER_BLEND_PRESETS; i++) {
				SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_ADDSTRING,0,(LONG)_ShaderBlendSettingPresetNames[i]);
			}
			SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_SETCURSEL,0,0);
			break;

		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_MOUSEMOVE:
			{
				IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
			}
			return FALSE;

		case WM_COMMAND:
			{
				if (code == CBN_SELCHANGE) {
					
					switch (id) 
					{
						case IDC_DEPTHCOMPARE_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_DEPTHCOMPARE_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Depth_Compare(PassIndex,cursel);
							break;
						case IDC_DESTBLEND_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_DESTBLEND_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Dest_Blend(PassIndex,cursel);
							TheMtl->Notify_Changed();
							Set_Preset();
							break;
						case IDC_PRIGRADIENT_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_PRIGRADIENT_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Pri_Gradient(PassIndex,cursel);
							TheMtl->Notify_Changed();
							break;
						case IDC_SECGRADIENT_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_SECGRADIENT_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Sec_Gradient(PassIndex,cursel);
							TheMtl->Notify_Changed();
							break;
						case IDC_SRCBLEND_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_SRCBLEND_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Src_Blend(PassIndex,cursel);
							TheMtl->Notify_Changed();
							Set_Preset();
							break;
						case IDC_DETAILCOLOR_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILCOLOR_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Detail_Color_Func(PassIndex,cursel);
							TheMtl->Notify_Changed();
							break;
						case IDC_DETAILALPHA_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILALPHA_COMBO,CB_GETCURSEL,0,0);
							TheMtl->Set_Detail_Alpha_Func(PassIndex,cursel);
							TheMtl->Notify_Changed();
							break;
						case IDC_PRESET_COMBO:
							cursel = SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_GETCURSEL,0,0);
							Apply_Preset(cursel);
							break;
					}

				} else {
				
					switch(id) {
						
						case IDC_DEPTHMASK_CHECK:
							if (SendDlgItemMessage(dlg_wnd,IDC_DEPTHMASK_CHECK,BM_GETCHECK,0,0)) {
								TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_ENABLE);
							} else {
								TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_DISABLE);
							}
							Set_Preset();
							break;

						case IDC_ALPHATEST_CHECK:
							if (SendDlgItemMessage(dlg_wnd,IDC_ALPHATEST_CHECK,BM_GETCHECK,0,0)) {
								TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_ENABLE);
							} else {
								TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_DISABLE);
							}
							Set_Preset();
							break;

						case IDC_SHADER_DEFAULTS_BUTTON:
							Set_Advanced_Defaults();
							break;
					}
				}
			}
	}

	return FALSE;
}


/***********************************************************************************************
 * GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls                *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/23/98   GTH : Created.                                                                 *
 *=============================================================================================*/
void GameMtlShaderDlg::ReloadDialog(void)
{
	DebugPrint("GameMtlShaderDlg::ReloadDialog\n");
	SendDlgItemMessage(m_hWnd, IDC_DESTBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Dest_Blend(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_SRCBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Src_Blend(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_PRIGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Pri_Gradient(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_SECGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Sec_Gradient(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_DEPTHCOMPARE_COMBO, CB_SETCURSEL, TheMtl->Get_Depth_Compare(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_DETAILCOLOR_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Color_Func(PassIndex), 0 );
	SendDlgItemMessage(m_hWnd, IDC_DETAILALPHA_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Alpha_Func(PassIndex), 0 );
	Set_Preset();
	
	SetCheckBox(m_hWnd,IDC_DEPTHMASK_CHECK, TheMtl->Get_Depth_Mask(PassIndex));
	SetCheckBox(m_hWnd,IDC_ALPHATEST_CHECK, TheMtl->Get_Alpha_Test(PassIndex));
}


/***********************************************************************************************
 * GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/23/98   GTH : Created.                                                                 *
 *=============================================================================================*/
void GameMtlShaderDlg::ActivateDlg(BOOL onoff)
{
	// shader has no color swatches which need to be activated...
}


/***********************************************************************************************
 * GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting                             *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/23/98   GTH : Created.                                                                 *
 *=============================================================================================*/
void GameMtlShaderDlg::Apply_Preset(int preset_index)
{
	if (preset_index < 0 || preset_index >= NUM_SHADER_BLEND_PRESETS) return;

	const ShaderBlendSettingPreset &preset = ShaderBlendSettingPresets[preset_index];

	TheMtl->Set_Src_Blend(PassIndex, preset.SrcBlend);

	TheMtl->Set_Dest_Blend(PassIndex, preset.DestBlend);

	int depth_mask = preset.DepthMask ? W3DSHADER_DEPTHMASK_WRITE_ENABLE : W3DSHADER_DEPTHMASK_WRITE_DISABLE;
	TheMtl->Set_Depth_Mask(PassIndex, depth_mask);

	int alpha_test = preset.AlphaTest ? W3DSHADER_ALPHATEST_ENABLE : W3DSHADER_ALPHATEST_DISABLE;
	TheMtl->Set_Alpha_Test(PassIndex, alpha_test);

	TheMtl->Notify_Changed();
	ReloadDialog();
}


/***********************************************************************************************
 * GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material          *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   02/26/99   NH : Created.                                                                  *
 *=============================================================================================*/
void GameMtlShaderDlg::Set_Preset(void)
{
	for (int i = 0; i < NUM_SHADER_BLEND_PRESETS; i++) {
		if (CompareShaderToBlendPreset(ShaderBlendSettingPresets[i])) break;
	}
	SendDlgItemMessage(m_hWnd, IDC_PRESET_COMBO, CB_SETCURSEL, i, 0);
}


/***********************************************************************************************
 * GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader      *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   02/26/99   NH : Created.                                                                  *
 *=============================================================================================*/
bool GameMtlShaderDlg::CompareShaderToBlendPreset(const ShaderBlendSettingPreset &blend_preset)
{
	if (TheMtl->Get_Src_Blend(PassIndex) != blend_preset.SrcBlend) return false;
	if (TheMtl->Get_Dest_Blend(PassIndex) != blend_preset.DestBlend) return false;
	bool depthmask = TheMtl->Get_Depth_Mask(PassIndex) != W3DSHADER_DEPTHMASK_WRITE_DISABLE;
	if (depthmask != blend_preset.DepthMask) return false;
	bool alphatest = TheMtl->Get_Alpha_Test(PassIndex) != W3DSHADER_ALPHATEST_DISABLE;
	if (alphatest != blend_preset.AlphaTest) return false;
	return true;
}


/***********************************************************************************************
 * GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults                *
 *                                                                                             *
 * INPUT:                                                                                      *
 *                                                                                             *
 * OUTPUT:                                                                                     *
 *                                                                                             *
 * WARNINGS:                                                                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   02/26/99   NH : Created.                                                                  *
 *=============================================================================================*/
void GameMtlShaderDlg::Set_Advanced_Defaults(void)
{
	TheMtl->Set_Pri_Gradient(PassIndex, W3DSHADER_PRIGRADIENT_DEFAULT);
	TheMtl->Set_Sec_Gradient(PassIndex, W3DSHADER_SECGRADIENT_DEFAULT);
	TheMtl->Set_Depth_Compare(PassIndex, W3DSHADER_DEPTHCOMPARE_DEFAULT);
	TheMtl->Set_Detail_Color_Func(PassIndex, W3DSHADER_DETAILCOLORFUNC_DEFAULT);
	TheMtl->Set_Detail_Alpha_Func(PassIndex, W3DSHADER_DETAILALPHAFUNC_DEFAULT);

	TheMtl->Notify_Changed();
	ReloadDialog();
}