/****************************************************************************
File    : SettingsDlg.cpp
/*
@(#) #SY# Atari800Win PLus
@(#) #IS# CSettingsDlg implementation file
@(#) #BY# Tomasz Szymankowski
@(#) #LM# 17.03.2002
*/

#include "StdAfx.h"
#include "Atari800Win.h"
#include "Helpers.h"
#include "WarningDlg.h"
#include "SettingsAdvDlg.h"
#include "SettingsDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define IDC_SETTINGS_FIRST		IDC_SETTINGS_DISABLEBASIC
#define IDC_SETTINGS_LAST		IDC_SETTINGS_CANCEL


/////////////////////////////////////////////////////////////////////////////
// CSettingsDlg dialog

BEGIN_MESSAGE_MAP(CSettingsDlg, CCommonDlg)
	//{{AFX_MSG_MAP(CSettingsDlg)
	ON_BN_CLICKED(IDC_SETTINGS_DISABLEBASIC, OnDisableBasic)
	ON_BN_CLICKED(IDC_SETTINGS_ENABLESIO, OnEnableSio)
	ON_BN_CLICKED(IDC_SETTINGS_ENABLEH, OnEnableH)
	ON_BN_CLICKED(IDC_SETTINGS_ENABLEP, OnEnableP)
	ON_BN_CLICKED(IDC_SETTINGS_ENABLER, OnEnableR)
	ON_BN_CLICKED(IDC_SETTINGS_HARDREADONLY, OnHardReadOnly)
	ON_BN_CLICKED(IDC_SETTINGS_PRINTCHECK, OnPrintCheck)
	ON_EN_KILLFOCUS(IDC_SETTINGS_PRINTCMD, OnKillfocusPrintCmd)
	ON_BN_CLICKED(IDC_SETTINGS_ADVSETTING, OnAdvSetting)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_SETTINGS_OK, OnOK)
	ON_BN_CLICKED(IDC_SETTINGS_CANCEL, CCommonDlg::OnCancel)
END_MESSAGE_MAP()

/*========================================================
Method   : CSettingsDlg::CSettingsDlg
=========================================================*/
/* #FN#
   Standard constructor */
CSettingsDlg::
CSettingsDlg(
	CWnd *pParent /*=NULL*/ /* #IN# Pointer to the parent window */
)
	: CCommonDlg( CSettingsDlg::IDD, pParent )
{
	//{{AFX_DATA_INIT(CSettingsDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

	m_bReboot    = FALSE;
	m_nFirstCtrl = IDC_SETTINGS_FIRST;
	m_nLastCtrl  = IDC_SETTINGS_LAST;
} /* #OF# CSettingsDlg::CSettingsDlg */

/*========================================================
Method   : CSettingsDlg::DoDataExchange
=========================================================*/
/* #FN#
   Dynamic Data Exchange (not used) */
void
/* #AS#
   Nothing */
CSettingsDlg::
DoDataExchange(
	CDataExchange *pDX /* #IN# Pointer to CDataExchange object */
)
{
	CCommonDlg::DoDataExchange( pDX );
	//{{AFX_DATA_MAP(CSettingsDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
} /* #OF# CSettingsDlg::DoDataExchange */


/////////////////////////////////////////////////////////////////////////////
// CSettingsDlg implementation

/*========================================================
Method   : CSettingsDlg::SetDlgState
=========================================================*/
/* #FN#
   Sets up the state of the dialog controls */
void
/* #AS#
   Nothing */
