/*
Copyright (c) 1998 Richard Lawrence

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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// CSoundDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Atari800Win.h"
#include "CSoundDlg.h"
#include "winatari.h"
#include "CWarnDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern "C" 
{
#include "registry.h"
extern BOOL Sound_VolumeCapable( void );
extern void WriteRegDWORD( HKEY hkInput, char *item, DWORD value);
extern ULONG	ulSoundState;
extern int	nSoundRate, nSoundVol;
extern void	Clear_Sound( BOOL bPermanent );
extern void Sound_Initialise( void );
extern void Sound_SetVolume( void );
extern int	nSkipUpdateDefault;
extern ULONG	ulDontShowFlags;
extern int	default_tv_mode;
}

static int	nNewSkipDefault;
static int	nLowSkipLimit = 1;
static int nHighSkipLimit = 262;
static int nSoundRates[7] = { 8000, 11025, 21280, 22050, 31920, 44100, 48000 };
static int nLowLimits[7] = { 6, 4, 2, 2, 2, 1, 1 };
/////////////////////////////////////////////////////////////////////////////
// SoundDlg dialog


SoundDlg::SoundDlg(CWnd* pParent /*=NULL*/)
	: CDialog(SoundDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(SoundDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void SoundDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(SoundDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(SoundDlg, CDialog)
	//{{AFX_MSG_MAP(SoundDlg)
	ON_BN_CLICKED(IDC_SOUND_MMSOUND, OnSoundMmsound)
	ON_BN_CLICKED(IDC_SOUND_DIRECTSOUND, OnSoundDirectsound)
	ON_BN_CLICKED(IDC_SOUND_NOSOUND, OnSoundNosound)
	ON_BN_CLICKED(IDC_SOUND_FORCE_PRIMARY, OnSoundForcePrimary)
	ON_NOTIFY(UDN_DELTAPOS, IDC_POKEY_DIVISOR_SPIN, OnDeltaposPokeyDivisorSpin)
	ON_CBN_SELCHANGE(IDC_SOUND_PLAYBACK, OnSelchangeSoundPlayback)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// SoundDlg message handlers

void SoundDlg::SetPokeyDivisor( void )
{
	char	szDigits[16];

	if( nNewSkipDefault < nLowSkipLimit )
		nNewSkipDefault = nLowSkipLimit;
	if( nNewSkipDefault > nHighSkipLimit )
		nNewSkipDefault = nHighSkipLimit;

	itoa( nNewSkipDefault, szDigits, 10 );
	SetDlgItemText( IDC_POKEY_DIVISOR, szDigits );
}

void SoundDlg::SetButtons( void )
{
	CButton *cbCheckBox = NULL;
	CSliderCtrl	*cSlider;
	CComboBox	*pCombo = NULL;

	if( default_tv_mode == 1 )
		nHighSkipLimit = 262;
	else
		nHighSkipLimit = 312;

	cSlider = (CSliderCtrl *)GetDlgItem( IDC_VOLUME_SLIDER );
	if( cSlider )
	{
		cSlider->EnableWindow( Sound_VolumeCapable( ) );
		cSlider->SetRange( 0, 100, FALSE );
		cSlider->SetPos( 100 + iNewSoundVol );
	}

#ifdef USE_DSOUND
	cbCheckBox = (CButton *)GetDlgItem( IDC_SOUND_FORCE_PRIMARY );
	if( !cbCheckBox )
		return;

	if( iNewSoundState & SOUND_FORCE_PRIMARY )
		cbCheckBox->SetCheck( 1 );
	else
		cbCheckBox->SetCheck( 0 );

	if( iNewSoundState & SOUND_MMSOUND )
		CheckRadioButton( IDC_SOUND_MMSOUND, IDC_SOUND_DIRECTSOUND, IDC_SOUND_MMSOUND );
	else
#endif
		CheckRadioButton( IDC_SOUND_MMSOUND, IDC_SOUND_DIRECTSOUND, IDC_SOUND_DIRECTSOUND );

	pCombo = (CComboBox *)GetDlgItem( IDC_SOUND_PLAYBACK );
	if( pCombo )
	{
		switch( iNewSoundRate )
		{
			case	8000:
				pCombo->SetCurSel( 0 );
				nLowSkipLimit = 6;
				break;

			case	11025:
				pCombo->SetCurSel( 1 );
				nLowSkipLimit = 4;
				break;

			case	21280:
				pCombo->SetCurSel( 2 );
				nLowSkipLimit = 2;
				break;

			case	22050:
				pCombo->SetCurSel( 3 );
				nLowSkipLimit = 2;
				break;

			case	31920:
				pCombo->SetCurSel( 4 );
				nLowSkipLimit = 2;
				break;

			case	44100:
				pCombo->SetCurSel( 5 );
				nLowSkipLimit = 1;
				break;

			case	48000:
				pCombo->SetCurSel( 6 );
				nLowSkipLimit = 1;
				break;

			default:
				pCombo->SetCurSel( 5 );
				iNewSoundRate = 44100;
				nLowSkipLimit = 1;
				break;
		}
	}

	nNewSkipDefault = nSkipUpdateDefault;
	SetPokeyDivisor();
	
	cbCheckBox = (CButton *)GetDlgItem( IDC_SOUND_NOSOUND );
	if( !cbCheckBox )
		return;
	
	if( iNewSoundState & SOUND_NOSOUND )
		cbCheckBox->SetCheck( 1 );
	else
		cbCheckBox->SetCheck( 0 );
}

BOOL SoundDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	iNewSoundState = ulSoundState;
	iNewSoundRate = nSoundRate;
	iNewSoundVol = nSoundVol;
	
	SetButtons();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void SoundDlg::OnSelchangeSoundPlayback() 
{
	CComboBox	*pCombo = NULL;
	pCombo = (CComboBox *)GetDlgItem( IDC_SOUND_PLAYBACK );
	if( pCombo )
	{
		nLowSkipLimit = nLowLimits[ pCombo->GetCurSel() ];
		iNewSoundRate = nSoundRates[ pCombo->GetCurSel() ];
		SetPokeyDivisor();
	}
	if( iNewSoundRate == 22050 )
		iNewSoundState &= ~SOUND_CUSTOM_RATE;
	else
		iNewSoundState |= SOUND_CUSTOM_RATE;
}

void SoundDlg::OnSoundMmsound() 
{
	iNewSoundState |= SOUND_MMSOUND;
#ifdef USE_DSOUND
	iNewSoundState &= ~SOUND_DIRECTSOUND;
	SetButtons();
#endif
}


void SoundDlg::OnSoundDirectsound() 
{
#ifdef USE_DSOUND
	iNewSoundState &= ~SOUND_MMSOUND;
	iNewSoundState |= SOUND_DIRECTSOUND;
	SetButtons();
#endif
}

void SoundDlg::OnSoundForcePrimary() 
{
#ifdef USE_DSOUND
	if( iNewSoundState & SOUND_FORCE_PRIMARY )
		iNewSoundState &= ~SOUND_FORCE_PRIMARY;
	else
		iNewSoundState |= SOUND_FORCE_PRIMARY;
	SetButtons();
#endif
}

void SoundDlg::OnSoundNosound() 
{
	if( iNewSoundState & SOUND_NOSOUND )
	{
		iNewSoundState &= ~SOUND_NOSOUND;
#ifndef USE_DSOUND
		iNewSoundState |= SOUND_MMSOUND;
#endif
	}
	else
	{
		iNewSoundState |= SOUND_NOSOUND;
	}
	SetButtons();
}

void SoundDlg::OnOK() 
{
	CSliderCtrl	*cSlider;
	cSlider = (CSliderCtrl *)GetDlgItem( IDC_VOLUME_SLIDER );
	if( cSlider )
		iNewSoundVol = cSlider->GetPos() - 100;

	if( iNewSoundVol != nSoundVol )
	{
		nSoundVol = iNewSoundVol;
		WriteRegDWORD( NULL, REG_SOUND_VOLUME, nSoundVol );
		Sound_SetVolume( );
	}

	if( (iNewSoundState != ulSoundState) || (iNewSoundRate != nSoundRate) || nNewSkipDefault!= nSkipUpdateDefault )
	{
		WriteRegDWORD( NULL, REG_SOUND_STATE, iNewSoundState );
		WriteRegDWORD( NULL, REG_SOUND_RATE, iNewSoundRate );

		ulSoundState = iNewSoundState;
		nSoundRate = iNewSoundRate;
		nSkipUpdateDefault = nNewSkipDefault;
		Clear_Sound( TRUE );
		Sound_Initialise();
	}
	CDialog::OnOK();
}


void SoundDlg::OnDeltaposPokeyDivisorSpin(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
	nNewSkipDefault -= pNMUpDown->iDelta;

	SetPokeyDivisor();

	*pResult = nNewSkipDefault;
}

