//	ADFS_Menus.c

#include "ADFS_LogFile.h"
#include "ADFS_Prefs.h"
#include "Open_Save.h"
#include "DSAppleEvents.h"
#include "IC_FileIO.h"
#include "IC_Errors.h"
#include "COutlineWindow.h"
#include "Carbon68kGlue.h"
#include "Utils.h"
#include "ADFS_LogFile.h"
#include "CDialogGetInfo.h"
#include "CDialogCopy.h"

#include "ADFS_Menus.h"

void	StripCommands(void);

void	SetUpMenus(void)
{
	Handle		mBar;
	MenuHandle	theMenu;
	
	mBar = GetNewMBar(128);
	SetMenuBar(mBar);
	DisposeHandle(mBar);

	StripCommands();

	#ifndef __68k__
		if (Is_OS_X()) {
			theMenu = GetMenuHandle(menuFile);
			DeleteMenuItem(theMenu, CommandItem(cmdQuit));
			DeleteMenuItem(theMenu, CommandItem(cmdQuit) - 1);

			theMenu = GetMenuHandle(menuEdit);
			DeleteMenuItem(theMenu, CommandItem(cmdPreferences));
			DeleteMenuItem(theMenu, CommandItem(cmdPreferences) - 1);
		}
	#else
		AppendResMenu(GetMenuHandle(menuApple), 'DRVR');
	#endif
	
	theMenu = GetMenuHandle(menuFont);
	if (theMenu) {
		AppendResMenu(theMenu, 'FONT');
	}
	
	DrawMenuBar();
}

Boolean		DoMenuKey(EventRecord *theEvent)
{
	Boolean	handled = FALSE;
	
	if (theEvent->modifiers & cmdKey) {
		long	command;
		char	theKey = theEvent->message & charCodeMask;
		
		UpdateMenus();
		
		if (theKey == DELETE_KEY) {
			theKey = 0x17;	//	ctrl-opt-w (the glyph for [delete])
		}
		
		command = MenuKey(theKey);

		handled = CommandMenu(command) != 0;
		
		if (handled) {
			DoMenu(command);
		}
	}
	
	return handled;
}

void	DoAppleMenu(short menuChoice)
{
	if (menuChoice == CommandItem(cmdAboutADFS)) {
		void	ShowAbout(void);
		
		ShowAbout ();	/*	Show the about box */
	} else {
		#ifdef __68k__
			Str255	itemStr;
			
			GetMenuItemText(GetMenuHandle(menuApple), menuChoice, itemStr);
			OpenDeskAcc(itemStr);
		#endif
	}
}


void	DoFileMenu(short menuChoice)
{
	switch (menuChoice) {

		case CommandItem(cmdQuit): {
			SendQuitToSelf();	// send self a 'quit' event
			break;
		}
	}
}

void	DoEditMenu(short menuChoice)
{
}

static	Boolean	DoFontMenuCB(CWindow *window, void *data)
{
	window->UpdateFontInfo((ADFS_FontRec *)data);
	return FALSE;
}

void	DoFontMenu(short menuChoice)
{
	GetMenuItemText(GetMenuHandle(menuFont), menuChoice, gFontRec.fontName);
	gFontRec.fontID = FMGetFontFamilyFromName(gFontRec.fontName);
	gFontRec.fontFace = normal;
	gFontRec.fontMode = srcCopy;
	IterateCWindows(DoFontMenuCB, &gFontRec);
}

void	DoSizeMenu(short menuChoice)
{
	Str255	sizeString;
	char	*sizeStringC = (char *)&sizeString;
	
	GetMenuItemText(GetMenuHandle(menuSize), menuChoice, sizeString);
	CopyPascalStringToC(sizeString, sizeStringC);
	sscanf(sizeStringC, "%hu", (unsigned short *)&gFontRec.fontSize);
	IterateCWindows(DoFontMenuCB, &gFontRec);
}

MenuRef		FindMenu(short menuID)
{
	MenuRef		theMenu = GetMenuHandle(menuID);
	
	if (!theMenu) {
		theMenu = GetMenu(menuID);
	}
	
	return theMenu;
}