CSettingsDlg::
SetDlgState()
{
	CButton	*pButton = NULL;
	CWnd	*pWnd    = NULL;

	/* Set up check buttons states */
	if( m_nDisableBasic )
	{
		pButton = (CButton*)GetDlgItem( IDC_SETTINGS_DISABLEBASIC );
		ASSERT(pButton);
		pButton->SetCheck( 1 );
	}
	if( m_nEnableSIOPatch )
	{
		pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLESIO );
		ASSERT(pButton);
		pButton->SetCheck( 1 );
	}
	if( m_nEnableHPatch )
	{
		pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLEH );
		ASSERT(pButton);
		pButton->SetCheck( 1 );
	}
	pButton = (CButton *)GetDlgItem( IDC_SETTINGS_HARDREADONLY );
	ASSERT(pButton);
	pButton->SetCheck( m_nHardReadOnly );
	pButton->EnableWindow( m_nEnableHPatch );

	if( m_nEnablePPatch )
	{
		pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLEP );
		ASSERT(pButton);
		pButton->SetCheck( 1 );
	}
	pButton = (CButton *)GetDlgItem( IDC_SETTINGS_PRINTCHECK );
	ASSERT(pButton);
	pButton->SetCheck( (m_ulMiscState & MS_USE_PRINT_COMMAND) != 0 );
	pButton->EnableWindow( m_nEnablePPatch );

	/* An alternative print command */
	SetDlgItemText( IDC_SETTINGS_PRINTCMD, m_szPrintCommand );

	pWnd = GetDlgItem( IDC_SETTINGS_PRINTCMD );
	ASSERT(pWnd);
	pWnd->EnableWindow( m_nEnablePPatch && m_ulMiscState & MS_USE_PRINT_COMMAND );

	pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLER );
	ASSERT(pButton);
	if( m_nEnableRPatch )
		pButton->SetCheck( 1 );
	pButton->EnableWindow( sock_capable() != -1 );
} /* #OF# CSettingsDlg::SetDlgState */


/////////////////////////////////////////////////////////////////////////////
// CSettingsDlg message handlers

/*========================================================
Method   : CSettingsDlg::OnInitDialog
=========================================================*/
/* #FN#
   Performs special processing when the dialog box is initialized */
BOOL
/* #AS#
   TRUE unless you set the focus to a control */
CSettingsDlg::
OnInitDialog()
{
	CCommonDlg::OnInitDialog();

	m_ulMiscState     = g_Misc.ulState;
	m_nDisableBasic   = disable_basic;
	m_nEnableSIOPatch = enable_sio_patch;
	m_nEnableHPatch   = enable_h_patch;
	m_nEnablePPatch   = enable_p_patch;
	m_nEnableRPatch   = enable_r_patch;
	m_nHardReadOnly   = hd_read_only;
	m_nEnableRTime    = rtime_enabled;

	strncpy( m_szPrintCommand, print_command, PRINT_CMD_LENGTH );

	SetDlgState();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
} /* #OF# CSettingsDlg::OnInitDialog */

/*========================================================
Method   : CSettingsDlg::OnDisableBasic
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnDisableBasic()
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_DISABLEBASIC );
	ASSERT(pButton);
	m_nDisableBasic = pButton->GetCheck();
} /* #OF# CSettingsDlg::OnDisableBasic */

/*========================================================
Method   : CSettingsDlg::OnEnableSio
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnEnableSio() 
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLESIO );
	ASSERT(pButton);
	m_nEnableSIOPatch = pButton->GetCheck();
} /* #OF# CSettingsDlg::OnEnableSio */

/*========================================================
Method   : CSettingsDlg::OnEnableH
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnEnableH()
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLEH );
	ASSERT(pButton);
	m_nEnableHPatch = pButton->GetCheck();

	SetDlgState();
} /* #OF# CSettingsDlg::OnEnableH */

/*========================================================
Method   : CSettingsDlg::OnEnableP
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnEnableP()
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLEP );
	ASSERT(pButton);
	m_nEnablePPatch = pButton->GetCheck();

	SetDlgState();
} /* #OF# CSettingsDlg::OnEnableP */

/*========================================================
Method   : CSettingsDlg::OnEnableR
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnEnableR()
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_ENABLER );
	ASSERT(pButton);
	m_nEnableRPatch = pButton->GetCheck();
} /* #OF# CSettingsDlg::OnEnableR */

/*========================================================
Method   : CSettingsDlg::OnHardReadOnly
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnHardReadOnly()
{
	CButton *pButton = (CButton *)GetDlgItem( IDC_SETTINGS_HARDREADONLY );
	ASSERT(pButton);
	m_nHardReadOnly = pButton->GetCheck();
} /* #OF# CSettingsDlg::OnHardReadOnly */

/*========================================================
Method   : CSettingsDlg::OnPrintCheck
=========================================================*/
/* #FN#
	Sets a state of the object regarding to an appropriate check box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnPrintCheck()
{
	_ClickButton( IDC_SETTINGS_PRINTCHECK, m_ulMiscState, MS_USE_PRINT_COMMAND );
	SetDlgState();
} /* #OF# CSettingsDlg::OnPrintCheck */

