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

#include <stdio.h>
#include "Utils.h"
#include "FSUtils.h"
#include "IC_Errors.h"
#include "Utils.h"
#include "ADFS_Menus.h"
#include "Carbon68kGlue.h"

//	a command follows a slash (/)
//	a double slash (//) is a literal slash
static	void	StripCommand(Str255 theString, Str255 theCommand)
{
	unsigned char	*theChar = NULL;
	short			charIndex, length;
	Boolean			doubleSlash = FALSE;
	
	length = theString[0];
	
	if (length == 0) {
		ReportErrorStr(0, "Zero length string!");
	}
	
	if (length) for (
		theChar = &theString[1], charIndex = 1; 
		charIndex <= length; 
		theChar++, charIndex++
	) {
		if (theChar[0] == '/') {
			if (theChar[1] != '/') {
				break;
			} else {
				doubleSlash = TRUE;
				theChar++, charIndex++;
			}
		}
	}
	
	if (length && *theChar == '/') {
		theString[0] = charIndex - 1;		
		theString[charIndex] = length - charIndex;
		CopyString(theChar, theCommand);
	} else {
		theCommand[0] = 0;
	}
	
	if (doubleSlash) {
		length = theString[0];
		
		for (
			theChar = &theString[1], charIndex = 1; 
			charIndex <= length; 
			theChar++, charIndex++
		) {
			*theChar = theString[charIndex];
			
			if (theChar[0] == '/' && theChar[1] == '/') {
				theString[0]--;
				charIndex++;
			}
		}
	}
}

typedef struct {
	unsigned	char	menusChanged	: 1;
	unsigned	char	unused6			: 1;
	unsigned	char	unused5			: 1;
	unsigned	char	unused4			: 1;
	unsigned	char	unused3			: 1;
	unsigned	char	unused2			: 1;
	unsigned	char	unused1			: 1;
	unsigned	char	unused0			: 1;
} ADFS_FlagRec, **ADFS_FlagH;

static	Boolean		UpdateIt(void)
{
	Boolean			updated	= FALSE;
	ADFS_FlagH		flagH	= (ADFS_FlagH)Get1Resource('MENf', 128);
	
	if (!flagH) {
		ReportErrorStr(ResError(), "Couldn't get flag resourse.");
	} else {
		updated = (**flagH).menusChanged;
		
		if (updated) {
			(**flagH).menusChanged	= FALSE;
			
			ChangedResource((Handle)flagH);
			WriteResource((Handle)flagH);
			ReleaseResource((Handle)flagH);
		} else {
			updated = check_key_down(option_key);
		}
	}
		
	return updated;
}

static	Boolean		UpdateChangeFlag(void)
{
	Boolean			updated = UpdateIt();
	
	if (updated) {
		FSSpec	resFSSpec;
		short	appRes = CurResFile();
		short	projRes;
		OSErr	err;
		
		err = FSpThisApp(&resFSSpec);
		
		if (!err) {
			CopyString(c2p(":Source:MenuFlag.rsrc"), resFSSpec.name);

			projRes = FSpOpenResFile(&resFSSpec, fsRdWrPerm);
			err = ResError();
		}
		
		if (!err) {
			UseResFile(projRes);
			UpdateIt();
			UseResFile(appRes);
		} else {
			ReportErrorStr(err, "Couldn't open the project resource file.");
		}
	}
	
	return updated;
}

void	GetMenuCommand(MenuRef theMenu, Str255 command);
void	GetMenuCommand(MenuRef theMenu, Str255 command)
{
	short		resID = GetMenuID(theMenu);
	ResType		resType;
	Handle		resHandle;

	resHandle = Get1Resource('MENU', resID);
	GetResInfo(resHandle, &resID, &resType, command);
}


#define		kAppleChar		20

void	StripCommands(void);
void	StripCommands(void)
{
	MenuRef			theMenu;
	short			curMenuIndex;
	MBarHandle		mBarH;
	FILE			*cmdFile = NULL;
		
	if (UpdateChangeFlag()) {
		cmdFile = fopen(":Source:ADFS_Commands.h", "w");
		if (!cmdFile) {
			ReportErrorStr(0, "Can't open command file.");
		} else {
			fprintf(cmdFile, 
				"//	ADFS_Commands.h\n\n"
				"#ifndef _H_ADFS_Commands\n"
				"#define _H_ADFS_Commands\n"
			);
		}
	}
	
	mBarH = (MBarHandle)GetResource('MBAR', 129);
	
	for (
		curMenuIndex = 0;	//	don't start at 0 == apple menu
		curMenuIndex < (**mBarH).numItems;
		curMenuIndex++
	) {
		theMenu = FindMenu((**mBarH).itemA[curMenuIndex]);
		
		if (!theMenu) {
			ReportErrorStr(ResError(), "Can't get indexed menu.");
		} else {
			short	menuID, cmdChar;

			menuID = GetMenuID(theMenu);

			if (!theMenu) {
				ReportErrorStr(menuID, "MenuID does not match!");
			} else {
				short	menuItem, maxItems;
				short	curSpace, maxSpace;
				Str255	theString, command, spaces;

				GetMenuCommand(theMenu, command);

				if (cmdFile && command[0]) {
					maxSpace = 25 - command[0];
					spaces[0] = maxSpace;
					
					for (curSpace = 1; curSpace <= maxSpace; curSpace++) {
						spaces[curSpace] = ' ';
					}
					
					fprintf(cmdFile, "\n"
						"/*********************************************************/\n"
						"//		%#s\n" 
						"#define	%#s%#s0x%.4X\n\n", 
						command, command, spaces, menuID
					);
				}
			
				//	 only do one item on the apple menu
				if (curMenuIndex == 0) {
					maxItems = 1;
				} else {
					maxItems = CountMenuItems(theMenu);
				}

				for (
					menuItem = 1;
					menuItem <= maxItems;
					menuItem++
				) {
					//	insert any sub menus
					GetItemCmd(theMenu, menuItem, &cmdChar);
					
					if (cmdChar == hMenuCmd) {
						MenuHandle		subMenuH;
						
						GetItemMark(theMenu, menuItem, &cmdChar);
						
						subMenuH = FindMenu(cmdChar);
						if (subMenuH) {
							InsertMenu(subMenuH, hierMenu);
						}
					}

					GetMenuItemText(theMenu, menuItem, theString);
					
					if (theString[1] != '-') {
						StripCommand(theString, command);
						SetMenuItemText(theMenu, menuItem, theString);

						if (cmdFile && command[0]) {
							maxSpace = 25 - command[0];
							spaces[0] = maxSpace;
							
							for (curSpace = 1; curSpace <= maxSpace; curSpace++) {
								spaces[curSpace] = ' ';
							}
							
							fprintf(cmdFile, 
								"#define	%#s%#s0x%.8lX\n", 
								command, spaces, MenuItemCommand(menuID, menuItem)
							);
						}
					}
				}
			}
		}
	}

	ReleaseResource((Handle)mBarH);

	if (cmdFile) {
		fprintf(cmdFile, "\n"
			"/*********************************************************/\n\n"
			"#endif\n"
		);
			
		fclose(cmdFile);
		
		ReportErrorStr(0, "Updated menu commands.  Will now quit.");
		ExitToShell();
	}
}
