// GSDialog.cpp
//
// Copyright 1996 Diehl Graphsoft, Inc.

#include "stdafx.h"

#define _MFC_EXTERNAL_ 1

#include <QTML.h>
#include <fp.h>

#include "GSWinSDK.h"
#include "MiniCadCallbacks.h"


/////////////////////////////////////////////////////////////////////////////////////////
CWnd *GS_GetCWndParent(CallBackPtr cbp)
{
	AfxLockTempMaps();
	HWND hMainWnd = GS_GetMainHWND(cbp);
	return CWnd::FromHandle(hMainWnd);
}

void GS_ReleaseCWndParent(CallBackPtr /*cbp*/, CWnd *&parent)
{
	AfxUnlockTempMaps();
	parent = NULL;
}


///////////////////////////////////////////////////////////////////////////////
// THelpItem implementation

///////////////////////////////////////////////////////////////////////////////
TGSDialog::THelpItem::THelpItem()
{
	fControlID = fLabelID = fStringID = (UINT) -1;
	fLoaded = FALSE;
}

///////////////////////////////////////////////////////////////////////////////
TGSDialog::THelpItem::THelpItem(UINT nStringID, UINT nControlID, UINT nLabelID)
{
	fControlID = nControlID;
	fLabelID = nLabelID;
	fStringID = nStringID;
	fLoaded = FALSE;
}

///////////////////////////////////////////////////////////////////////////////
TGSDialog::THelpItem &TGSDialog::THelpItem::operator=(const THelpItem &a)
{
	ASSERT_VALID(this);

	fControlID = a.fControlID;
	fLabelID = a.fLabelID;
	fStringID = a.fStringID;
	fLoaded = a.fLoaded;
	fString = a.fString;
	return *this;
}

///////////////////////////////////////////////////////////////////////////////
BOOL TGSDialog::THelpItem::PointInRect(const CWnd *pParent, const CPoint &pt) const
{
	ASSERT_VALID(this);

	// Try control.
	CRect rTarget;
	CWnd *pTarget = pParent->GetDescendantWindow(fControlID);
	ASSERT(pTarget);
	if (pTarget) {
		CRect rTarget;
		pTarget->GetWindowRect(&rTarget);
		if (rTarget.PtInRect(pt))
			return TRUE;
	}

	// Try label control.
	if (fLabelID != -1) {
		pTarget = pParent->GetDescendantWindow(fLabelID);
		ASSERT(pTarget);
		if (pTarget) {
			pTarget->GetWindowRect(&rTarget);
			if (rTarget.PtInRect(pt))
				return TRUE;
		}
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
const CString &TGSDialog::THelpItem::GetString()
{
	if (!fLoaded) {
		VERIFY( fString.LoadString(fStringID) );
		fLoaded = TRUE;
	}
	return fString;
}


///////////////////////////////////////////////////////////////////////////////
// TGSDialog implementation

BEGIN_MESSAGE_MAP(TGSDialog, CDialog)
	//{{AFX_MSG_MAP(TGSDialog)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////////
TGSDialog::TGSDialog(CallBackPtr cbp, UINT nIDTemplate, CWnd *pParent)
	: CDialog(nIDTemplate, pParent)
{
	fCBP = cbp;
	fHelpControlID = (UINT) -1;
	fLastHelpIndex = -1;
	fUseHelp = FALSE;
}

///////////////////////////////////////////////////////////////////////////////
void TGSDialog::EnableHelp(UINT nControlID, UINT nDefaultHelpID)
{
	ASSERT_VALID(this);

	fUseHelp = TRUE;
	fHelpControlID = nControlID;
	fLastHelpIndex = -2;
	if (nDefaultHelpID != -1)
		fDefaultHelp.LoadString(nDefaultHelpID);
	fHelpItems.RemoveAll();
}

///////////////////////////////////////////////////////////////////////////////
void TGSDialog::PutDlgAngle(int nID, double_param angle)
{
	ASSERT_VALID(this);

	char sz[28];
	GS_AngleToCString(GetCBP(), angle, sz, 28);
	GetDlgItem(nID)->SetWindowText(sz);
}

///////////////////////////////////////////////////////////////////////////////
void TGSDialog::PutDlgCoord(int nID, const WorldCoord& c)
{
	ASSERT_VALID(this);

	char sz[28];
	GS_CoordToDimCString(GetCBP(), c, sz, 28);
	GetDlgItem(nID)->SetWindowText(sz);
}

///////////////////////////////////////////////////////////////////////////////
BOOL TGSDialog::GetDlgAngle(int nID, double_gs &angle)
{
	ASSERT_VALID(this);

	CString cs;
	GetDlgItem(nID)->GetWindowText(cs);
	
	if (cs.IsEmpty())
		angle = 0.0;
	else if (!GS_CStringToAngle(GetCBP(), cs, angle)) {
		MessageBeep(MB_ICONHAND);
		GetDlgItem(nID)->SetFocus();
		return FALSE;
	}
	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
BOOL TGSDialog::GetDlgCoord(int nID, WorldCoord& c)
{
	ASSERT_VALID(this);

	CString cs;
	GetDlgItem(nID)->GetWindowText(cs);

	if (cs.IsEmpty())
		c = 0;
	else if (!GS_DimCStringToCoord(GetCBP(), cs, c)) {
		MessageBeep(MB_ICONHAND);
		GetDlgItem(nID)->SetFocus();
		return FALSE;
	}
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
void TGSDialog::RegisterHelpItem(UINT nStringID, UINT nControlID, UINT nLabelID)
{
	ASSERT_VALID(this);

	THelpItem item(nStringID, nControlID, nLabelID);
	fHelpItems.Add(item);
}

///////////////////////////////////////////////////////////////////////////////
BOOL TGSDialog::DisplayHelpItem(const CPoint &point)
{
	// Search for an item under the point.
	for (int i=0, max = fHelpItems.GetSize(); i < max; ++i) {
		if (fHelpItems[i].PointInRect(this, point)) {
			if (i != fLastHelpIndex) {
				fHelpItems[i].Display(GetDlgItem(fHelpControlID));
				fLastHelpIndex = i;
			}
			return TRUE;
		}
	}
	// No item found.
	if (fLastHelpIndex != -1) {
		GetDlgItem(fHelpControlID)->SetWindowText(fDefaultHelp);
		fLastHelpIndex = -1;
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
BOOL TGSDialog::PreTranslateMessage(MSG *pMsg) 
{
	if (fUseHelp && pMsg->message == WM_MOUSEMOVE)
		DisplayHelpItem(pMsg->pt);
	return CDialog::PreTranslateMessage(pMsg);
}

//---------------------------------------------------------------------------------------
int TGSDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	const int result = CDialog::OnCreate(lpCreateStruct);
	ASSERT(this->GetSafeHwnd() != NULL);
	ASSERT(this->GetParent() != NULL);
	GS_EnterMoveableWindow(GetCBP(), this->GetSafeHwnd());
	return result;
}

//---------------------------------------------------------------------------------------
void TGSDialog::OnDestroy()
{
	ASSERT(this->GetSafeHwnd() != NULL);
	GS_ExitMoveableWindow(GetCBP(), this->GetSafeHwnd());
	CDialog::OnDestroy();
}
