//	CDialogGetInfo.c

#ifndef __GNUC__
	#include "Controls.h"
#endif

#include "CAppearance.h"
#include "Carbon68kGlue.h"
#include "A2Pix_AE.h"
#include "CFile.h"
#include "CDisk.h"
#include "IC_Errors.h"
#include "ADFS_Menus.h"
#include "ADFS_Prefs.h"

#include "CDialogGetInfo.h"

extern	Gen_AccessBits		Gen_kAccess_LOCKED;
extern	Boolean				g_isIconView;
CDialogGetInfo				*gGetInfoP = NULL;

CDialogGetInfo		*ShowGetInfo(CEntry *entryP, Boolean showPreviewB)
{
	if (!gGetInfoP) {
		gGetInfoP = new CDialogGetInfo;
		
		if (gGetInfoP) {
			if (!gGetInfoP->IGetInfo(entryP, showPreviewB)) {
				gGetInfoP->Dispose();
				gGetInfoP = NULL;
			}
		}
	} else {
		gGetInfoP->SetGetInfoEntry(entryP, showPreviewB);
		SelectWindow(gGetInfoP->GetWindowRef());
	}

	return gGetInfoP;
}

void	HideGetInfo(void)
{
	if (gGetInfoP) {
		gGetInfoP->Dispose();
	}
}

CDialogGetInfo		*GetGetInfo(void)
{
	return gGetInfoP;
}
/**************************************************************************/

Boolean		CDialogGetInfo::IGetInfo(CEntry *entryP, Boolean showPreviewB)
{
	OSErr				err = noErr;
	short				itemIndexS;
	
	//	get it hidden, then show
	if (!_inherited::IDialog(ADFS_Window_MDLG_GET_INFO, 201)) {
		err = IC_Err_COULDNT_LOAD_DLG;
	}

	if (!err) {
		GetSmallFontRec(&i_fontRec);
		i_fontRec.fontSize	= 10;
		i_entryP			= NULL;
		i_showPreviewB		= FALSE;
		i_previewRec.type	= ADFS_Preview_NONE;
		ClearPreviewRec();
		
		//	verify the number of items
		itemIndexS = CountDITL(GetDialogRef());

		if (itemIndexS != (ADFS_GetInfo_NUMTYPES - 1)) {
			err = IC_Err_WRONG_NUM_DLG_ITEMS;
		}
	}

	if (!err) {
		Rect			theRect;
		TEHandle		teH;
		TextStyle		newStyle;
		
		//	set up the custom user procs		
		SetDlgItemUseStdDrawGroup(ADFS_GetInfo_USER_ICON, ADFS_GetInfo_STAT_TYPE);
		SetDlgItemUseStdDrawGroup(ADFS_GetInfo_POPUP_DOS_TYPE, ADFS_GetInfo_STAT_AUXTYPE);
		SetDlgItemUseStdDraw(ADFS_GetInfo_SC_DESTROY);
		SetDlgItemUseStdDraw(ADFS_GetInfo_SC_RENAME);
		SetDlgItemUseStdDraw(ADFS_GetInfo_SC_WRITE);
		SetDlgItemUseStdDraw(ADFS_GetInfo_SC_BACKUP);
		SetDlgItemUseStdDrawGroup(ADFS_GetInfo_SC_READ, ADFS_GetInfo_USER_ERASE_LOCKED);
		SetDlgItemUseStdDraw(ADFS_GetInfo_SC_LOCKED);
		SetDlgItemUseStdDrawGroup(ADFS_GetInfo_USER_GROUP_SHOW, ADFS_GetInfo_USER_PREVIEW);

		//	set up the checkbox userprocs
		for (itemIndexS = 0; itemIndexS < ADFS_GetInfoCheck_NUMTYPES; itemIndexS++) {
			i_checked[itemIndexS] = FALSE;
			SetDlgItemUseStdDraw(GI_Check2Item(itemIndexS));
		}
		
		HideDlogItem(ADFS_GetInfo_USER_PREVIEW);
		
		i_showPop = GetNewControl(kGetInfoPopCNTL_ID, GetWindowRef());
		SetControlValue(i_showPop, kGetInfoMenuItem_GENERAL);
		GetDlogItemRect(ADFS_GetInfo_POP_SHOW_DRAW, &theRect);
		MoveControl(i_showPop, theRect.left, theRect.top);

		{
			short	pop;
			
			for (pop = 0; pop < 4; pop++) {
				i_typePops[pop] = GetNewControl(pop + kGetInfoTypeCNTL_ID, GetWindowRef());
				GetDlogItemRect(pop + ADFS_GetInfo_POPUP_DOS_TYPE, &theRect);
				MoveControl(i_typePops[pop], theRect.left, theRect.top);
			}
		}
		
		i_curPopType = ADFS_GetInfo_POPUP_DOS_TYPE;
		HideDlogItem(ADFS_GetInfo_POPUP_PRO_TYPE);
		HideDlogItem(ADFS_GetInfo_POPUP_PAS_TYPE);
		HideDlogItem(ADFS_GetInfo_POPUP_CPM_TYPE);

		newStyle.tsFont = i_fontRec.fontID;
		newStyle.tsSize = i_fontRec.fontSize;

		teH = GetDlogEditTextTE(ADFS_GetInfo_EDIT_TYPE);
		TESetFont(doFont | doSize, &newStyle, FALSE, teH);

		teH = GetDlogEditTextTE(ADFS_GetInfo_EDIT_AUXTYPE);
		TESetFont(doFont | doSize, &newStyle, FALSE, teH);

		SetGetInfoEntry(entryP, showPreviewB);
		SelectDlogItem(ADFS_GetInfo_EDIT_TYPE);

/*		SetControlValue(GetDlogItemControl(i_curPopType), 
			entryP->i_cDisk.gen->FileTypeToMenuItem(
				entryP->GetFileType(), entryP->GetAuxType()));
*/
		{
			Rect	aboutR = (**gPrefsH).windA[PREF_Wind_INFO];
			
			if (!EmptyRect(&aboutR)) {
				MoveWindow(
					GetWindowRef(),
					aboutR.left, aboutR.top, FALSE);
			}
		}

		//	show and do the dialog
		ShowWindow(GetWindowRef());
	}
	
	return err == noErr;
}

