// ProppageGeneral.cpp : implementation file
//

#include "stdafx.h"
#include "dslavsplit.h"
#include "ProppageGeneral.h"

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

/////////////////////////////////////////////////////////////////////////////
// CProppageGeneral property page
// 11/23-2 New class


IMPLEMENT_DYNCREATE(CProppageGeneral, CPropertyPage)

CProppageGeneral::CProppageGeneral() : CPropertyPage(CProppageGeneral::IDD)
{
	TRACE(_T("In CProppageGeneral ctr.\n"));

	//{{AFX_DATA_INIT(CProppageGeneral)
	m_bStartVol = FALSE;
	m_iVolPercent = 0;
	//}}AFX_DATA_INIT

	// Members
	ZeroMemory(&m_listLf, sizeof(LOGFONT));
	ZeroMemory(&m_treeLf, sizeof(LOGFONT));
}

CProppageGeneral::~CProppageGeneral()
{
}

void CProppageGeneral::DoDataExchange(CDataExchange* pDX)
{
	TRACE(_T("In CProppageGeneral::DoDataExchange.\n"));

	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CProppageGeneral)
	DDX_Control(pDX, IDC_COMBO_FONT_SZ_RIGHT, m_comboFontSzRight);
	DDX_Control(pDX, IDC_COMBO_FONT_SZ_LEFT, m_comboFontSzLeft);
	DDX_Control(pDX, IDC_COMBO_FONT_RIGHT, m_comboFontRight);
	DDX_Control(pDX, IDC_COMBO_FONT_LEFT, m_comboFontLeft);
	DDX_Control(pDX, IDC_EDIT_START_VOL_PCT, m_editVolPercent);
	DDX_Control(pDX, IDC_CHECK_START_VOL, m_checkStartVol);
	DDX_Check(pDX, IDC_CHECK_START_VOL, m_bStartVol);
	DDX_Text(pDX, IDC_EDIT_START_VOL_PCT, m_iVolPercent);
	DDV_MinMaxInt(pDX, m_iVolPercent, 0, 100);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CProppageGeneral, CPropertyPage)
	//{{AFX_MSG_MAP(CProppageGeneral)
	ON_CBN_CLOSEUP(IDC_COMBO_FONT_LEFT, OnCloseupFontLeft)
	ON_CBN_CLOSEUP(IDC_COMBO_FONT_RIGHT, OnCloseupFontRight)
	ON_CBN_CLOSEUP(IDC_COMBO_FONT_SZ_LEFT, OnCloseupFontSzLeft)
	ON_CBN_CLOSEUP(IDC_COMBO_FONT_SZ_RIGHT, OnCloseupFontSzRight)
	ON_BN_CLICKED(IDC_CHECK_START_VOL, OnCheckLastStartVol)
	ON_EN_KILLFOCUS(IDC_EDIT_START_VOL_PCT, OnKillfocusStartVolPct)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// Initialize m_comboFontLeft with TT Fonts.
void CProppageGeneral::InitFontComboLeft()
{
	CString str;
	CSize szStr;
	int max = 0;

	// Empty
	m_comboFontLeft.ResetContent();

	// Fill combo list.
	CClientDC dc (this);
    ::EnumFontFamilies ((HDC)dc, NULL, (FONTENUMPROC) EnumFontFamProcLeft,
        (LPARAM) this);

	// Get DC
	CDC * pDC = m_comboFontLeft.GetDC();

	// Set font for combo - needed for proper metrics.
	//
	LOGFONT lf;
	// Get existing font.
	m_comboFontLeft.GetFont()->GetLogFont(&lf);
	// Delete member as needed.
	if((HFONT)m_fontLeft)
	{
		pDC->SelectStockObject(SYSTEM_FONT);
		m_fontLeft.DeleteObject();
	}
	// Create new.
	if(!m_fontLeft.CreateFontIndirect(&lf))
	{
		TRACE(_T("Error - CProppageGeneral::InitFontsCombo CreateFont left failed\n"));
		return;
	}
	// Set and select into DC.
	m_comboFontLeft.SetFont(&m_fontLeft, FALSE);
	pDC->SelectObject(&m_fontLeft);

	// Get longest string.
	int sz = m_comboFontLeft.GetCount();
	for(int i = 0; i < sz; i++)
	{
		m_comboFontLeft.GetLBText(i, str);
		szStr = pDC->GetTextExtent(str);
		if(szStr.cx > max)
			max = szStr.cx;
	}
	// Add one char padding.
	szStr = pDC->GetTextExtent(_T("X"));
	max += szStr.cx;

	// Clean dc.
	m_comboFontLeft.ReleaseDC(pDC);

	// Adjust the width for the vert scroll bar.
	max += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * ::GetSystemMetrics(SM_CXEDGE);

	// Set the list box width.
	m_comboFontLeft.SetDroppedWidth(max);
}