/*========================================================
Method   : CSettingsDlg::OnKillfocusPrintCmd
=========================================================*/
/* #FN#
   The framework calls this function before an edit losing input focus */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnKillfocusPrintCmd()
{
	GetDlgItemText( IDC_SETTINGS_PRINTCMD, m_szPrintCommand, PRINT_CMD_LENGTH );
} /* #OF# CSettingsDlg::OnKillfocusPrintCmd */

/*========================================================
Method   : CSettingsDlg::OnAdvSetting
=========================================================*/
/* #FN#
   Displays "Advanced Atari Setting" dialog box */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnAdvSetting()
{
	CSettingsAdvDlg dlgSettingsAdv( &m_ulMiscState,
									&m_nEnableRTime,
									this );
	dlgSettingsAdv.DoModal();
} /* #OF# CSettingsDlg::OnAdvSetting */

/*========================================================
Method   : CSettingsDlg::ReceiveFocused
=========================================================*/
/* #FN#
   Receive the edit controls content again. The user could press
   'Enter' or 'Alt-O' and then all changes he's made in the last
   edited control would be lost. */
void
/* #AS#
   Nothing */
CSettingsDlg::
ReceiveFocused()
{
	CWnd *pWnd    = GetFocus();
	UINT  nCtrlID = pWnd ? pWnd->GetDlgCtrlID() : 0;

	if( IDC_SETTINGS_PRINTCMD == nCtrlID )
	{
		OnKillfocusPrintCmd();
	}
} /* #OF# CSettingsDlg::ReceiveFocused */

/*========================================================
Method   : CSettingsDlg::OnOK
=========================================================*/
/* #FN#
   Called when the user clicks the OK button */
void
/* #AS#
   Nothing */
CSettingsDlg::
OnOK() 
{
	/* Unfortunately, edit controls do not lose the focus before
	   handling this when the user uses accelerators */
	ReceiveFocused();

	if( m_nDisableBasic != disable_basic )
	{
		disable_basic = m_nDisableBasic;
		WriteRegDWORD( NULL, REG_DISABLE_BASIC, disable_basic );

//		m_bReboot = TRUE; /* I think we don't really need this */
	}
	if( m_nEnableSIOPatch != enable_sio_patch )
	{
		enable_sio_patch = m_nEnableSIOPatch;
		WriteRegDWORD( NULL, REG_ENABLE_SIO_PATCH, enable_sio_patch );

		Atari800_UpdatePatches();
	}
	if( m_nEnableHPatch != enable_h_patch )
	{
		enable_h_patch = m_nEnableHPatch;
		WriteRegDWORD( NULL, REG_ENABLE_H_PATCH, enable_h_patch );

		Atari800_UpdatePatches();
	}
	if( m_nEnablePPatch != enable_p_patch )
	{
		enable_p_patch = m_nEnablePPatch;
		WriteRegDWORD( NULL, REG_ENABLE_P_PATCH, enable_p_patch );

		Atari800_UpdatePatches();
	}
	if( m_nEnableRPatch != enable_r_patch )
	{
		enable_r_patch = m_nEnableRPatch;
		WriteRegDWORD( NULL, REG_ENABLE_R_PATCH, enable_r_patch );

		RDevice_UpdatePatches();
		Atari800_UpdatePatches();
	}
	if( m_nHardReadOnly != hd_read_only )
	{
		hd_read_only = m_nHardReadOnly;
		WriteRegDWORD( NULL, REG_HD_READ_ONLY, hd_read_only );
	}
	if( m_nEnableRTime != rtime_enabled )
	{
		rtime_enabled = m_nEnableRTime;
		WriteRegDWORD( NULL, REG_ENABLE_RTIME, rtime_enabled );

		m_bReboot = TRUE;
	}
	if( m_ulMiscState != g_Misc.ulState )
	{
		g_Misc.ulState = m_ulMiscState;
		WriteRegDWORD( NULL, REG_MISC_STATE, g_Misc.ulState );
	}

	if( *m_szPrintCommand == '\0' )
		strcpy( m_szPrintCommand, DEF_PRINT_COMMAND );
	if( _stricmp( m_szPrintCommand, print_command ) != 0 )
	{
		strncpy( print_command, m_szPrintCommand, PRINT_CMD_LENGTH );
		WriteRegString( NULL, REG_PRINT_COMMAND, print_command );
	}
	CCommonDlg::OnOK();
} /* #OF# CSettingsDlg::OnOK */