void		CDialogGetInfo::Dispose(void)
{
	switch (i_previewRec.type) {
	
		case ADFS_Preview_TEXT: {
			TrackDisposeHandle(i_previewRec.u.textH);
			break;
		}
	
		case ADFS_Preview_PIC: {
			i_previewRec.u.offsP->Dispose();
			break;
		}
	}

	gGetInfoP = NULL;
	_inherited::Dispose();
}

/*********************************************************/
void	CDialogGetInfo::Move(EventRecord *event)
{
	_inherited::Move(event);
	(**gPrefsH).windA[PREF_Wind_INFO] = GetWindowRect(WindowRect_ALL_GLOBAL);
	SavePrefs();
}

void		CDialogGetInfo::SetGetInfoTypeAndAux(void)
{
	short				fileType;

	fileType = i_entryP->GetFileType();
	sprintf(i_fileTypeStrA, "0x%.2hX", (int)fileType);
	SetDlogItemText(ADFS_GetInfo_EDIT_TYPE, i_fileTypeStrA);
	
	fileType = i_entryP->GetAuxType();
	sprintf(i_auxTypeStrA, "0x%.4hX", (int)fileType);
	SetDlogItemText(ADFS_GetInfo_EDIT_AUXTYPE, i_auxTypeStrA);

	InvalDialogItem(ADFS_GetInfo_USER_ICON);
	InvalDialogItem(ADFS_GetInfo_VERB_KIND);
}

void		CDialogGetInfo::SetLockBits(void)
{
	Gen_AccessBits		access = Gen_kAccess_LOCKED;

	i_entryP->GetAccessBits(&access);

	i_checked[ADFS_GetInfoCheck_DESTROY]	= access.destroyEnable;
	i_checked[ADFS_GetInfoCheck_RENAME]		= access.renameEnable;
	i_checked[ADFS_GetInfoCheck_WRITE]		= access.writeEnable;
	i_checked[ADFS_GetInfoCheck_READ]		= access.readEnable;
	i_checked[ADFS_GetInfoCheck_BACKUP]		= access.backup;
	i_checked[ADFS_GetInfoCheck_LOCK]		= !access.destroyEnable && !access.renameEnable && !access.writeEnable;

	InvalDialogItem(ADFS_GetInfo_USER_ICON);
	InvalDialogItem(ADFS_GetInfo_UC_LOCKED);
	InvalDialogItem(ADFS_GetInfo_UC_DESTROY);
	InvalDialogItem(ADFS_GetInfo_UC_RENAME);
	InvalDialogItem(ADFS_GetInfo_UC_READ);
	InvalDialogItem(ADFS_GetInfo_UC_WRITE);
	InvalDialogItem(ADFS_GetInfo_UC_BACKUP);
}

void		CDialogGetInfo::ClearPreviewRec(void)
{
	switch (i_previewRec.type) {
	
		case ADFS_Preview_TEXT: {
			TrackDisposeHandle(i_previewRec.u.textH);
			break;
		}
	
		case ADFS_Preview_PIC: {
			i_previewRec.u.offsP->Dispose();
			break;
		}
	}
	
	structclr(i_previewRec);
}

