//	CDialog.c

#include "IC_Errors.h"
#include "Utils.h"
#include "Carbon68kGlue.h"
#include "string.h"
#include "CDialog.h"

CDialog		*GetCDialog(WindowRef windowRef)
{
	CWindow		*window	= GetCWindow(windowRef);

	if (
		window->i_windowType < ADFS_Window_DIALOG
		|| window->i_windowType >= ADFS_Window_DOCUMENT
	) {
		window = NULL;
	}

	return (CDialog *)window;
}
/********************************************/
Boolean		CDialog::IDialog(
	ADFS_WindowType windowType, 
	short			resourceID)
{
	Boolean		success = TRUE;
	
	i_dialog_UI_UPP		= NULL;
	i_macPort.dialog	= GetNewDialog(resourceID, NULL, (WindowPtr)-1);
	success				= i_macPort.dialog != NULL;
	
	if (!success) {
		ReportError(IC_Err_COULDNT_LOAD_DLG);
	}

	if (success) success = _inherited::IWindow(windowType);
	
	if (success) {
		i_dialog_UI_UPP	= NewUserItemUPP(CB_S_DialogItemStandardDrawProc);
		success = i_dialog_UI_UPP != NULL;

		if (!success) {
			ReportErrorStr(-1, "Error: couldn't allocate draw UPP");
		}
	}
	
	if (success) {
		if (
			windowType >= ADFS_Window_MODAL_DIALOG
			&& windowType <= ADFS_Window_MODAL_DIALOG
		) {
			success = SetWindowModality(
				GetWindowRef(), kWindowModalityAppModal, NULL) == noErr;
		}
	}
	
	return success;
}

void		CDialog::Dispose(void)
{
	if (i_dialog_UI_UPP) {
		DisposeUserItemUPP(i_dialog_UI_UPP);
	}

	_inherited::Dispose();
}

/*********************************************/
void		CDialog::SetDlgItemUseStdDraw(short dItem)
{
    DialogItemType		itemType;
    Handle				item;
    Rect				theRect;
	
	GetDialogItem(GetDialogRef(), dItem, 
		&itemType, &item, &theRect);
	
	SetDialogItem(GetDialogRef(), dItem, 
		itemType, (Handle)i_dialog_UI_UPP, &theRect);
}

void		CDialog::SetDlgItemUseStdDrawGroup(short startItem, short endItem)
{
	short	curItem;
	
	for (curItem = startItem; curItem <= endItem; curItem++) {
		SetDlgItemUseStdDraw(curItem);
	}
}

//	static
pascal void	CDialog::CB_S_DialogItemStandardDrawProc(
	DialogRef		theDialog, 
	DialogItemIndex	itemNo)
{
	CDialog		*dialogP = GetCDialog(GetDialogWindow(theDialog));
	
	if (dialogP) {
	    DialogItemType		itemType;
	    Handle				item;
	    Rect				theRect;
		
		GetDialogItem(theDialog, itemNo, &itemType, &item, &theRect);

		dialogP->DialogItemStandardDrawProc(itemNo, &theRect);
	}
}

void		CDialog::DialogItemStandardDrawProc(
	DialogItemIndex	itemNo, 
	Rect			*itemRectP)
{
	//	override me
}

/*****************************************/
DialogRef	CDialog::GetDialogRef(void)
{
	return i_macPort.dialog;
}

WindowRef	CDialog::GetWindowRef(void)
{
	return GetDialogWindow(i_macPort.dialog);
}

GrafPtr		CDialog::GetGrafPtr(void)
{
	return GetDialogPort(i_macPort.dialog);
}

/*****************************************/
void		CDialog::InvalDialogItem(short dItem)
{
	DialogRef			dlogP = GetDialogRef();
	GrafPtr				savePort;
    DialogItemType		itemType;
    Handle				item;
    Rect				theRect;
    	
	GetPort(&savePort);
	SetPort(GetGrafPtr());
	GetDialogItem(dlogP, dItem, &itemType, &item, &theRect);
	InvalWindowRect(GetWindowRef(), &theRect);
	SetPort(savePort);
}