// Initialize m_comboFontRight with TT Fonts.
void CProppageGeneral::InitFontComboRight()
{
	CString str;
	CSize szStr;
	int max = 0;

	// Empty
	m_comboFontRight.ResetContent();

	// Fill combo list.
	CClientDC dc (this);
    ::EnumFontFamilies((HDC)dc, NULL, (FONTENUMPROC) EnumFontFamProcRight, (LPARAM) this);

	// Get DC
	CDC * pDC = m_comboFontRight.GetDC();

	// Set font for combo - needed for proper metrics.
	//
	LOGFONT lf;
	// Get existing font.
	m_comboFontRight.GetFont()->GetLogFont(&lf);
	// Delete member as needed.
	if((HFONT)m_fontRight)
	{
		pDC->SelectStockObject(SYSTEM_FONT);
		m_fontRight.DeleteObject();
	}
	// Create new.
	if(!m_fontRight.CreateFontIndirect(&lf))
	{
		TRACE(_T("Error - CProppageGeneral::InitFontsCombo CreateFont Right failed\n"));
		return;
	}
	// Set and select into DC.
	m_comboFontRight.SetFont(&m_fontRight, FALSE);
	pDC->SelectObject(&m_fontRight);

	// Get longest string.
	int sz = m_comboFontRight.GetCount();
	for(int i = 0; i < sz; i++)
	{
		m_comboFontRight.GetLBText(i, str);
		szStr = pDC->GetTextExtent(str);
		if(szStr.cx > max)
			max = szStr.cx;
	}
	// Add one char padding.
	szStr = pDC->GetTextExtent(_T("X"));
	max += szStr.cx;

	// Clean dc.
	m_comboFontRight.ReleaseDC(pDC);

	// Adjust the width for the vert scroll bar.
	max += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * ::GetSystemMetrics(SM_CXEDGE);

	// Set the list box width.
	m_comboFontRight.SetDroppedWidth(max);
}

// FontsCombo EnumFontFamProc callback - right.
int CALLBACK CProppageGeneral::EnumFontFamProcRight(ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, 
													int nFontType, LPARAM lParam)
{
    CProppageGeneral * pWnd = (CProppageGeneral*) lParam;

	if(nFontType & TRUETYPE_FONTTYPE)
	{
		CString str = lpelf->elfLogFont.lfFaceName;
		pWnd->m_comboFontRight.AddString(str);
	}
	return 1;
}
// FontsCombo EnumFontFamProc callback - left.
int CALLBACK CProppageGeneral::EnumFontFamProcLeft(ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, 
												   int nFontType, LPARAM lParam)
{
    CProppageGeneral * pWnd = (CProppageGeneral*) lParam;

	if(nFontType & TRUETYPE_FONTTYPE)
	{
		CString str = lpelf->elfLogFont.lfFaceName;
		pWnd->m_comboFontLeft.AddString(str);
	}
	return 1;
}

// Select right and left font face name and size.
void CProppageGeneral::SetFontComboSels()
{
	CString fontName, fontSize;
	int iFontSz = 0, index = 0;

	// Set Left tree font combo sel Face Name.
	fontName = m_treeLf.lfFaceName;
	index = m_comboFontLeft.FindStringExact(-1, fontName);
	if(index == CB_ERR)
		index = 0;
	m_comboFontLeft.SetCurSel(index);

	// Set Right list font combo sel Face Name.
	fontName = m_listLf.lfFaceName;
	index = m_comboFontRight.FindStringExact(-1, fontName);
	if(index == CB_ERR)
		index = 0;
	m_comboFontRight.SetCurSel(index);

	// Set Left tree font Point Sz m_comboFontSzLeft sel.
	iFontSz = LogicalSizeToPointSize(m_treeLf.lfHeight);
	fontSize.Format(_T("%d"), iFontSz);
	index = m_comboFontSzLeft.FindStringExact(-1, fontSize);
	if(index == CB_ERR)
		index = 0;
	m_comboFontSzLeft.SetCurSel(index);

	// Set Right list font Point Sz m_comboFontSzRight sel.
	iFontSz = LogicalSizeToPointSize(m_listLf.lfHeight);
	fontSize.Format(_T("%d"), iFontSz);
	index = m_comboFontSzRight.FindStringExact(-1, fontSize);
	if(index == CB_ERR)
		index = 0;
	m_comboFontSzRight.SetCurSel(index);
}