void		CDialogGetInfo::SetGetInfoEntry(CEntry *entryP, Boolean showPreviewB)
{
	if (entryP == NULL) {
		HideGetInfo();
	} else {
		short			popType;
		char			buf1[32], buf2[32];
		
		ClearPreviewRec();

		i_entryP			= entryP;
		i_entryP->i_badPicB = FALSE;
		
		sprintf(buf1, "%s info", i_entryP->GetName(buf2));
		SetTitle(buf1);

		popType = i_entryP->i_cDisk.gen->i_imageRec->osType - FSType_DOS + ADFS_GetInfo_POPUP_DOS_TYPE;
		
		if (popType > ADFS_GetInfo_POPUP_CPM_TYPE) {
			popType = ADFS_GetInfo_POPUP_CPM_TYPE;
			ReportErrorStr(-1, "Strange OS");
		}
		
		if (popType != i_curPopType) {
			HideDlogItem(i_curPopType);
			i_curPopType = popType;
			ShowDlogItem(i_curPopType);
		}
		
		SetGetInfoTypeAndAux();
		SetLockBits();

		if (i_showPreviewB != showPreviewB) {
			i_showPreviewB = showPreviewB;
			SwapShowInfo();
		}
		
		InvalWindow(WindowRect_ALL);
	}
}

void		CDialogGetInfo::SwapShowInfo(void)
{
	SetControlValue(GetDlogItemControl(ADFS_GetInfo_POP_SHOW_DRAW), 1 + i_showPreviewB);

	if (i_showPreviewB) {
		HideDialogItemGroup(ADFS_GetInfo_FIRST_GEN_GROUP, ADFS_GetInfo_LAST_GEN_GROUP);
		ShowDialogItemGroup(ADFS_GetInfo_FIRST_PREVIEW_GROUP, ADFS_GetInfo_LAST_PREVIEW_GROUP);
	} else {
		HideDialogItemGroup(ADFS_GetInfo_FIRST_PREVIEW_GROUP, ADFS_GetInfo_LAST_PREVIEW_GROUP);
		ShowDialogItemGroup(ADFS_GetInfo_FIRST_GEN_GROUP, ADFS_GetInfo_LAST_GEN_GROUP);
	}
}

short	TrackPopupControl(ControlRef theControl, Point thePoint, CEntry *entryP);
short	TrackPopupControl(ControlRef theControl, Point thePoint, CEntry *entryP)
{
	short			newValue		= 0;
	short			menuID			= GetControlPopupMenuID(theControl);
	GrafPtr			controlPortP	= (GrafPtr)GetWindowPort(GetControlOwner(theControl));
	Boolean			isTypeMenuB		= menuID >= 206 && menuID <= 209;
	MenuRef			theMenu;
	short			curValue;
	short			maxValue;
	ulong			newCommand;
	Rect			controlRect;
	Str255			controlTitle;
	short			strWidthS;
	ADFS_FontRec	saveFontRec, sysFontRec;
	
	if (isTypeMenuB) {
		theMenu		= entryP->i_cDisk.gen->GetFileTypeMenu();
		curValue	= entryP->i_cDisk.gen->FileTypeToMenuItem(
			entryP->GetFileType(), entryP->GetAuxType());
		maxValue	= CountMenuItems(theMenu);
	} else {
		theMenu		= FindMenu(menuID);
		curValue	= GetControlValue(theControl);
		maxValue	= GetControlMaximum(theControl);
	}

	GetControlBounds(theControl, &controlRect);
	LocalRectToGlobal(controlPortP, &controlRect);
	OffsetRect(&controlRect, 1, -1);
	
	GetControlTitle(theControl, controlTitle);

	GetCurFontRec(&saveFontRec);
	GetSysFontRec(&sysFontRec);
	SetFontRec(&sysFontRec);
	strWidthS = StringWidth(controlTitle);
	SetFontRec(&saveFontRec);

	if (strWidthS) {
		controlRect.left += strWidthS + 10;
	}
	
	CheckMenuGroup(theMenu, 1, maxValue, curValue);
	
	HiliteControl(theControl, 10);
	InsertMenu(theMenu, hierMenu);
	newCommand = PopUpMenuSelect(theMenu, controlRect.top, controlRect.left, curValue);
	DeleteMenu(menuID);
	HiliteControl(theControl, 0);
	
	if (newCommand) {
		newValue = CommandItem(newCommand);
		
		if (!isTypeMenuB) {
			SetControlValue(theControl, newValue);
		}
	}
	
	return newValue;
}

