// FontDlgDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FontDlg.h"
#include "FontDlgDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFontDlgDlg dialog

CFontDlgDlg::CFontDlgDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CFontDlgDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CFontDlgDlg)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFontDlgDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CFontDlgDlg)
    DDX_Control(pDX, IDC_CONDHEADERS, m_CondHeaders);
    DDX_Control(pDX, IDC_SAMPLE_TEXT, m_Sample);
    DDX_Control(pDX, IDC_SAMPLE_FRAME, m_Frame);
    DDX_Control(pDX, IDC_FONTNAMES, m_FontNames);
    DDX_Control(pDX, IDC_FONTSTYLES, m_FontStyles);
    DDX_Control(pDX, IDC_FONTSIZES, m_FontSizes);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFontDlgDlg, CDialog)
    //{{AFX_MSG_MAP(CFontDlgDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_CTLCOLOR()
    ON_BN_CLICKED(IDC_CONDHEADERS, OnCondheaders)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFontDlgDlg message handlers

BOOL CFontDlgDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // reset font for all combo boxes to use the form's
    // default font
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
    vFontNames->PutFont(NULL);
    vFontNames->Headers->PutFont(NULL);
    vFontNames->Edit->PutFont(NULL);
    ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();
    vFontStyles->PutFont(NULL);
    vFontStyles->Headers->PutFont(NULL);
    vFontStyles->Edit->PutFont(NULL);
    ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();
    vFontSizes->PutFont(NULL);
    vFontSizes->Headers->PutFont(NULL);
    vFontSizes->Edit->PutFont(NULL);

    // set sort order
    // add all font information
    UpdateFontNames();
    
    return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFontDlgDlg::OnPaint() 
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFontDlgDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

HBRUSH CFontDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    if (pWnd == &m_Frame || pWnd == &m_Sample) {
        pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
        pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        m_Brush.DeleteObject();
        m_Brush.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
        return (HBRUSH)m_Brush;
    }
    return hbr;
}

void CFontDlgDlg::UpdateFontNames()
{
    // add all font names
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();

    vFontNames->BulkUpdate = VARIANT_TRUE;
    vFontNames->Items->Clear();
    vFontNames->Items->AddFontNames(-1, fontSftBoxAll, VARIANT_TRUE, 0);
    vFontNames->Items->Selection = 0;
    PerformSort(vFontNames, sortSftBoxAscending);
    vFontNames->BulkUpdate = VARIANT_FALSE;
    vFontNames->Columns->MakeOptimal(0);
    vFontNames->Items->RecalcHorizontalExtent(0);

    m_CondHeaders.SetCheck(1);
}

void CFontDlgDlg::UpdateFontStyles()
{
    // add all styles for the current font name
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
    ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();

    if (vFontNames->Items->Selection >= 0) {
        CString OldText((LPCTSTR) vFontStyles->Edit->Text);
        vFontStyles->Items->AddFontStyles(vFontNames->Cell[vFontNames->Items->Selection][0]->Text, 0, "", "");
        long index;
        vFontStyles->Items->raw_Find((_bstr_t)OldText, 0, 0, VARIANT_FALSE, VARIANT_TRUE, VARIANT_TRUE, &index);
        if (index < 0) index = 0;
        vFontStyles->Items->Selection = index;
    } else
        vFontStyles->Items->Clear();
    PerformSort(vFontStyles, sortSftBoxAscending);
    vFontStyles->Columns->MakeOptimal(0);
    vFontStyles->Items->RecalcHorizontalExtent(0);
}

void CFontDlgDlg::UpdateFontSizes()
{
    // add all sizes for the current font name
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
    ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();

    if (vFontNames->Items->Selection >= 0) {
        CString OldText((LPCTSTR) vFontSizes->Edit->Text);
        vFontSizes->Items->AddFontSizes(vFontNames->Cell[vFontNames->Items->Selection][0]->Text, 0);
        long index;
        vFontSizes->Items->raw_Find((_bstr_t)OldText, 0, 0, VARIANT_FALSE, VARIANT_TRUE, VARIANT_TRUE, &index);
        if (index < 0) index = 0;
        vFontSizes->Items->Selection = index;
    } else
        vFontSizes->Items->Clear();
    PerformSortSize(vFontSizes, sortSftBoxAscending); 
    vFontSizes->Columns->MakeOptimal(0);
    vFontSizes->Items->RecalcHorizontalExtent(0);
    UpdateSample();
}

void CFontDlgDlg::UpdateSample()
{
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
    ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();
    ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();

    long SelItem = vFontStyles->Items->Selection;
    if (SelItem >= 0 && lstrcmp(vFontSizes->Edit->Text, "") != 0) {
        m_Sample.SetWindowText(_T("AaBbCcYyZz"));
        long val = vFontStyles->Cell[SelItem][0]->Data;
        BOOL fItalic = (val & 0x80000000L) != 0;
        val &= 0x7fffffff;

        m_SampleFont.DeleteObject();
        // convert point size to pixels
        CDC* pDC;
        pDC = GetDC();
        int height = MulDiv(atoi(vFontSizes->Edit->Text), pDC->GetDeviceCaps(LOGPIXELSY), 72);
        ReleaseDC(pDC);
        m_SampleFont.CreateFont(-height, 0, 0, 0, val, fItalic, 0, 0, 0, 0, 0, 0, 0, vFontNames->Edit->Text);
        m_Sample.SetFont(&m_SampleFont);
    } else
        m_Sample.SetWindowText(_T(""));
}