ControlRef	CDialog::GetDlogItemControl(short dlgItem)
{
    DialogItemType		itemType;
    Handle				itemH;
    Rect				theRect;
	ControlRef			controlH = NULL;

	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &itemH, &theRect);
	
	if ((itemType & kControlDialogItem) == kControlDialogItem) {
		#ifdef OLD68K
			controlH = (ControlRef)itemH;
		#else
			if (GetSystemVers() >= 0x0800) {
				GetDialogItemAsControl(GetDialogRef(), dlgItem, &controlH);
			} else {
				controlH = (ControlRef)itemH;
			}
		#endif
	}
	
	return controlH;
}

void		CDialog::HideDlogItem(short dItem)
{
	ControlRef	controlH = GetDlogItemControl(dItem);

	HideDialogItem(GetDialogRef(), dItem);
	
	if (controlH) {
		HideControl(controlH);
	}
}

void		CDialog::ShowDlogItem(short dItem)
{
	ControlRef	controlH = GetDlogItemControl(dItem);

	ShowDialogItem(GetDialogRef(), dItem);
	
	if (controlH) {
		ShowControl(controlH);
	}
}

void		CDialog::HideDialogItemGroup(short firstItem, short lastItem)
{
	short		loop;
	
	for (loop = firstItem; loop <= lastItem; loop++) {
		HideDlogItem(loop);
	}
}

void		CDialog::ShowDialogItemGroup(short firstItem, short lastItem)
{
	short		loop;
	
	for (loop = firstItem; loop <= lastItem; loop++) {
		ShowDlogItem(loop);
	}
}

void	SetControlRect(ControlHandle theControl, Rect *theRect)
{
	HideControl(theControl);

	MoveControl(theControl, theRect->left, theRect->top);

	SizeControl(theControl, 
		theRect->right - theRect->left, 
		theRect->bottom - theRect->top);
		
	ShowControl(theControl);
}

void		CDialog::SetDlogItemRect(short dlgItem, Rect *theRect)
{
    DialogItemType		itemType;
    Handle				item;
    Rect				oldRect;
	ControlRef			controlH = GetDlogItemControl(dlgItem);

	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &item, &oldRect);
	SetDialogItem(GetDialogRef(), dlgItem, itemType, item, theRect);
	
	if (controlH) {
		SetControlRect(controlH, theRect);
	}
}

void		CDialog::GetDlogItemRect(short dlgItem, Rect *theRect)
{
    DialogItemType		itemType;
    Handle				item;

	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &item, theRect);
}

void		CDialog::OffsetDlogItem(short dlgItem, short hOffset, short vOffset)
{
	Rect	theRect;
		
	GetDlogItemRect(dlgItem, &theRect);
	OffsetRect(&theRect, hOffset, vOffset);
	SetDlogItemRect(dlgItem, &theRect);
}

extern	EventRecord	gEvent;

void		CDialog::Update(void)
{
	if (IsDialogEvent(&gEvent)) {
		DialogPtr	theDialog;
		short		itemHit;

		DialogSelect(&gEvent, &theDialog, &itemHit);
	}
	
	_inherited::Update();
}

void	CDialog::Idle(void)
{
	//	idle gets called for all windows regardless of
	//	whether it is specifically dialog related.  so
	//	let's make sure it's dialog related
	if (IsDialogEvent(&gEvent)) {
		DialogPtr	theDialog;
		short		itemHit;

		DialogSelect(&gEvent, &theDialog, &itemHit);
	}

	_inherited::Idle();
}

Rect		CDialog::GetBestRect(short dlgItem)
{
	Rect			theRect;

	#ifdef OLD68K
		GetDlogItemRect(dlgItem, &theRect);
	#else
		short			baseLineS;
		ControlRef		controlH = GetDlogItemControl(dlgItem);

		(void)GetBestControlRect(controlH, &theRect, &baseLineS);
	#endif
	
	return theRect;
}

