// DemoPropDlg.cpp : implementation file
//

#include "stdafx.h"
#include "demopaja.h"
#include "DemoPropDlg.h"
#include "PajaTypes.h"

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


using namespace PajaTypes;

/////////////////////////////////////////////////////////////////////////////
// CDemoPropDlg dialog


CDemoPropDlg::CDemoPropDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDemoPropDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDemoPropDlg)
	//}}AFX_DATA_INIT

	m_iCurPage = -1;
	m_pages.RemoveAll();

	m_pStartPage = NULL;
}

CDemoPropDlg::~CDemoPropDlg()
{
	// clean up
	for( int i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( i );
		delete pPS;
	}
}


void CDemoPropDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDemoPropDlg)
	DDX_Control(pDX, IDC_PAGETREE, m_rPageTree);
	DDX_Control(pDX, IDC_STATIC_BOUDINGFRAME, m_rStaticBoundingFrame);
	DDX_Control(pDX, IDC_STATIC_TITLE, m_rStaticTitle);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDemoPropDlg, CDialog)
	//{{AFX_MSG_MAP(CDemoPropDlg)
	ON_WM_CREATE()
	ON_NOTIFY(TVN_SELCHANGED, IDC_PAGETREE, OnSelchangedPagetree)
	ON_NOTIFY(TVN_GETDISPINFO, IDC_PAGETREE, OnGetdispinfoPagetree)
	//}}AFX_MSG_MAP
	ON_MESSAGE( WM_CHANGE_PAGE, OnChangePage )
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDemoPropDlg message handlers

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

	m_rFont.CreateFont( 14, 0, 0, 0, FW_BOLD, 0, 0, 0,
		ANSI_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,
		DEFAULT_PITCH | FF_DONTCARE,
		"arial" );

	m_rStaticTitle.SetFont( &m_rFont );


/*	long l = GetWindowLong( m_pageTree.m_hWnd, GWL_STYLE );
#if (_MSC_VER > 1100)
	l = l | TVS_TRACKSELECT ;
#else
	//#define TVS_TRACKSELECT         0x0200
	l = l | 0x0200;
#endif
	SetWindowLong(m_pageTree.m_hWnd, GWL_STYLE, l);*/

	// where will the dlgs live?
	m_rStaticBoundingFrame.GetWindowRect( m_frameRect );
	ScreenToClient( m_frameRect );
	m_frameRect.DeflateRect( 2, 2 );

	// set some styles for the pretty page indicator bar
/*	m_captionBar.m_textClr     = ::GetSysColor(COLOR_3DFACE);
	m_captionBar.m_fontWeight  = FW_BOLD;
	m_captionBar.m_fontSize    = 14;
	m_captionBar.m_csFontName  = "Verdana";
	m_captionBar.SetConstantText(m_csConstantText);*/

	// fill the tree. we'll create the pages as we need them
	for( int i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC *pPS = (PageStructC*)m_pages.GetAt( i );
		ASSERT( pPS );
		ASSERT( pPS->pDlg );
		if( pPS ) {
			TV_INSERTSTRUCT tvi;

			// find this node's parent...
			tvi.hParent = FindHTREEItemForDlg( pPS->pDlgParent );

			tvi.hInsertAfter = TVI_LAST;
			tvi.item.cchTextMax = 0;
			tvi.item.pszText = LPSTR_TEXTCALLBACK;
			tvi.item.lParam = (long)pPS;
			tvi.item.mask = TVIF_PARAM | TVIF_TEXT;

			HTREEITEM hTree = m_rPageTree.InsertItem( &tvi );

			// keep track of the dlg's we've added (for parent selection)
			if( hTree ) {
				DWORD dwTree = (DWORD)hTree;
				m_dlgMap.SetAt( pPS->pDlg, dwTree );
			}
		}
	}

	// start with page 0
	ShowPage( 0 );

	return TRUE;
}

HTREEITEM CDemoPropDlg::FindHTREEItemForDlg( CPrefSubDlg *pParent )
{
	// if you didn't specify a parent in AddPage(...) , the
	// dialog becomes a root-level entry
	if( pParent == NULL )
		return TVI_ROOT;
	else {
		DWORD dwHTree;
		if( m_dlgMap.Lookup( pParent, dwHTree ) )
			return (HTREEITEM)dwHTree;
		else {
			// you have specified a parent that has not 
			// been added to the tree - can't do that.
			ASSERT( FALSE );
			return TVI_ROOT;
		}
	}
}

LONG CDemoPropDlg::OnChangePage( UINT u, LONG l )
{
	if( ShowPage( u ) )
		m_iCurPage = u;   

	return 0L;
}

bool CDemoPropDlg::AddPage( CPrefSubDlg& dlg, const char *pCaption, CPrefSubDlg* pDlgParent )
{
	if( m_hWnd ) {
		// can't add once the window has been created
		ASSERT( 0 );
		return false;
	}

	PageStructC*	pPS = new PageStructC;
	pPS->pDlg = &dlg;
	pPS->id = dlg.GetID();
	pPS->csCaption = pCaption;
	pPS->pDlgParent = pDlgParent;

	m_pages.Add( pPS );

	return true;
}


bool CDemoPropDlg::ShowPage( CPrefSubDlg* pPage )
{
	// find that page
	for( int i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( i );
		ASSERT( pPS );
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg == pPage ) {
				ShowPage( i );
				m_iCurPage = i;
				return true;
			}
		}
	}
	
	return false;
}

