/***************************************************************************
**
**    $Header:   D:/EP196/SRC/LOG/SRCDLL/SRCFROM.CPP   1.0   15 Aug 1997 14:03:40   ZJRD  $
**
**    $Log:   D:/EP196/SRC/LOG/SRCDLL/SRCFROM.CPP  $
** 
**    Rev 1.0   15 Aug 1997 14:03:40   ZJRD
** Initial revision.
** 
**    Rev 1.1.7.0   19 Jun 1997 14:49:14   ZJRD
** 1.0c
** 
****************************************************************************/

// srcfrom.cpp : implementation file
//

#include "stdafx.h"
#include "srcdll.h"
#include "srcgbl.h"
#include "srcaddr.h"
#include "srcfrom.h"

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


/////////////////////////////////////////////////////////////////////////////
// CSourceBrowseFromDlg dialog

CSourceBrowseFromDlg::CSourceBrowseFromDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSourceBrowseFromDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSourceBrowseFromDlg)
	m_bPC = FALSE;
	m_strAddr = "";
	//}}AFX_DATA_INIT
}

void CSourceBrowseFromDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSourceBrowseFromDlg)
	DDX_Control(pDX, IDC_LIST_SRC_BROWSEFROM_FUNCTION, m_lstFunction);
	DDX_Control(pDX, IDC_LIST_SRC_BROWSEFROM_MODULE, m_lstModule);
	DDX_Control(pDX, IDC_CHECK_SRC_BROWSEFROM_PC, m_btnPC);
	DDX_Check(pDX, IDC_CHECK_SRC_BROWSEFROM_PC, m_bPC);
	DDX_Control(pDX, IDC_COMBO_SRC_BROWSEFROM_LOCATION, m_comboAddr);
	DDX_CBString(pDX, IDC_COMBO_SRC_BROWSEFROM_LOCATION, m_strAddr);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSourceBrowseFromDlg, CDialog)
	//{{AFX_MSG_MAP(CSourceBrowseFromDlg)
	ON_BN_CLICKED(IDC_CHECK_SRC_BROWSEFROM_PC, OnCheckSrcBrowsefromPc)
	ON_LBN_SELCHANGE(IDC_LIST_SRC_BROWSEFROM_MODULE, OnSelchangeListSrcBrowsefromModule)
	ON_LBN_DBLCLK(IDC_LIST_SRC_BROWSEFROM_FUNCTION, OnDblclkListSrcBrowsefromFunction)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CSourceBrowseFromDlg common routines

BOOL CSourceBrowseFromDlg::CheckSyntax()
{
	// Is Addr valid?
	CSourceAddr Addr;
	return ( ::SrcTextToAddr(m_strAddr, Addr) );
}

void CSourceBrowseFromDlg::EnableControl()
{
	// Not PC
	BOOL bEnable = m_bPC ? FALSE : TRUE;
	m_comboAddr.EnableWindow(bEnable);
	m_lstModule.EnableWindow(bEnable);
	m_lstFunction.EnableWindow(bEnable);
	
	// Module & Function list
	if ( bEnable && !::SrcIsLoadedSymbol() ) {
		m_lstModule.EnableWindow(FALSE);
		m_lstFunction.EnableWindow(FALSE);
	}
	
	// OK button
//	CString strAddr(m_strAddr);
//	strAddr.TrimLeft();
//	strAddr.TrimRight();
//	bEnable = strAddr.IsEmpty() ? FALSE : TRUE;
//	m_btnOK.EnableWindow(bEnable);
}

void CSourceBrowseFromDlg::GetModuleInfo()
{
	// If symbol is not loaded, cancel
	if ( !::SrcIsLoadedSymbol() ) {
		return;
	}
	
	// Get module info from Symbol server
	CStringList* pModuleList = new CStringList;
	::SrcGetModuleList(pModuleList);
	
	// Add to the list box
	m_lstModule.ResetContent();
	POSITION pos = pModuleList->GetHeadPosition();
	int nLen(0);
	while ( pos ) {
		CString strModule = pModuleList->GetNext(pos);
		nLen = max(nLen, strModule.GetLength());
		m_lstModule.AddString(strModule);
	}
	m_lstModule.SetHorizontalExtent(8*(nLen+1));

	if ( m_lstModule.GetCount() > 0 ) {
		m_lstModule.SetCurSel(0);
		GetFunctionInfo();
	}

	// Free module info list
	pModuleList->RemoveAll();
	delete pModuleList;
}