void		CDialogGetInfo::DoClick(EventRecord *theEvent)
{
	if (FrontWindow() != GetWindowRef()) {
		_inherited::DoClick(theEvent);
	} else {
		DialogRef		theDialog;
		short			itemHit;
		
		SetDialogFont();
		
		DialogSelect(theEvent, &theDialog, &itemHit);
		GlobalToLocal(&theEvent->where);

		switch (itemHit) {

			case ADFS_GetInfo_POPUP_DOS_TYPE: 
			case ADFS_GetInfo_POPUP_PRO_TYPE: 
			case ADFS_GetInfo_POPUP_PAS_TYPE: 
			case ADFS_GetInfo_POPUP_CPM_TYPE:
			case ADFS_GetInfo_POP_SHOW_HIT: {
				short	newItem;
				
				TextFont(FMGetFontFamilyFromName("\pCharcoal"));
				TextSize(12);
				
				newItem = TrackPopupControl(
					GetDlogItemControl(itemHit), 
					theEvent->where, i_entryP);
				
				if (newItem) {
					if (itemHit == ADFS_GetInfo_POP_SHOW_HIT) {
						if (i_showPreviewB != newItem - 1) {
							i_showPreviewB = newItem - 1;
							SwapShowInfo();
						}
					} else {
						short	fileType;
						ushort	auxType = i_entryP->GetAuxType();
						CDisk	*thiz	= i_entryP->i_cDisk.gen;
						
						fileType = thiz->MenuItemToFileType(
							newItem, &auxType);
						
						if (i_entryP->i_type == FSObject_FILE) {
							CFile	*cFileP = (CFile *)i_entryP;
							
							cFileP->SetFileAndAuxType(fileType, auxType);

							SetGetInfoTypeAndAux();
							SelectDlogItem(ADFS_GetInfo_EDIT_TYPE);
						}
					}
				}
				break;
			}
			
			case ADFS_GetInfo_UCE_LOCKED_HIT:
			case ADFS_GetInfo_UCE_DESTROY:
			case ADFS_GetInfo_UCE_RENAME:
			case ADFS_GetInfo_UCE_READ:
			case ADFS_GetInfo_UCE_WRITE:
			case ADFS_GetInfo_UCE_BACKUP: {
				if (itemHit == ADFS_GetInfo_UCE_LOCKED_HIT) {
					itemHit = ADFS_GetInfo_UCE_LOCKED;
				}
				
				//	convert to actual check box
				itemHit++;
				
				if (TrackCheck(itemHit)) {
					ADFS_GetInfoCheckType	checkType	= GI_Item2Check(itemHit);
					Gen_AccessBits			access		= Gen_kAccess_LOCKED;

					i_checked[checkType] = !i_checked[checkType];
					
					if (checkType == ADFS_GetInfoCheck_LOCK) {
						i_checked[ADFS_GetInfoCheck_DESTROY]	= !i_checked[checkType];
						i_checked[ADFS_GetInfoCheck_RENAME]		= !i_checked[checkType];
						i_checked[ADFS_GetInfoCheck_WRITE]		= !i_checked[checkType];
					}


					access.destroyEnable	= i_checked[ADFS_GetInfoCheck_DESTROY];
					access.renameEnable		= i_checked[ADFS_GetInfoCheck_RENAME];
					access.readEnable		= i_checked[ADFS_GetInfoCheck_READ];
					access.writeEnable		= i_checked[ADFS_GetInfoCheck_WRITE];
					access.backup			= i_checked[ADFS_GetInfoCheck_BACKUP];

					i_entryP->SetAccessBits(&access);
					
					SetLockBits();
				}
				break;
			}
		}
	}
}

static	ADFS_StatType	InfoToStat(ADFS_GetInfoType infoType)
{
	ADFS_StatType	statType = ADFS_Stat_NONE;
	
	switch (infoType) {
	
		case ADFS_GetInfo_VERB_NAME: {
			statType = ADFS_Stat_NAME;
			break;
		}

		case ADFS_GetInfo_VERB_SIZE: {
			statType = ADFS_Stat_SIZE;
			break;
		}

		case ADFS_GetInfo_VERB_USED: {
			statType = ADFS_Stat_USED;
			break;
		}
	
		case ADFS_GetInfo_VERB_KIND: {
			statType = ADFS_Stat_KIND;
			break;
		}

		case ADFS_GetInfo_VERB_CREATED: {
			statType = ADFS_Stat_CRE_DATE;
			break;
		}

		case ADFS_GetInfo_VERB_MODIFIED: {
			statType = ADFS_Stat_MOD_DATE;
			break;
		}
	}
	
	return statType;
}

void	CDialogGetInfo::SetDialogFont(void)
{
	Prepare();
	
	if (Is_OS_X()) {
		TextSize(11);
	}
}

#define			DGI_ItemTable_MAX		15
DGI_ItemRec		gDGI_ItemTable[DGI_ItemTable_MAX] = {
	{	ADFS_GetInfo_STAT_KIND,			"Kind:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_SIZE,			"Size:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_USED,			"Used:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_WHERE,		"Where:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_CREATED,		"Created:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_MODIFIED,		"Modified:",	teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_STORAGE,		"Storage:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_TYPE,			"Type:",		teJustRight,		bold	},
	{	ADFS_GetInfo_STAT_AUXTYPE,		"AuxType:",		teJustRight,		bold	},
	{	ADFS_GetInfo_SC_DESTROY,		"Destroy",		teJustLeft,			bold	},
	{	ADFS_GetInfo_SC_RENAME,			"Rename",		teJustLeft,			bold	},
	{	ADFS_GetInfo_SC_WRITE,			"Write",		teJustLeft,			bold	},
	{	ADFS_GetInfo_SC_BACKUP,			"Backup",		teJustLeft,			bold	},
	{	ADFS_GetInfo_SC_READ,			"Read",			teJustLeft,			bold	},
	{	ADFS_GetInfo_SC_LOCKED,			"Locked",		teJustLeft,			bold	}
};