// Logical to Point font size conversions:
//  Windows users are typically shown font sizes in "Point Size",
//  which is about 1/72 of an inch high.
//  The CreateFontIndirect() function takes a LOGFONT struct with 
//  its lfHeight member in logical units, which is MM_TEXT pixels 
//  for this app. 
//  So a neg -17 pixels Logical Size converts to a Points Size
//  of 10, which gets selected in the m_comboFontSz "Point Sizes"
//  combo, and a 10 Point Sz selected in the m_comboFontSz 
//  converts to -17 Logical Sz for use in the pane's LOGFONT.
//
// Convert Point font sz to Logical.
int CProppageGeneral::PointSizeToLogicalSize(int ptSz)
{
	CWindowDC dc(NULL);
	int logPixY = dc.GetDeviceCaps(LOGPIXELSY);			// 120

	// Point to Logical Size.
	//  For example, if ptSz = 10: 10 X 120 / 72 = -16.66 = -17
	int logSz = -MulDiv(ptSz, logPixY, 72);

	// Ensure neg.
	if(logSz > 0)
		return -logSz;
	else
		return logSz;
}
// Convert Logical font sz to Point.
int CProppageGeneral::LogicalSizeToPointSize(int logSz)
{
	CWindowDC dc(NULL);
	int logPixY = dc.GetDeviceCaps(LOGPIXELSY);			// 120

	// Logical Size to Point.
	//  For example, if logSz = -17: -17 X 72 / 120 = -10.2 = 10
	int ptSz = -MulDiv(logSz, 72, logPixY);

	// Ensure pos.
	return abs(ptSz);
}

/////////////////////////////////////////////////////////////////////////////
// CProppageGeneral message handlers

BOOL CProppageGeneral::OnInitDialog() 
{
	TRACE(_T("In CProppageGeneral::OnInitDialog()\n"));
	CPropertyPage::OnInitDialog();

	// Note CSettingsDlg::SetSettingsData() has initialized:
	//  m_listLf
	//  m_treeLf
	//  m_iVolPercent
	//  m_bStartVol	

	// Init m_comboFontSzLeft.
	m_comboFontSzLeft.ResetContent();
	CString str;
	for(int i = 8; i < 73; i++)	// 8 - 72
	{
		str.Format(_T("%d"), i);
		m_comboFontSzLeft.AddString(str);
	}
	// Init m_comboFontSzRight.
	m_comboFontSzRight.ResetContent();
	for(int i = 8; i < 73; i++)	// 8 - 72
	{
		str.Format(_T("%d"), i);
		m_comboFontSzRight.AddString(str);
	}
	// Init the fonts combos.
	InitFontComboLeft();
	InitFontComboRight();

	// Set Font and Font Size combo sels.
	SetFontComboSels();

	// Enable m_editVolPercent edit box per m_bStartVol.
	m_editVolPercent.EnableWindow(!m_bStartVol);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// Left pane tree font Face Name.
void CProppageGeneral::OnCloseupFontLeft() 
{
	int i = m_comboFontLeft.GetCurSel();
	if(i == CB_ERR)
		return;
	CString selected;
	m_comboFontLeft.GetLBText(i, selected);

	// Set tree LF with user selection.
	wcscpy(m_treeLf.lfFaceName, selected); 
}

// Right pane list font Face Name.
void CProppageGeneral::OnCloseupFontRight() 
{
	int i = m_comboFontRight.GetCurSel();
	if(i == CB_ERR)
		return;
	CString selected;
	m_comboFontRight.GetLBText(i, selected);

	// Set list LF with user selection.
	wcscpy(m_listLf.lfFaceName, selected); 
}

// Left pane tree font size.
void CProppageGeneral::OnCloseupFontSzLeft() 
{
	int i = m_comboFontSzLeft.GetCurSel();
	if(i == CB_ERR)
		return;
	CString selected;
	m_comboFontSzLeft.GetLBText(i, selected);

	// Note - should be no errors as the combo has
	// fixed strings from 8 to 72.

	// Get string as int.
	int iSel = _ttoi(selected);

	// Convert from point sz to logical sz (pixels)
	// and set tree LF.
	m_treeLf.lfHeight = PointSizeToLogicalSize(iSel);
}

// Right pane list font size.
void CProppageGeneral::OnCloseupFontSzRight() 
{
	int i = m_comboFontSzRight.GetCurSel();
	if(i == CB_ERR)
		return;
	CString selected;
	m_comboFontSzRight.GetLBText(i, selected);

	// Note - should be no errors as the combo has
	// fixed strings from 8 to 72.

	// Get string as int.
	int iSel = _ttoi(selected);

	// Convert from point sz to logical sz (pixels)
	// and set tree LF.
	m_listLf.lfHeight = PointSizeToLogicalSize(iSel);
}

void CProppageGeneral::OnCheckLastStartVol() 
{
	// Note DoDataExchange() setting m_bStartVol.

	// Get the check.
	UpdateData();
	// Enable m_editVolPercent edit box per m_bStartVol.
	m_editVolPercent.EnableWindow(!m_bStartVol);
	
}

void CProppageGeneral::OnKillfocusStartVolPct() 
{
	// DoDataExchange() handles validation, 0 - 100.	
}