void		CDialog::SetDlogItemText(short dlgItem, char *text)
{
    DialogItemType		itemType;
    Handle				itemH;
	Rect 				theRect;
	unsigned char		textStr[256];
	
	CopyCStringToPascal(text, textStr);
	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &itemH, &theRect);
	itemType &= ~kItemDisableBit;
	
	if (
		itemType == kStaticTextDialogItem
		|| itemType == kEditTextDialogItem
	) {
		SetDialogItemText(itemH, textStr);
	} else if ((itemType & kControlDialogItem) != 0) {
		SetControlTitle(GetDlogItemControl(dlgItem), textStr);
	}
}

void		CDialog::GetDlogItemText(short dlgItem, char *text)
{
    DialogItemType		itemType;
    Handle				itemH;
	Rect 				theRect;
	
	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &itemH, &theRect);
	itemType	&= ~kItemDisableBit;
	text[0]		= 0;
	
	if (
		itemType == kStaticTextDialogItem
		|| itemType == kEditTextDialogItem
	) {
		GetDialogItemText(itemH, (unsigned char *)text);
	} else if ((itemType & kControlDialogItem) != 0) {
		GetControlTitle(GetDlogItemControl(dlgItem), (unsigned char *)text);
	}

	CopyPascalStringToC((unsigned char *)text, text);
}

void		CDialog::SimulateClick(short dlgItem)
{
    DialogItemType		itemType;
    Handle				itemH;
	Rect 				theRect;
	
	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &itemH, &theRect);
	
	if ((itemType & kButtonDialogItem) != 0) {
		ControlRef		controlH = GetDlogItemControl(dlgItem);
		
		HiliteControl(controlH, kControlButtonPart);
		Flush();
		WaitNTicks(10);
		HiliteControl(controlH, kControlNoPart);
	}
}

TEHandle	CDialog::GetDlogEditTextTE(short dlgItem)
{
	SelectDlogItem(dlgItem);
	return GetDialogTextEditHandle(GetDialogRef());
}

void		CDialog::SelectDlogItem(short dlgItem)
{
    DialogItemType		itemType;
    Handle				itemH;
	Rect 				theRect;
	
	GetDialogItem(GetDialogRef(), dlgItem, &itemType, &itemH, &theRect);
	
	itemType &= ~kItemDisableBit;
	
	if (
		itemType == kEditTextDialogItem
	) {
		SelectDialogItemText(GetDialogRef(), dlgItem, 0, 32767);
	} else {
		ASSERT(FALSE);
	}
}

short		CDialog::GetDlogTextRestore(TERestoreRec *restoreRec)
{
	restoreRec->teH		= GetDialogTextEditHandle(GetDialogRef());
	restoreRec->itemHit = GetDialogKeyboardFocusItem(GetDialogRef());
	
	GetDlogItemText(restoreRec->itemHit, restoreRec->text);
	TEGetSelect(restoreRec->teH, &restoreRec->selStart, &restoreRec->selEnd);
	
	return restoreRec->itemHit;
}

void		CDialog::RestoreDlogText(TERestoreRec *restoreRec)
{
	SetDlogItemText(
		restoreRec->itemHit, restoreRec->text);

	SelectDialogItemText(
		GetDialogRef(), 
		restoreRec->itemHit, 
		restoreRec->selStart, 
		restoreRec->selEnd);
}

void		CDialog::ValueConvert(
	DGI_ValueConvertType	convertType, 
	short					dlgItem)
{
	//	override me
}

short		GetItemTableIndex(DGI_ItemRec *itemTable, short dlogItem, short maxItems)
{
	short		tableIndex;
	
	for (tableIndex = 0; tableIndex < maxItems; tableIndex++) {
		if (itemTable[tableIndex].dlogItem == dlogItem) {
			break;
		}
	}
	
	ASSERT(tableIndex < maxItems);
	
	return tableIndex;
}

static		short	s_modalLevelS = 0;

Boolean		IsModalUp(void)
{
	return s_modalLevelS != 0;
}

void		SetModalUp(Boolean modalUpB)
{
	if (modalUpB) {
		s_modalLevelS++;
	} else {
		if (s_modalLevelS == 0) {
			ReportErrorStr(-1, "Modal Underflow");
		} else {
			s_modalLevelS--;
		}
	}
}