void	CDialogGetInfo::DialogItemStandardDrawProc(
	DialogItemIndex	itemNo, 
	Rect			*itemRectP)
{
	Rect	windowR = GetWindowRect(WindowRect_ALL);

	if (SectRect(&windowR, itemRectP, &windowR)) {
		char				str1[256], str2[256], str3[256];
//		unsigned char		*str1P = (unsigned char *)str1;
		Boolean				drawStringB = FALSE;
		Boolean				isFrontB = IsWindowHilited(GetWindowRef());
		short				justifyS = teJustLeft;
		RGBColor			foreK, backK;
		
		GetForeColor(&foreK);
		GetBackColor(&backK);
		
		SetDialogFont();

		if (!isFrontB) {
			APR_SetColor(APR_Color_MEDIUM);
		}

		switch (itemNo) {

			case ADFS_GetInfo_USER_ICON_OUTLINE: {
				//FrameRect(itemRectP);
				break;
			}

			case ADFS_GetInfo_USER_ICON: {
				i_entryP->DrawIcon(
					(isFrontB ? kTransformNone : kTransformDisabled), itemRectP);
				break;
			}

			case ADFS_GetInfo_STAT_KIND:
			case ADFS_GetInfo_STAT_SIZE:
			case ADFS_GetInfo_STAT_USED:
			case ADFS_GetInfo_STAT_WHERE:
			case ADFS_GetInfo_STAT_CREATED:
			case ADFS_GetInfo_STAT_MODIFIED:
			case ADFS_GetInfo_STAT_STORAGE:
			case ADFS_GetInfo_STAT_TYPE:
			case ADFS_GetInfo_STAT_AUXTYPE:
			case ADFS_GetInfo_SC_DESTROY:
			case ADFS_GetInfo_SC_RENAME:
			case ADFS_GetInfo_SC_WRITE:
			case ADFS_GetInfo_SC_BACKUP:
			case ADFS_GetInfo_SC_READ:
			case ADFS_GetInfo_SC_LOCKED: {
				short	tableIndex = GetItemTableIndex(gDGI_ItemTable, itemNo, DGI_ItemTable_MAX);
				
				strcpy(str1, gDGI_ItemTable[tableIndex].itemStr);
				justifyS = gDGI_ItemTable[tableIndex].justifyS;
				TextFace(gDGI_ItemTable[tableIndex].face);
				drawStringB = TRUE;
				break;
			}

			case ADFS_GetInfo_VERB_NAME: {
				EraseRect(itemRectP);
				TextFont(FMGetFontFamilyFromName("\pCharcoal"));
				TextSize(12);
				//	*** NO BREAK!!
			}

			case ADFS_GetInfo_VERB_SIZE:
			case ADFS_GetInfo_VERB_USED:
			case ADFS_GetInfo_VERB_KIND:
			case ADFS_GetInfo_VERB_CREATED:
			case ADFS_GetInfo_VERB_MODIFIED: {
				Rect			rect1, rect2, rect3;
				ADFS_StatType	statType = InfoToStat((ADFS_GetInfoType)itemNo);
				Boolean			oldIconView = g_isIconView;
				
				g_isIconView = TRUE;	//	turns off truncating
				i_entryP->GetStatString(statType, str1, &rect1, &rect2, &rect3);
				g_isIconView = oldIconView;
				
				if (itemNo == ADFS_GetInfo_VERB_USED) {
					ulong	sizeUL = i_entryP->GetLogicalSize();
					
					if (sizeUL > 1024) {
						FormatWithCommas(sizeUL, str2);
						sprintf(str3, "%s (%s bytes)", str1, str2);
						strcpy(str1, str3);
					}
				} else if (
					itemNo == ADFS_GetInfo_VERB_SIZE
					&& i_entryP->i_type == FSObject_DISK
				) {
					CDisk	*diskP = (CDisk *)i_entryP;
					ulong	sizeUL = diskP->GetVolumeBytesFree();
					
					FormatSize(sizeUL, str2);
					sprintf(str3, "%s (%s free)", str1, str2);
					strcpy(str1, str3);
				}
				
				drawStringB = TRUE;
				break;
			}

			case ADFS_GetInfo_USER_GROUP_LOCKED:
			case ADFS_GetInfo_USER_PREVIEW:
			case ADFS_GetInfo_USER_GROUP_SHOW: {
				OffsetRect(itemRectP, 1, 1);

				if (isFrontB) {
					APR_SetColor(APR_Color_WHITE);
					FrameRect(itemRectP);
				} else {
					Rect	eraseRect;

					eraseRect = *itemRectP;
					eraseRect.bottom = eraseRect.top + 1;
					EraseRect(&eraseRect);
					
					eraseRect = *itemRectP;
					eraseRect.left = eraseRect.right - 1;
					EraseRect(&eraseRect);

					eraseRect = *itemRectP;
					eraseRect.top = eraseRect.bottom - 1;
					EraseRect(&eraseRect);
					
					eraseRect = *itemRectP;
					eraseRect.right = eraseRect.left + 1;
					EraseRect(&eraseRect);
				}

				OffsetRect(itemRectP, -1, -1);

				APR_SetColor(APR_Color_MEDIUM);
				FrameRect(itemRectP);
				APR_SetColor(APR_Color_BLACK);
				
				if (itemNo == ADFS_GetInfo_USER_PREVIEW) {
				
					if (i_previewRec.type == ADFS_Preview_NONE) {
						i_entryP->GetPreview(&i_previewRec);
					}
					
					InsetRect(itemRectP, 2, 2);
					itemRectP->right	+= 1;
					itemRectP->bottom	+= 1;
					EraseRect(itemRectP);

					if (i_previewRec.type != ADFS_Preview_NONE) {

						switch (i_previewRec.type) {
						
							case ADFS_Preview_TEXT: {
								TextFont(GetAppFonts(40));
								TextSize(9);
								TextMode(srcOr);
								
								HLock(i_previewRec.u.textH);
								
								TETextBox(
									*i_previewRec.u.textH, 
									GetHandleSize(i_previewRec.u.textH), 
									itemRectP, teJustLeft);
									
								HUnlock(i_previewRec.u.textH);
								
								TextMode(srcCopy);
								BackColor(whiteColor);
								break;
							}
						
							case ADFS_Preview_PIC: {
								i_previewRec.u.offsP->Blit();
								break;
							}
						}
					}
				}
				break;
			}

			case ADFS_GetInfo_USER_ERASE_LOCKED:
			case ADFS_GetInfo_USER_ERASE_SHOW: {
				EraseRect(itemRectP);
				break;
			}

			case ADFS_GetInfo_POP_SHOW_DRAW:
			case ADFS_GetInfo_POPUP_DOS_TYPE:
			case ADFS_GetInfo_POPUP_PRO_TYPE: 
			case ADFS_GetInfo_POPUP_PAS_TYPE: 
			case ADFS_GetInfo_POPUP_CPM_TYPE: {
				HiliteControl(GetDlogItemControl(itemNo), isFrontB ? 0 : 255);
				Draw1Control(GetDlogItemControl(itemNo));
				break;
			}

			case ADFS_GetInfo_VERB_WHERE: {
				i_entryP->GetWhereString(str1);
				drawStringB = TRUE;
				break;
			}

			case ADFS_GetInfo_VERB_STORAGE: {
				i_entryP->GetStorageStr(str1);
				drawStringB = TRUE;
				break;
			}

			case ADFS_GetInfo_UC_LOCKED:
			case ADFS_GetInfo_UC_DESTROY:
			case ADFS_GetInfo_UC_RENAME:
			case ADFS_GetInfo_UC_WRITE:
			case ADFS_GetInfo_UC_READ:
			case ADFS_GetInfo_UC_BACKUP: {
				DrawCheck(itemNo, FALSE);
				break;
			}
		}

		if (drawStringB) {
			Rect	theRect = *itemRectP;
			
			if (
				justifyS == teJustRight
				&& Is_OS_X()
			) {
				theRect.right -= 4;
			}
			
			DrawCStringInRect(str1, &theRect, justifyS);
		}

		RGBForeColor(&foreK);
		RGBBackColor(&backK);
	}
}
typedef struct {
	CDialogGetInfo		*thiz;
	short				itemHit;
} GID_TrackCheckRec;