bool CDemoPropDlg::ShowPage(int iPage)
{
	// turn off the current page
	if( (m_iCurPage >= 0) && (m_iCurPage < m_pages.GetSize()) )
	{
		PageStructC *pPS = (PageStructC *)m_pages.GetAt( m_iCurPage );
		ASSERT( pPS );
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg )
				if( ::IsWindow( pPS->pDlg->m_hWnd ) )
					pPS->pDlg->ShowWindow( SW_HIDE );
		}
		else
			return false;
	}

	// show the new one
	if ((iPage >= 0) && (iPage < m_pages.GetSize())) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( iPage );
		ASSERT( pPS );
		
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg ) {
				
				// update caption bar
				m_rStaticTitle.SetWindowText( pPS->csCaption );
				
				// if we haven't already, Create the dialog
				if( !::IsWindow( pPS->pDlg->m_hWnd ) )
					pPS->pDlg->Create( pPS->pDlg->GetID(), this );
				
				// move, show, focus
				if( ::IsWindow( pPS->pDlg->m_hWnd ) ) {
					pPS->pDlg->MoveWindow( m_frameRect.left, m_frameRect.top, m_frameRect.Width(), m_frameRect.Height() );
					pPS->pDlg->ShowWindow( SW_SHOW );
					pPS->pDlg->SetFocus();
				}
				
				// change the tree
				
				// find this in our map
				HTREEITEM hItem = FindHTREEItemForDlg( pPS->pDlg );
				if( hItem ) {
					// select it
					m_rPageTree.SelectItem( hItem );
				}

				return true;
			}
		}
	}

	return false;
}

int CDemoPropDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	return 0;
}

void CDemoPropDlg::OnCancel() 
{
	// tell all of the sub-dialogs "Cancel"
	for( int i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( i );
		ASSERT( pPS );
		
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg ) {
				if( ::IsWindow( pPS->pDlg->m_hWnd ) )
					pPS->pDlg->OnCancel();
			}
		}
	}
	

	CDialog::OnCancel();
}

void CDemoPropDlg::OnOK() 
{
	if( EndOK() )	
		CDialog::OnOK();
}


bool CDemoPropDlg::EndOK()
{
	bool bOK = true;
	
	CPrefSubDlg* pPage = NULL;
	
	// first, UpdateData...
	for( int i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( i );
		ASSERT( pPS );
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg ) {
				if( ::IsWindow( pPS->pDlg->m_hWnd ) ) {
					if( !pPS->pDlg->UpdateData( TRUE ) ) {
						bOK = false;
						pPage = pPS->pDlg;
						break;
					}
				}
			}
		}
	}
	
	// were there any UpdateData errors?
	if( (!bOK) && (pPage != NULL) ) {
		ShowPage( pPage );
		return false;
	}
	
	// tell all of the sub-dialogs "OK"
	for( i = 0; i < m_pages.GetSize(); i++ ) {
		PageStructC*	pPS = (PageStructC*)m_pages.GetAt( i );
		ASSERT( pPS );
		if( pPS ) {
			ASSERT( pPS->pDlg );
			if( pPS->pDlg ) {
				if( ::IsWindow( pPS->pDlg->m_hWnd ) )
					pPS->pDlg->OnOK();
			}
		}
	}
	
	return true;
}

void CDemoPropDlg::OnSelchangedPagetree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	if (pNMTreeView->itemNew.lParam ) {
		// find out which page was selected
		int iIdx = -1;
		for( int i = 0; i < m_pages.GetSize(); i++ ) {
			if( m_pages.GetAt( i )==(PageStructC*)pNMTreeView->itemNew.lParam ) {
				iIdx = i;
				break;
			}
		}
		
		// show that page
		if( (iIdx >= 0) && (iIdx < m_pages.GetSize()) ) {
			PageStructC*	pPS = (PageStructC*)m_pages.GetAt( iIdx );
			if( m_iCurPage != iIdx )
				PostMessage( WM_CHANGE_PAGE, iIdx );
		}
	}
	
	*pResult = 0;
}

void CDemoPropDlg::OnGetdispinfoPagetree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;

	// return the caption of the appropriate dialog
	if( pTVDispInfo->item.lParam ) {
		if( pTVDispInfo->item.mask & TVIF_TEXT ) {
			PageStructC*	pPS = (PageStructC*)pTVDispInfo->item.lParam;
			strcpy( pTVDispInfo->item.pszText, pPS->csCaption );
		}
	}
	
	*pResult = 0;
}

BOOL CDemoPropDlg::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, NULL, NULL, NULL);
	cs.style |= WS_CLIPCHILDREN;
	return TRUE;
}

BOOL CDemoPropDlg::PreTranslateMessage(MSG* pMsg) 
{
	ASSERT( pMsg != NULL );
	ASSERT_VALID( this );
	ASSERT( m_hWnd != NULL );

	// Don't let CDialog process the Escape key.
	if( (pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_ESCAPE) )
		return TRUE;

	if( CWnd::PreTranslateMessage( pMsg ) )
		return TRUE;

	// don't translate dialog messages when 
	// application is in help mode
	CFrameWnd* pFrameWnd = GetTopLevelFrame();
	if( pFrameWnd != NULL && pFrameWnd->m_bHelpMode )
		return FALSE;

	// ensure the dialog messages will not
	// eat frame accelerators
	pFrameWnd = GetParentFrame();
	while( pFrameWnd != NULL ) {
		if( pFrameWnd->PreTranslateMessage( pMsg ) )
			return TRUE;
		pFrameWnd = pFrameWnd->GetParentFrame();
	}

	return PreTranslateInput( pMsg );
}