void CFontDlgDlg::OnCondheaders() 
{
    ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
    ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();
    ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();

    if (m_CondHeaders.GetCheck()) {
        vFontNames->Headers->Main = VARIANT_TRUE;
        vFontNames->Headers->DropDown = VARIANT_FALSE;
        vFontStyles->Headers->Main = VARIANT_TRUE;
        vFontStyles->Headers->DropDown = VARIANT_FALSE;
        vFontSizes->Headers->Main = VARIANT_TRUE;
        vFontSizes->Headers->DropDown = VARIANT_FALSE;
    } else {
        vFontNames->Headers->Main = VARIANT_FALSE;
        vFontNames->Headers->DropDown = VARIANT_TRUE;
        vFontStyles->Headers->Main = VARIANT_FALSE;
        vFontStyles->Headers->DropDown = VARIANT_TRUE;
        vFontSizes->Headers->Main = VARIANT_FALSE;
        vFontSizes->Headers->DropDown = VARIANT_TRUE;
    }
}

void CFontDlgDlg::PerformSort(ISftBoxPtr box, SftBoxSortConstants currDirection)
{
    if (currDirection == sortSftBoxAscending)
        box->Header[0]->Image->Appearance = sftImageSortAsc;
    else
        box->Header[0]->Image->Appearance = sftImageSortDesc;
    // Font styles and font names are sorted by Cell.Text property
    box->Items->Sort(-1, 0, currDirection);
}

void CFontDlgDlg::PerformSortSize(ISftBoxPtr box, SftBoxSortConstants currDirection)
{
    if (currDirection == sortSftBoxAscending)
        box->Header[0]->Image->Appearance = sftImageSortAsc;
    else
        box->Header[0]->Image->Appearance = sftImageSortDesc;
    // Font sizes are sorted according to numeric Cell.Data property
    // Outside of this function, only sortSftBoxAscending and sortSftBoxDescending
    // are used, so we need to translate these
    if (currDirection == sortSftBoxAscending)
        currDirection = sortSftBoxCellValueAscending;
    else
        currDirection = sortSftBoxCellValueDescending;
    box->Items->Sort(-1, 0, currDirection);
}

void CFontDlgDlg::ReverseSortOrder(ISftBoxPtr box, SftBoxSortConstants& currDirection)
{
    if (currDirection == sortSftBoxAscending)
        currDirection = sortSftBoxDescending;
    else
        currDirection = sortSftBoxAscending;
}

void CFontDlgDlg::OnSelectionChangeFontnames() 
{
    UpdateFontStyles();
}

void CFontDlgDlg::OnSelectionChangeFontstyles() 
{
    UpdateFontSizes();
}

void CFontDlgDlg::OnSelectionChangeFontsizes() 
{
    UpdateSample();
}

void CFontDlgDlg::OnItemClickFontnames(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
        ReverseSortOrder(vFontNames, m_fontNamesDirection);
        PerformSort(vFontNames, m_fontNamesDirection);
    }
}

void CFontDlgDlg::OnItemDblClkFontnames(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontNames = m_FontNames.GetControlUnknown();
        ReverseSortOrder(vFontNames, m_fontNamesDirection);
        PerformSort(vFontNames, m_fontNamesDirection);
    }
}

void CFontDlgDlg::OnItemClickFontstyles(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();
        ReverseSortOrder(vFontStyles, m_fontStylesDirection);
        PerformSort(vFontStyles, m_fontStylesDirection);
    }
}

void CFontDlgDlg::OnItemDblClkFontstyles(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontStyles = m_FontStyles.GetControlUnknown();
        ReverseSortOrder(vFontStyles, m_fontStylesDirection);
        PerformSort(vFontStyles, m_fontStylesDirection);
    }
}

void CFontDlgDlg::OnItemClickFontsizes(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();
        ReverseSortOrder(vFontSizes, m_fontSizesDirection);
        PerformSortSize(vFontSizes, m_fontSizesDirection);
    }
}

void CFontDlgDlg::OnItemDblClkFontsizes(long Part, long AreaType, long ItemIndex, short ColNum, short Button, short Shift) 
{
    if (AreaType == areaSftBoxColumn) {
        ISftBoxPtr vFontSizes = m_FontSizes.GetControlUnknown();
        ReverseSortOrder(vFontSizes, m_fontSizesDirection);
        PerformSortSize(vFontSizes, m_fontSizesDirection);
    }
}


BEGIN_EVENTSINK_MAP(CFontDlgDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CFontDlgDlg)
    ON_EVENT(CFontDlgDlg, IDC_FONTNAMES, 20 /* SelectionChange */, OnSelectionChangeFontnames, VTS_NONE)
    ON_EVENT(CFontDlgDlg, IDC_FONTSTYLES, 20 /* SelectionChange */, OnSelectionChangeFontstyles, VTS_NONE)
    ON_EVENT(CFontDlgDlg, IDC_FONTSIZES, 20 /* SelectionChange */, OnSelectionChangeFontsizes, VTS_NONE)
    ON_EVENT(CFontDlgDlg, IDC_FONTNAMES, 8 /* ItemClick */, OnItemClickFontnames, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    ON_EVENT(CFontDlgDlg, IDC_FONTNAMES, 9 /* ItemDblClk */, OnItemDblClkFontnames, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    ON_EVENT(CFontDlgDlg, IDC_FONTSTYLES, 8 /* ItemClick */, OnItemClickFontstyles, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    ON_EVENT(CFontDlgDlg, IDC_FONTSTYLES, 9 /* ItemDblClk */, OnItemDblClkFontstyles, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    ON_EVENT(CFontDlgDlg, IDC_FONTSIZES, 8 /* ItemClick */, OnItemClickFontsizes, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    ON_EVENT(CFontDlgDlg, IDC_FONTSIZES, 9 /* ItemDblClk */, OnItemDblClkFontsizes, VTS_I4 VTS_I4 VTS_I4 VTS_I2 VTS_I2 VTS_I2)
    //}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()