static	void		GID_CB_S_TrackCheck(Rect *theRect, void *data, Boolean in, Boolean Last)
{
	GID_TrackCheckRec	*checkDataP = (GID_TrackCheckRec *)data;
	
	checkDataP->thiz->DrawCheck(checkDataP->itemHit, in);
}

Boolean		CDialogGetInfo::TrackCheck(short itemHit)
{
	Rect				trackRect;
	GID_TrackCheckRec	checkData;
	
	//	get the UCE
	GetDlogItemRect(itemHit - 1, &trackRect);

	checkData.thiz		= this;
	checkData.itemHit	= itemHit;
	
	return TrackMouse1(&trackRect, GID_CB_S_TrackCheck, NULL, &checkData);
}

void			CDialogGetInfo::DrawCheck(short itemHit, Boolean trackingB)
{
	ADFS_GetInfoCheckType 	theCheck	= GI_Item2Check(itemHit);
	Rect					theRect;
	
	GetDlogItemRect(itemHit, &theRect);
	
	FrameRect(&theRect);
	InsetRect(&theRect, 1, 1);
	EraseRect(&theRect);
	InsetRect(&theRect, -1, -1);

	theRect.bottom--;
	theRect.right--;

	if (i_checked[theCheck]) {
		MoveTo(theRect.left, theRect.top);
		LineTo(theRect.right, theRect.bottom);
		MoveTo(theRect.right, theRect.top);
		LineTo(theRect.left, theRect.bottom);
	}

	if (trackingB) {
		theRect.top++;
		theRect.left++;
		FrameRect(&theRect);
	} else {
		Rect	eraseRect;

		theRect.bottom++;
		theRect.right++;
		
		InsetRect(&theRect, 1, 1);
		
		eraseRect = theRect;
		eraseRect.bottom = eraseRect.top + 1;
		InsetRect(&eraseRect, 1, 0);
		EraseRect(&eraseRect);
		
		eraseRect = theRect;
		eraseRect.left = eraseRect.right - 1;
		InsetRect(&eraseRect, 0, 1);
		EraseRect(&eraseRect);

		eraseRect = theRect;
		eraseRect.top = eraseRect.bottom - 1;
		InsetRect(&eraseRect, 1, 0);
		EraseRect(&eraseRect);
		
		eraseRect = theRect;
		eraseRect.right = eraseRect.left + 1;
		InsetRect(&eraseRect, 0, 1);
		EraseRect(&eraseRect);
	}
}