Boolean	DoCommand(long command)
{
	CWindow			*window;
	Boolean			commanded = FALSE;
	
	if (!commanded && (window = GetFrontCWindow()) != NULL) {	/*=*/
		commanded = window->DoCommand(command);
	}
	
	if (!commanded) {
	
		switch (command) {
		
			case cmdPreferences: {
				ShowPrefsDialog();
				break;
			}
			
			default: {
				#ifdef __ROSE__
					commanded = DoCommand_Generator(command);
				#endif
				break;
			}
		}
	}

	return commanded;
}

void DoMenu ( long command ) 
{
	if (CommandMenu(command)) {
		char	bufAC[256];
		
		ADFS_Log(GetCommandString(command, bufAC));

		if (!DoCommand(command)) {
			short	commandItem = CommandItem(command);

			switch (CommandMenu(command)) {

				case menuApple:
					DoAppleMenu(commandItem);
					break;
					
				case menuFile:
					DoFileMenu(commandItem);
					break;

				case menuEdit:
					DoEditMenu(commandItem);
					break;

				case menuFont: {
					DoFontMenu(commandItem);
					break;
				}
				
				case menuSize: {
					DoSizeMenu(commandItem);
					break;
				}
			}
		}
	}

	HiliteMenu(0);		// turn it off!
}

static	void		DisableEveryMenuItem(MenuRef theMenu)
{
	if (theMenu) {
		short	maxItems, curItem, cmdChar;

		maxItems = CountMenuItems(theMenu);
		
		for (
			curItem = 1;
			curItem <= maxItems;
			curItem++
		) {
			DisableMenuItem(theMenu, curItem);
			GetItemCmd(theMenu, curItem, &cmdChar);
			
			if (cmdChar == hMenuCmd) {
				MenuHandle		subMenuH;
				
				GetItemMark(theMenu, curItem, &cmdChar);
				
				subMenuH = GetMenuHandle(cmdChar);
				DisableEveryMenuItem(subMenuH);
			} else {
				SetItemMark(theMenu, curItem, noMark);
			}
		}
	}
}

void	UpdateMenus(void)
{
	CWindow			*window;
	MenuRef			theMenu;
	short			curMenuIndex;
	MBarHandle		mBarH;
	
	mBarH = (MBarHandle)GetResource('MBAR', 128);
	
	for (
		curMenuIndex = 1;	//	don't start at 0 == apple menu
		curMenuIndex < (**mBarH).numItems;
		curMenuIndex++
	) {
		theMenu = GetMenuHandle((**mBarH).itemA[curMenuIndex]);
		DisableEveryMenuItem(theMenu);
	}

	ReleaseResource((Handle)mBarH);

	DisableCommand(cmdAboutADFS);
	DisableCommand(cmdPreferences);

	if ((window = GetFrontCWindow()) != NULL) {	/*=*/
		window->UpdateMenus();
	}
	
	#ifdef __ROSE__
		UpdateMenus_Generator();
	#endif
}


/********************************/
void	AbleMenuItem(MenuRef theMenu, short menuItem, Boolean able)
{
	if (able) {
		EnableMenuItem(theMenu, menuItem);
	} else {
		DisableMenuItem(theMenu, menuItem);
	}
}

void	AbleCommand(ulong cmd, Boolean able)
{
	MenuHandle		theMenu;
	MenuItemIndex	menuItem;
	
	if (Is_OS_X() && cmd == cmdPreferences) {
		#ifndef __68k__
			OSErr	err = GetIndMenuItemWithCommandID(
				NULL, // search all menus
				kHICommandPreferences,
				1,	// return first found item
				&theMenu,
				&menuItem);
			
			if (err) {
				ReportErrorStr(err, "Couldn't find Prefs menu item");
				theMenu = NULL;
			}
		#endif
	} else {
		theMenu		= GetMenuHandle(CommandMenu(cmd));
		menuItem	= CommandItem(cmd);
	}
	
	if (theMenu) {
		AbleMenuItem(theMenu, menuItem, able);
	}
}

void	EnableCommand(ulong cmd)
{
	AbleCommand(cmd, TRUE);
}

void	DisableCommand(ulong cmd)
{
	AbleCommand(cmd, FALSE);
}