void CSourceBrowseFromDlg::GetFunctionInfo()
{
	// If symbol is not loaded, cancel
	if ( !::SrcIsLoadedSymbol() ) {
		return;
	}
	
	// Get current selected module
	CString strModule;
	m_lstModule.GetText(m_lstModule.GetCurSel(), strModule);

	// Get function info from Symbol server
	CStringList* pFunctionList = new CStringList;
	::SrcGetFunctionList(strModule, pFunctionList);
	
	// Add to the list box
	m_lstFunction.ResetContent();
	POSITION pos = pFunctionList->GetHeadPosition();
	int nLen(0);
	while ( pos ) {
		CString strFunction = pFunctionList->GetNext(pos);
		nLen = max(nLen, strFunction.GetLength());
		m_lstFunction.AddString(strFunction);
	}
	m_lstFunction.SetHorizontalExtent(8*(nLen+1));

	if ( m_lstFunction.GetCount() > 0 ) {
		m_lstFunction.SetCurSel(0);
	}

	// Free function info list
	pFunctionList->RemoveAll();
	delete pFunctionList;
}

void CSourceBrowseFromDlg::GetAddrInfo()
{
	// Get previous input
	m_comboAddr.ResetContent();
	POSITION pos = ::pSourceFromList->GetHeadPosition();
	while ( pos ) {
		m_comboAddr.AddString(::pSourceFromList->GetNext(pos));
	}
}

void CSourceBrowseFromDlg::SetAddrText()
{
	// Get Module & Function
	CString strModule;
	if ( m_lstModule.GetCount() >= 1 ) {
		m_lstModule.GetText(m_lstModule.GetCurSel(), strModule);
	}
	
	CString strFunction;
	if ( m_lstFunction.GetCount() >= 1 ) {
		m_lstFunction.GetText(m_lstFunction.GetCurSel(), strFunction);
	}
		
	// Set to Address if OK
	CString strAddr;
	if ( !strModule.IsEmpty() ) {
	 	strAddr += CString('#') + strModule;
	 	if ( !strFunction.IsEmpty() ) {
	 		strAddr += CString('#') + strFunction;
	 	}
		m_strAddr = strAddr;
	}
}

void CSourceBrowseFromDlg::SetFromList()
{
	// Trim leading space
	m_strAddr.TrimLeft();
	m_strAddr.TrimRight();

	// Without same string in the list
	POSITION pos = ::pSourceFromList->GetHeadPosition();
	while ( pos ) {
		POSITION posOld(pos);
		if ( m_strAddr == ::pSourceFromList->GetNext(pos) ) {
			::pSourceFromList->RemoveAt(posOld);
			break;
		}
	}

	// Add to head
	::pSourceFromList->AddHead(m_strAddr);
}


/////////////////////////////////////////////////////////////////////////////
// CSourceBrowseFromDlg message handlers

BOOL CSourceBrowseFromDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
	// Center window
	CenterWindow();
	
	// Set list font
    HFONT hFont = (HFONT)::GetStockObject(ANSI_FIXED_FONT);
    CFont font;
	m_lstModule.SetFont(font.FromHandle(hFont));
	m_lstFunction.SetFont(font.FromHandle(hFont));

	// Get Module info
	GetModuleInfo();

	// Get Addr info
	GetAddrInfo();
	
	// Set Addr text
	SetAddrText();

	// Enable controls
	EnableControl();
	
	UpdateData(FALSE);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSourceBrowseFromDlg::OnCheckSrcBrowsefromPc()
{
	// TODO: Add your control notification handler code here

	// Enable controls
	UpdateData();
		
	EnableControl();
}

void CSourceBrowseFromDlg::OnSelchangeListSrcBrowsefromModule()
{
	// TODO: Add your control notification handler code here

	// Update Function list-box
	UpdateData();

	GetFunctionInfo();
}

void CSourceBrowseFromDlg::OnDblclkListSrcBrowsefromFunction()
{
	// TODO: Add your control notification handler code here

	// Update Address edit-box
	UpdateData();

	SetAddrText();

	EnableControl();

	UpdateData(FALSE);
}

void CSourceBrowseFromDlg::OnOK()
{
	// TODO: Add extra validation here

	// Set global list
	UpdateData();

	if ( !m_bPC ) {
		if ( CheckSyntax() ) {
			SetFromList();
		}
		else {
			::SrcDisplayErrorMessage(::errBrowseFrom);
			return;
		}
	}

	CDialog::OnOK();
}