void		CDialogGetInfo::UpdateMenus(void)
{
	EnableCommand(cmdPreferences);
	EnableCommand(cmdAboutADFS);
	EnableCommand(cmdCloseWindow);
	EnableCommand(cmdCut);
	EnableCommand(cmdCopy);
	EnableCommand(cmdPaste);
	EnableCommand(cmdClear);
	EnableCommand(cmdQuit);
}

Boolean		CDialogGetInfo::DoCommand(long command)
{
	Boolean			handled = FALSE;
	
	switch (command) {
		
		case cmdCloseWindow: {
			Dispose();
			handled = TRUE;
			break;
		}

		case cmdCut: {
			DialogCut(GetDialogRef());
			break;
		}
		
		case cmdCopy: {
			DialogCopy(GetDialogRef());
			break;
		}
		
		case cmdPaste: {
			TERestoreRec	restoreRec;
			short			itemHit = GetDlogTextRestore(&restoreRec);
			
			DialogPaste(GetDialogRef());
			(void)VerifyText(itemHit, &restoreRec);
			break;
		}
		
		case cmdClear: {
			DialogDelete(GetDialogRef());
			break;
		}
	}
	
	return handled;
}

void		CDialogGetInfo::DoKeyDown(EventRecord *theEvent)
{
	short			keyResult = DGI_KeyDown_NONE;
	DialogPtr		theDialog;
	char			theKey	= VirtualASCII(theEvent);
	short			itemHit;
	TERestoreRec	restoreRec;

	if (theEvent->modifiers & cmdKey) {
		
		//	cut, copy, paste, clear all get handled at the top
			
		switch (theKey) {
			
			case '.': {
				keyResult = DGI_KeyDown_EXIT;
				break;
			}
				
			default: {
				_inherited::DoKeyDown(theEvent);
				break;
			}
		}
	} else {

		switch (theKey) {
			
			case RETURN_KEY:
			case ENTER_KEY: {
				itemHit = GetDialogKeyboardFocusItem(GetDialogRef());
				keyResult = DGI_KeyDown_DONE;
				break;
			}
			
			case ESC_CLEAR_KEY: {
				itemHit = GetDialogKeyboardFocusItem(GetDialogRef());
				keyResult = DGI_KeyDown_EXIT;
				break;
			}
			
			case DELETE_KEY:
			case TAB_KEY:
			case LEFT_ARROW_KEY:
			case RIGHT_ARROW_KEY: {
				DialogSelect(theEvent, &theDialog, &itemHit);				
				break;
			}
			
			default: {
				if (
					IS_HEX_DIGIT(theKey)
					|| (theKey == 'x' || theKey == 'X')
				) {
					short		ignore;

					itemHit = GetDlogTextRestore(&restoreRec);
					DialogSelect(theEvent, &theDialog, &ignore);
					keyResult = DGI_KeyDown_GOOD;
				} else {
					keyResult = DGI_KeyDown_BAD;
				}
				break;
			}
		}		
	}
	
	switch (keyResult) {
		
		case DGI_KeyDown_NONE: {
			//	yaaay!
			break;
		}

		case DGI_KeyDown_EXIT: {
			CancelText(itemHit);
			break;
		}

		case DGI_KeyDown_BAD: {
			SysBeep(1);
			break;
		}

		case DGI_KeyDown_GOOD: {			
			(void)VerifyText(itemHit, &restoreRec);
			break;
		}

		case DGI_KeyDown_DONE: {
			if (i_entryP->i_type == FSObject_FILE) {
				CFile	*cFileP		= (CFile *)i_entryP;
				Byte	newType		= VerifyText(ADFS_GetInfo_EDIT_TYPE, NULL);
				ushort	newAuxType	= VerifyText(ADFS_GetInfo_EDIT_AUXTYPE, NULL);

				cFileP->SetFileAndAuxType(newType, newAuxType);
				
				SetGetInfoTypeAndAux();
				SelectDlogItem(itemHit);
			}
			break;
		}
	}
}