void	AbleCommandGroup(ulong firstCmd, ulong lastCmd, Boolean ableB)
{
	ulong	curCmd;
	
	for (curCmd = firstCmd; curCmd <= lastCmd; curCmd++) {
		AbleCommand(curCmd, ableB);
	}
}

void	RadioButtonItem(MenuHandle theMenu, int firstItem, int lastItem, int buttonItem)
{
	int	theItem;
	
	for (theItem = firstItem ; theItem <= lastItem ; ++theItem)
		SetItemMark(theMenu, theItem, (char)noMark);

	SetItemMark(theMenu, buttonItem, '¥');
}

void	RadioButtonCommand(ulong firstCmd, ulong lastCmd, ulong buttonCmd)
{
	RadioButtonItem(
		GetMenuHandle(CommandMenu(buttonCmd)), 
		CommandItem(firstCmd), 
		CommandItem(lastCmd), 
		CommandItem(buttonCmd)
	);
}

char	*GetCommandString(ulong command, char *bufZ)
{
	char		strAC1[256], strAC2[256];
	MenuRef		theMenu = GetMenuHandle(CommandMenu(command));
	
	bufZ[0] = 0;
	
	if (theMenu) {
		GetMenuTitle(theMenu, (uchar *)strAC1);
		CopyPascalStringToC((uchar *)strAC1, strAC1);
		
		GetMenuItemText(theMenu, CommandItem(command), (uchar *)strAC2);
		CopyPascalStringToC((uchar *)strAC2, strAC2);
		
		sprintf(bufZ, "Menu Command: %s->%s\n", strAC1, strAC2);
	}
	
	return bufZ;
}

void	CheckCommand(ulong command, Boolean check)
{
	CheckMenuItem(GetMenuHandle(CommandMenu(command)), CommandItem(command), check);
}

void	DashCommand(ulong command, Boolean dash)
{
	SetItemMark(GetMenuHandle(CommandMenu(command)), CommandItem(command), '-');
}

char	GetCommandMark(ulong command)
{
	short	theChar;
	
	GetItemMark(GetMenuHandle(CommandMenu(command)), CommandItem(command), &theChar);
	return (char)theChar;
}

Boolean IsItemEnabled(MenuRef menu, short item)
{
	Boolean result	= TRUE;
	
	#ifndef __68k__
		result = IsMenuItemEnabled(menu, item);
	#else
		long	flag	= 1;

		if (item >= 1 && item <= 31)
			flag = 1L << item;

		if (!((**menu).enableFlags & 1) || !((**menu).enableFlags & flag)) {
			result = FALSE;
		}
	#endif
	
	return result;
}

Boolean	IsCommandEnabled(ulong cmd)
{
	return IsItemEnabled(
		GetMenuHandle(CommandMenu(cmd)), 
		CommandItem(cmd)
	);
}

void	ClearMenu(MenuHandle theMenu)
{
	if (theMenu != NULL) {
		int		items, curItem;
		
		items = CountMenuItems(theMenu);
		for (curItem = 1; curItem <= items; ++curItem)
			DeleteMenuItem(theMenu, 1);
	}
}

void	CopyMenu(MenuHandle dest_menu, MenuHandle src_menu)
{
	ClearMenu(dest_menu);

	if (dest_menu != NULL) {
		int		items, curItem;
		Style	style;
		Str255	buf;
		
		items = CountMenuItems(src_menu);
		
		for (curItem = 1; curItem <= items; ++curItem) {
			AppendMenu(dest_menu, P_MENU_BLANK);
			
			GetMenuItemText(src_menu, curItem, buf);
			SetMenuItemText(dest_menu, curItem, buf);
			
			GetItemStyle(src_menu, curItem, &style);
			SetItemStyle(dest_menu, curItem, style);
		}
	}
}

void	CheckMenuGroup(MenuRef theMenu, int firstItem, int lastItem, int checkItem)
{
	int	theItem;
	
	for (theItem = firstItem ; theItem <= lastItem ; ++theItem)
		SetItemMark(theMenu, (short)theItem, (char)noMark);
		
	CheckMenuItem(theMenu, (short)checkItem, TRUE);
}