void		CDialogGetInfo::CancelText(short itemHit)
{
	switch (itemHit) {
		
		case ADFS_GetInfo_EDIT_TYPE: {
			SetDlogItemText(itemHit, i_fileTypeStrA);
			break;
		}

		case ADFS_GetInfo_EDIT_AUXTYPE: {
			SetDlogItemText(itemHit, i_auxTypeStrA);
			break;
		}
	}

	SelectDlogItem(itemHit);
}

ushort		CDialogGetInfo::VerifyText(short itemHit, TERestoreRec *restoreRec0)
{
	ushort		newValueS	= 0;
	Boolean		badB		= FALSE;
	char		itemTextA[256];
	
	itemTextA[0] = 0;
	GetDlogItemText(itemHit, itemTextA);
	
	//	empty is okay, means zero
	if (itemTextA[0] != 0) {
		short		loop, loopMax;

		switch (itemHit) {
			
			case ADFS_GetInfo_EDIT_TYPE: {
				newValueS	= i_entryP->GetFileType();
				loopMax		= 2;
				break;
			}

			case ADFS_GetInfo_EDIT_AUXTYPE: {
				newValueS	= i_entryP->GetAuxType();
				loopMax		= 4;
				break;
			}
		}

		//	must start with 0x
		if (
			itemTextA[0] != '0'
			|| !(
				itemTextA[1] == 0 
				|| itemTextA[1] == 'x' 
				|| itemTextA[1] == 'X'
			)
		) {
			badB = TRUE;
		}
		
		if (!badB) {
			for (loop = 0; loop <= loopMax; loop++) {
				if (loop == loopMax) {
					if (itemTextA[2 + loop] != 0) {
						badB = TRUE;
					}
				} else if (itemTextA[2 + loop] == 0) {
					loop = loopMax;
				} else {
					char		newChar = itemTextA[2 + loop];
					Boolean		goodB = FALSE;
					
					if (newChar >= '0' && newChar <= '9')
						goodB = TRUE;
					
					if (newChar >= 'a' && newChar <= 'f')
						goodB = TRUE;
					 
					if (newChar >= 'A' && newChar <= 'F')
						goodB = TRUE;
					
					badB = !goodB;

//					if (!IS_HEX_DIGIT(newChar)) {
//						badB = TRUE;
//					}
				}
			}
			
			if (!badB) {
				int		newValueI;
				
				sscanf(itemTextA, "%i", &newValueI);
				newValueS = (ushort)newValueI;
			}
		}
		
		if (badB) {
			SysBeep(1);
			if (restoreRec0) {
				RestoreDlogText(restoreRec0);
			}
		}
	}
	
	return newValueS;
}

ControlRef	CDialogGetInfo::GetDlogItemControl(short dlgItem)
{
	ControlRef	theControl = NULL;
	
	if (
		dlgItem >= ADFS_GetInfo_POPUP_DOS_TYPE
		&& dlgItem <= ADFS_GetInfo_POPUP_CPM_TYPE
	) {
		theControl = i_typePops[dlgItem - ADFS_GetInfo_POPUP_DOS_TYPE];
	} else if (
		dlgItem == ADFS_GetInfo_POP_SHOW_DRAW
		|| dlgItem == ADFS_GetInfo_POP_SHOW_HIT
	) {
		theControl = i_showPop;
	}

	return theControl;
}

//	static
void	CDialogGetInfo::CB_S_GetInfo_Offs(
	OffscreenCBType cbType, 
	OffscreenCBData	*cbData, 
	void			*cbRefcon)
{
	CDialogGetInfo	*thiz = (CDialogGetInfo *)cbRefcon;
	
	thiz->CB_GetInfo_Offs(cbType, cbData);
}

void	CDialogGetInfo::CB_GetInfo_Offs(
	OffscreenCBType cbType, 
	OffscreenCBData	*cbData)
{
	switch (cbType) {

		case OffscreenCB_GET_FRAME: {
			GetDlogItemRect(ADFS_GetInfo_USER_PREVIEW, &cbData->frame);
			InsetRect(&cbData->frame, 1, 1);
			cbData->frame.bottom = cbData->frame.top + kA2pixHeight;
			break;
		}

		case OffscreenCB_GET_FRAME_DEPTH: {
			cbData->frame_depth = 32;
			break;
		}

		case OffscreenCB_CAUSE_UPDATE: {
			InvalWindow(WindowRect_INTERIOR);
			break;
		}
	}
}

