//#define INHIBITALGO	// Make OT_InhibitAlgoStyle changeable
//#define FAMILYNAMES	// Make OT_Family, OT_BName etc. changeable

#ifndef T1MANAGER_GST
#include "t1manager.h"
#endif


/*************************************************************/
/* Global Variables */
/*************************************************************/

long __oslibversion = 37;	// TetiSoft: forgotten?

struct LocaleInfo LInfo;

struct GlyphEngine *engine;

/* MUI stuff */
struct Library *MUIMasterBase;
static Object *app_obj;			/* Application object */
static Object *window_obj_main;		/* Main window object */
static Object *cycle_obj_dirs;		/* Cycle object - Current font directory */
static Object *listview_obj;		/* Listview object - Already Installed Fonts */
static Object *string_obj_name;		/* String object - Font name */		// TetiSoft
static Object *button_obj_install;	/* Button object - Click To Install Fonts */
static Object *button_obj_modify;	/* Button object - Click to modify fonts */	// TetiSoft
static Object *button_obj_remove;	/* Button object - Click to remove fonts */
static Object *txt_obj_preview;		/* Text Object   - Preview */
static Object *bm_obj_preview;		/* Bitmap Object - Preview */

// TetiSoft: Modify window
static Object *window_obj_modify;	/* Modify window object */
static Object *cycle_obj_fixed;		/* Cycle object  - Fixed width */
static Object *cycle_obj_serif;		/* Cycle object  - Serifs */
static Object *cycle_obj_slant;		/* Cycle object  - Slant style */
static Object *cycle_obj_weight;	/* Cycle object  - Stem weight */
static Object *cycle_obj_hstyle;	/* Cycle object  - Horiz style */
//static Object *lv_obj_symset;		/* Listview      - SymbolSet */
static Object *check_obj_symset;	/* Checkmark     - SymbolSet */
static Object *cycle_obj_symset;	/* Cycle object  - SymbolSet */
static Object *button_obj_symset;	/* Button object - SymbolSet */
static Object *string_obj_spacew;	/* String object - Space width */
static Object *group_obj_ysizef;	/* Group object  - YSize factor */
static Object *string_obj_ysizefph;	/* String object - YSize factor point height */
static Object *string_obj_ysizefbh;	/* String object - YSize factor black height */
#ifdef INHIBITALGO
static Object *check_obj_bold;		/* Checkmark object - algorithmic boldening */
static Object *check_obj_italic;	/* Checkmark object - algorithmic slanting */
static Object *check_obj_extend;	/* Checkmark object - algorithmic extending */
static Object *check_obj_underl;	/* Checkmark object - algorithmic underlining */
#endif
static Object *lv_obj_sizes;		/* Listview object - Available sizes */
static Object *string_obj_sizes;	/* String object - Selected size */
static Object *button_obj_addsize;	/* Button object - Add a size */
static Object *button_obj_delsize;	/* Button object - Delete a size */
static Object *button_obj_addbm;	/* Button object - Add a bitmap size */
static Object *button_obj_delbm;	/* Button object - Delete a bitmap size */
#ifdef FAMILYNAMES
static Object *string_obj_family;	/* String object - Family name */
static Object *string_obj_bname;	/* String object - Bold font name */
static Object *string_obj_iname;	/* String object - Italic font name */
static Object *string_obj_biname;	/* String object - Bold italic font name */
#endif
static Object *group_obj_files;		/* Group object  - File names */
static Object *string_obj_type1;	/* String object - Type1 file name */
static Object *pop_obj_type1;		/* Popup button  - Type1 file name */
static Object *string_obj_afm;		/* String object - AFM file name */
static Object *pop_obj_afm;		/* Popup button  - AFM file name */
static Object *button_obj_save;		/* Button object - Save changes */
static Object *button_obj_cancel;	/* Button object - Ignore changes */

static Object *window_obj_enc;		/* Encoding window object */
static Object *cycle_obj_unipg;		/* Cycle object  - Unicode page */
static Object *txt_obj_unipg;		/* Text Object   - Unicode page description */
static Object *bm_obj_enc;		/* Bitmap object - Encoding display */

// Declared here with NULL pointers, replaced with localized strings later
static unsigned char *Widths[3];
static unsigned char *Slants[4];
static unsigned char *Serifs[3];
static unsigned char *Weights[17];
static unsigned char *HStyles[9];
static unsigned char *SymbolSets[NRENCODINGS+1];
unsigned char *Pages[257];
unsigned char PageNumbers[256][12];
static unsigned char *PageStrings[256];

// TetiSoft: Presets for Install
static struct OTagValues InstallPresets =
{
	TRUE,		// OT_SerifFlag default
	0xffff,		// Build OT_StemWeight from font dictionary "Weight" description
	OTH_Normal,	// OT_HorizStyle default
	0xffff,		// Build OT_IsFixed from font dictionary "IsFixedPitch" description
	0xffff,		// Build OT_SlantStyle from font dictionary "ItalicAngle" description
	0,		// Compute OT_SpaceWidth from fonts space width
	0,		// Compute OT_YSizeFactor from fonts ascender and descender heights
						// OT_EmboldenX, OT_EmboldenY, OT_UnderLined, OT_SetFactor not supported yet
	FSF_UNDERLINED|FSF_BOLD|FSF_EXTENDED,	// OT_InhibitAlgoStyle default
	"",		// Build OT_Family from font dictionary
	"",		// OT_BName default
	"",		// OT_IName default
	"",		// OT_BIName default
	"",		// OTagFileName default
	"",		// OT_Spec1_PFABFileName default
	"",		// OT_Spec2_AFMFileName default
	{
		8,	// OT_AvailSizes default
		{5, 10, 12, 15, 30, 45, 60, 75}
	},
	0,		// OT_SymbolSet default
	0,		// OT_SpaceFactor default. Synonym for OT_SpaceWidth?
	0xffff		// OT_Spec6_OwnEncoding default unknown
};

// TetiSoft: Presets for Modify
static struct OTagValues ModifyPresets;
static struct OTagValues OTagPresets;
static struct AvailSizeList AvailBMSizes;
static struct AvailSizeList WantedBMSizes;

enum IDs {
	ID_INSTALL = 1,
	ID_CYCLE,
	ID_DOUBLECLICK,
	ID_REMOVE,
	ID_SELECTCHANGE,
//	ID_REDRAW_PREVIEW,
	ID_RENAME,
	ID_MODIFY,
	ID_MODIFY_FIXED,
	ID_MODIFY_SERIF,
	ID_MODIFY_SLANT,
	ID_MODIFY_WEIGHT,
	ID_MODIFY_HSTYLE,
	ID_MODIFY_SYMSET,
	ID_MODIFY_SHOWSYMSET,
	ID_MODIFY_SPACEW,
	ID_MODIFY_YSIZEFPH,
	ID_MODIFY_YSIZEFBH,
#ifdef INHIBITALGO
	ID_MODIFY_INHIBITALGO,
#endif
	ID_MODIFY_SELSIZECHANGE,
	ID_MODIFY_SIZECHANGE,
	ID_MODIFY_ADDSIZE,
	ID_MODIFY_DELSIZE,
	ID_MODIFY_ADDBM,
	ID_MODIFY_DELBM,
#ifdef FAMILYNAMES
	ID_MODIFY_FAMILY,
	ID_MODIFY_BNAME,
	ID_MODIFY_INAME,
	ID_MODIFY_BINAME,
#endif
	ID_MODIFY_TYPE1FILE,
	ID_MODIFY_AFMFILE,
	ID_MODIFY_SAVE,
	ID_MODIFY_CANCEL,
	ID_ENC_CLOSE,
	ID_ENC_PAGE,
	ID_MENU_ABOUT
};

char *fontdirparts[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int sizefontdirparts = (sizeof(fontdirparts) / sizeof(char *));
int numfontdirparts = 0;

static BOOL mod_window_open = FALSE;
static BOOL enc_window_open = FALSE;
static struct Hook H_SizesDisp;

// TetiSoft: Preview text selectable
static unsigned char *PreviewText, *PreviewText2;

struct Hook H_AddManyFonts;

/* Storage for the font preview */
struct BitMap *bitmap;
struct BitMap *encbitmap;
int bitmapwidth, bitmapheight;
int encbmwidth, encbmheight;
char currentpreviewfont[80];
static LONG previewwidth, previewheight, encpreviewheight;

char *OTagFileBuf = NULL;		// TetiSoft
static char FontDirName[MAXFONTPATH];	// TetiSoft
static char blFontDir[MAXFONTPATH];	// TetiSoft
static char blFontName[MAXFONTPATH];	// TetiSoft
static char EncWinTitle[MAXFONTPATH];	// TetiSoft

unsigned char *UnicodeArray;
unsigned char UnicodePages[256];
int QuickInstall = FALSE;

int can_use_V39_funcs = 1;

static struct FileRequester *FileRequester = NULL;	// Moved by TetiSoft
static struct Window *window = NULL;			// Moved by TetiSoft

/*************************************************************/
/* Prototypes */
/*************************************************************/
static BOOL InstallFont(APTR ParentWindow, char *destdrawer);
static BOOL RenameFont(char *fontdrawer, char *oldfontname, char *newfontname);	// TetiSoft
static BOOL RemoveFont(APTR ParentWindow, char *destdrawer, char *fontname);
//static BOOL PreviewFont(APTR ParentWindow, char *destdrawer, char *fontname);
static BOOL PreviewFont(APTR ParentWindow, char *destdrawer, char *fontname, struct TagItem *AddOTags);	// TetiSoft
static struct BitMap *MyAllocBitMap(int width, int height);
static void MyFreeBitMap(struct BitMap *bitMap, int width, int height);
void AddFontToListview(char *otagname, char *filebuf);

// TetiSoft: Modify window
static BOOL create_modify_window(char *filename);
static BOOL open_modify_window(void);
static void close_modify_window(void);
static LONG __saveds __asm SizesDispFunc(register __a0 struct Hook *hook, register __a1 char *sizestr, register __a2 char **array);
static void AddBitmapsToList(char *filename, int filesize);
static void HandleBitmaps(struct AvailSizeList *there, struct AvailSizeList *wanted, int RebuildBitmaps);
static void DeleteBitmap(long size);
static int AddSize(struct AvailSizeList *list, long size);
static int DelSize(struct AvailSizeList *list, long size);
static void PreviewModified(void);
static BOOL DidChange(void);
static void SizeStringChange(void);
static BOOL create_enc_window(int bmwidth, int bmheight);
static BOOL update_enc_window(char *FontName);
static void close_enc_window(void);
static BOOL RenderEncoding(struct RastPort *rp, int width, int height, int charwidth, int charheight, int baseline, ULONG firstglyph, BOOL *didhorfit, BOOL *didvertfit);
static void OverWriteFontFile(char *fontfilename);

static BOOL RenderEncoding(struct RastPort *rp, int width, int height, int charwidth, int charheight, int baseline, ULONG firstglyph, BOOL *didhorfit, BOOL *didvertfit)
{
	ULONG glyphcode;
	int line;
	int i, x, y;
	int rc;
	struct GlyphMap *glyph;
	PLANEPTR Template;
	BOOL didfith = TRUE;
	BOOL didfitv = TRUE;

	if (Template = AllocRaster(width, charheight))
	{
		ULONG drawmodestorage = GetDrMd(rp);
		struct TextFont *fontstorage = rp->Font;
		char string[12];
		int bldiff;

		SetDrMd(rp, JAM1);
		SetFont(rp, GfxBase->DefaultFont);
//		bldiff = rp->Font->tf_YSize - rp->Font->tf_Baseline;
		bldiff = 1;	// We assume that numbers have no descenders
		for (x = 0; x <= (16 * (charwidth + 3)); x += (charwidth + 3))
		{
			Move(rp, x, 0);
			Draw(rp, x, height - 1);
		}
		for (y = 0, i = 0; y < height; y += (charheight + 3), i += 16)
		{
			Move(rp, 0, y);
			Draw(rp, width - 1, y);
			if (i <= 240)
			{
				if (!firstglyph)
					sprintf(string, "%03ld - %03ld", i, i + 15);
				else
					sprintf(string, "%04lx-%04lx", i + firstglyph, i + firstglyph + 15);
				Move(rp, 16 * (charwidth + 3) + 2, ((y - 2) - bldiff) + charheight + 3);
				Text(rp, string, 9);
			}
		}
		WaitBlit();
		SetDrMd(rp, COMPLEMENT);
		y = 2 + baseline;
		for (line = 0; line < 16; line++)
		{
			x = 2;
			for (glyphcode = firstglyph + line * 16; glyphcode < (firstglyph + (line + 1) * 16); glyphcode++)
			{
				if (((rc = SetInfo(engine, OT_GlyphCode, glyphcode, TAG_DONE, 0)) == OTERR_Success) &&
				    ((rc = ObtainInfo(engine, OT_GlyphMap, &glyph, TAG_DONE, 0)) == OTERR_Success))
				{
// TetiSoft: We MUST test the y direction, or we would write beyond our Template memory
					if (((baseline - glyph->glm_Y0 + glyph->glm_BlackTop) >= 0) &&
					    ((baseline - glyph->glm_Y0 + glyph->glm_BlackTop + glyph->glm_BlackHeight) <= charheight))
					{
						CopyMem(glyph->glm_BitMap, Template, glyph->glm_BMModulo * glyph->glm_BMRows);
						if ((glyph->glm_BlackWidth != 0) || (glyph->glm_BlackHeight != 0))
						{
							if ((glyph->glm_BlackLeft + glyph->glm_BlackWidth - glyph->glm_X0) > charwidth)
							{
								didfith = FALSE;
								RectFill(rp, x, y - baseline, x + (charwidth - 1), (y - baseline) + (charheight -1));
								WaitBlit();
							}
							BltTemplate( ((char *) Template) + (glyph->glm_BlackTop * glyph->glm_BMModulo) + (glyph->glm_BlackLeft >> 3),
								glyph->glm_BlackLeft & 0xf,
								glyph->glm_BMModulo,
								rp,
								x - glyph->glm_X0 + glyph->glm_BlackLeft,
								y - glyph->glm_Y0 + glyph->glm_BlackTop,
								glyph->glm_BlackWidth,
								glyph->glm_BlackHeight);
							WaitBlit();
						}
					} else {
						didfitv = FALSE;
						RectFill(rp, x, y - baseline, x + (charwidth - 1), (y - baseline) + (charheight -1));
						WaitBlit();
					}
					ReleaseInfo(engine, OT_GlyphMap, glyph, TAG_DONE, 0);
				}
				x += (charwidth + 3);
			}
			y += (charheight + 3);
		}
		WaitBlit();
		FreeRaster(Template, width, charheight);
		SetDrMd(rp, drawmodestorage);
		SetFont(rp, fontstorage);
	}
	*didvertfit = didfitv;
	*didhorfit = didfith;
	return TRUE;
}

static BOOL create_enc_window(int bmwidth, int bmheight)
{
	char *s;

	window_obj_enc = WindowObject,
		MUIA_Window_ID, MAKE_ID('E','N','C','O'),
		MUIA_Window_Width, bmwidth + 14,	// approx., only for the first opening
		MUIA_Window_Height, bmheight + 32,	// approx., only for the first opening
		MUIA_Background, MUII_WindowBack,
		WindowContents, VGroup,
			Child, HGroup,
			MUIA_Group_Columns, 2,
				Child, Label1(LString(MSG_PAGE_LABEL)),
				Child, cycle_obj_unipg = CycleObject,
					MUIA_Font, MUIV_Font_Button,
					MUIA_Cycle_Entries, Pages,
					MUIA_ShortHelp, LString(MSG_PAGES_HELP),
					End,
				Child, Label1(LString(MSG_PAGEDESC_LABEL)),
				Child, txt_obj_unipg = TextObject,
					TextFrame,
					MUIA_Background, MUII_TextBack,
					MUIA_Text_Contents, "\n\n\n",	// max 4 lines description
					MUIA_ShortHelp, LString(MSG_PAGEDESC_HELP),
					End,
				End,
			Child, bm_obj_enc = BitmapObject,
				TextFrame,
				MUIA_ShortHelp, LString(MSG_ENCODING_TABLE_HELP),
				End,
			End,
		End;
	if (!window_obj_enc) {
		MyErrorMsg(LString(MSG_ERROR_CREATE_ENC_WINDOW));
		return FALSE;
	}
// Set up keyboard shortcut if the localized label contain a '_'
	if ((s = strchr(LString(MSG_PAGE_LABEL), '_')) && s[1])
		set(cycle_obj_unipg, MUIA_ControlChar, tolower(s[1]));
	DoMethod(cycle_obj_unipg, MUIM_Notify, MUIA_Cycle_Active,	 MUIV_EveryTime, app_obj, 2, MUIM_Application_ReturnID, ID_ENC_PAGE );
	DoMethod(window_obj_enc,  MUIM_Notify, MUIA_Window_CloseRequest, TRUE,		 app_obj, 2, MUIM_Application_ReturnID, ID_ENC_CLOSE);
	return TRUE;
}

static void close_enc_window(void)
{
	if (enc_window_open)
	{
		set(window_obj_enc, MUIA_Window_Open, FALSE);
		enc_window_open = FALSE;
		DoMethod(app_obj, OM_REMMEMBER, window_obj_enc);
		MUI_DisposeObject(window_obj_enc);
	}
}

static BOOL update_enc_window(char *FontName)
{
	int glyphcode;
	struct GlyphMap *glyph;
	LONG width, height;
	BOOL erasebitmap;
	int rc;
	int pixelheight, ptheight;
	int pixelwidth, fixedwidth = 0;
	struct RastPort rp;
	int BaseLine;
	struct TextFont *TF;
	BOOL didhorfit;
	BOOL didvertfit;
	ULONG firstglyph;

	if (!Type1Base || !engine)
		return FALSE;
	if (!ModifyPresets.SpaceWidth && ModifyPresets.IsFixed)
		return FALSE;
	if (!(ModifyPresets.YSizeFactor & 0xffff0000) || !(ModifyPresets.YSizeFactor & 0xffff))
		return FALSE;

	TF = GfxBase->DefaultFont;

	if (!enc_window_open)
	{
		if (!GetUnicodeArray(ModifyPresets.Type1FileName))
			return FALSE;	// Pages not initialized
		if (!create_enc_window(13 * 16 + 3 * 16 + 4 + 9 * TF->tf_XSize, 18 * 16 + 3 * 15 + 4))	// assume 13 * 18 font for first opening
			return FALSE;
		DoMethod(app_obj, OM_ADDMEMBER, window_obj_enc);
		set(window_obj_enc, MUIA_Window_Open, TRUE);
		enc_window_open = TRUE;
	}

	if (ModifyPresets.SymbolSet == UNICODE)
	{
		int page, valid, index;
		set(cycle_obj_unipg, MUIA_Disabled, FALSE);
		get(cycle_obj_unipg, MUIA_Cycle_Active, &index);
		for (page = 0, valid = 0; page < 256; page++)
		{
			if (UnicodePages[page])
			{
				if (valid == index)
					break;
				valid++;
			}
		}
		if (page >= 256)
			page = 0;
		firstglyph = page * 256;
		set(txt_obj_unipg, MUIA_Text_Contents, PageStrings[page]);
	} else {
		SetAttrs(cycle_obj_unipg, MUIA_NoNotify, TRUE, MUIA_Cycle_Active, 0, MUIA_Disabled, TRUE, TAG_DONE, 0);	// only first page
		firstglyph = 0;
		set(txt_obj_unipg, MUIA_Text_Contents, "");
	}
	get(bm_obj_enc, MUIA_Height, &encpreviewheight);
	pixelheight = (encpreviewheight - (3 * 15 + 4)) / 16;
	if (TF->tf_YSize > pixelheight)
		pixelheight = TF->tf_YSize;

	height = pixelheight * 16 + 3 * 15 + 4;

	ptheight = (pixelheight * (ModifyPresets.YSizeFactor >> 16)) / (ModifyPresets.YSizeFactor & 0xffff);

	if (ModifyPresets.IsFixed)
		fixedwidth = (ModifyPresets.SpaceWidth * ptheight * 72) / (2540 * 250);

	if (!engine && ((engine = OpenEngine()) == NULL))
	{
		MyErrorMsg(LString(MSG_ERROR_OPEN_ENGINE));
		close_enc_window();
		return FALSE;
	}
	if ((rc = SetInfo(engine, OT_SpecCount, 1,
				  OT_Spec1_PFABFileName, ModifyPresets.Type1FileName,
				  OT_SymbolSet, ModifyPresets.SymbolSet,
				  OT_IsFixed, ModifyPresets.IsFixed,
				  OT_SpaceWidth, ModifyPresets.SpaceWidth,
				  OT_DeviceDPI, (72 << 16) | 72,
				  OT_PointHeight, ptheight << 16,
				  TAG_DONE, 0
			 )) == OTERR_Success)
	{
		int cw;
		int Ascend, maxAscend = 0;
		int Descend, maxDescend = 0;
		pixelwidth = 0;
		for (glyphcode = firstglyph; glyphcode < (firstglyph + 256); glyphcode++)
		{
			if ((SetInfo(engine, OT_GlyphCode, glyphcode, TAG_DONE, 0) == OTERR_Success) &&
			    (ObtainInfo(engine, OT_GlyphMap, &glyph, TAG_DONE, 0) == OTERR_Success))
			{
				cw =  glyph->glm_BlackLeft + glyph->glm_BlackWidth - glyph->glm_X0;
				if (cw > pixelwidth)
					pixelwidth = cw;
				Ascend = glyph->glm_Y0 - glyph->glm_BlackTop;
				if (Ascend > maxAscend)
					maxAscend = Ascend;
				Descend = glyph->glm_BlackTop + glyph->glm_BlackHeight - glyph->glm_Y0;
				if (Descend > maxDescend)
					maxDescend = Descend;
				ReleaseInfo(engine, OT_GlyphMap, glyph, TAG_DONE, 0);
			}
		}
		BaseLine = (pixelheight + maxAscend - maxDescend) / 2;
	} else {
//		CloseEngine(engine);
		close_enc_window();
		MyErrorMsg2(LString(MSG_ERROR_BUILD_ENC_PREVIEW), rc, ModifyPresets.Type1FileName);
		return FALSE;
	}

	width  = (fixedwidth ? fixedwidth : pixelwidth) * 16 + 3 * 15 + 4 + 9 * TF->tf_XSize;

	if ((encbitmap != NULL) && ((encbmwidth != width) || (encbmheight != height)))
	{
		MyFreeBitMap(encbitmap, encbmwidth, encbmheight);
		encbitmap = NULL;
	}
		
	if (encbitmap == NULL)
	{
		encbitmap = MyAllocBitMap(width, height);
		encbmwidth = width;
		encbmheight = height;
		InitBitMap(encbitmap, 1, width, height);
		erasebitmap = FALSE;
	}
	else
		erasebitmap = TRUE;

	InitRastPort(&rp);
	rp.BitMap = encbitmap;
	if (erasebitmap) EraseRect(&rp, 0, 0, width-1, height-1);

	if (RenderEncoding(&rp, width, height, fixedwidth ? fixedwidth : pixelwidth, pixelheight, BaseLine, firstglyph, &didhorfit, &didvertfit))
	{
		int i;
//		CloseEngine(engine);
		switch (ModifyPresets.SymbolSet)
		{
			case UNICODE:
				i = 0;
				break;
			case STANDARDENCODING:
				i = 1;
				break;
			case CEENCODING:
				i = 2;
				break;
			case WINCYRILLICENCODING:
				i = 3;
				break;
			case WINLATIN1ENCODING:
				i = 4;
				break;
			case PSISOLATIN1ENCODING:
				i = 5;
				break;
			case ISOLATIN1ENCODING:
			default:
				i = 6;
				break;
			case ISOLATIN2ENCODING:
				i = 7;
				break;
			case ISOLATIN3ENCODING:
				i = 8;
				break;
			case ISOLATIN4ENCODING:
				i = 9;
				break;
			case ISOCYRILLICENCODING:
				i = 10;
				break;
			case ISOARABICENCODING:
				i = 11;
				break;
			case ISOGREEKENCODING:
				i = 12;
				break;
			case ISOHEBREWENCODING:
				i = 13;
				break;
			case ISOLATIN5ENCODING:
				i = 14;
				break;
			case ISOLATIN6ENCODING:
				i = 15;
				break;
			case ISOTHAIENCODING:
				i = 16;
				break;
			case ISOLATIN7ENCODING:
				i = 17;
				break;
			case ISOLATIN8ENCODING:
				i = 18;
				break;
			case ISOLATIN9ENCODING:
				i = 19;
				break;
			case KOI8RENCODING:
				i = 20;
				break;
			case E2ENCODING:
				i = 21;
				break;
			case BUILTINENCODING:
				i = 22;
				break;
		}
		sprintf(EncWinTitle, LString(MSG_ENCODING_TITLE), FontName,
				(i == NRENCODINGS) ? LString(MSG_ENC_TITLE_INTERNAL) : SymbolSets[i],
				pixelheight, ptheight);
		if (!didvertfit)
			strcat(EncWinTitle, LString(MSG_ENCODING_TITLE_ADD_YSIZEFACTOR));
		if (!didhorfit)
			strcat(EncWinTitle, LString(MSG_ENCODING_TITLE_ADD_SPACEWIDTH));
		set(window_obj_enc, MUIA_Window_Title, EncWinTitle);
		SetAttrs(bm_obj_enc,
			MUIA_Bitmap_Width, encbmwidth,
			MUIA_Bitmap_Height, encbmheight,
			MUIA_Bitmap_Bitmap, encbitmap,
			TAG_DONE, 0);
		return TRUE;
	}
//	CloseEngine(engine);
	return FALSE;
}

static void SizeStringChange(void)
{
	LONG size;
	int i, sizeexists = FALSE;
	get(string_obj_sizes, MUIA_String_Integer, &size);
	for(i=0; i < ModifyPresets.AvailSizes.Count; i++)
	{
		if (size == ModifyPresets.AvailSizes.Sizes[i])
		{
			sizeexists = TRUE;
			break;
		}
	}
	if (sizeexists)
	{
		int bmexists = FALSE;
		for(i=0; i < WantedBMSizes.Count; i++)
		{
			if (size == WantedBMSizes.Sizes[i])
			{
				bmexists = TRUE;
				break;
			}
		}
		set(button_obj_addsize, MUIA_Disabled, TRUE);
		set(button_obj_delsize, MUIA_Disabled, FALSE);
		if (bmexists)
		{
			set(button_obj_addbm, MUIA_Disabled, TRUE);
			set(button_obj_delbm, MUIA_Disabled, FALSE);
		}
		else
		{
			set(button_obj_addbm, MUIA_Disabled, FALSE);
			set(button_obj_delbm, MUIA_Disabled, TRUE);
		}
	}
	else
	{
		set(button_obj_delsize, MUIA_Disabled, TRUE);
		set(button_obj_addbm, MUIA_Disabled, TRUE);
		set(button_obj_delbm, MUIA_Disabled, TRUE);
		if ((size >= 2) && (size <= 124) && (ModifyPresets.AvailSizes.Count < OT_MAXAVAILSIZES))
			set(button_obj_addsize, MUIA_Disabled, FALSE);
		else
			set(button_obj_addsize, MUIA_Disabled, TRUE);
	}
}

static BOOL DidChange(void)
{
	int i;
	struct OTagValues *O =&OTagPresets;
	struct OTagValues *M =&ModifyPresets;

	if (M->IsFixed)
	{
		set (string_obj_afm, MUIA_Disabled, TRUE);
		set (pop_obj_afm, MUIA_Disabled, TRUE);
	} else {
		set (string_obj_afm, MUIA_Disabled, FALSE);
		set (pop_obj_afm, MUIA_Disabled, FALSE);
	}
/*
	if ((O->IsFixed != M->IsFixed) ||
	    (O->SlantStyle != M->SlantStyle) ||
	    (O->StemWeight != M->StemWeight) ||
	    (O->SymbolSet != M->SymbolSet) ||
	    (O->YSizeFactor != M->YSizeFactor) ||
	    (M->IsFixed && (O->SpaceWidth != M->SpaceWidth)))
	{
		set (lv_obj_sizes, MUIA_Disabled, TRUE);
		set (string_obj_sizes, MUIA_Disabled, TRUE);
		set (button_obj_addsize, MUIA_Disabled, TRUE);
		set (button_obj_delsize, MUIA_Disabled, TRUE);
		set (button_obj_addbm, MUIA_Disabled, TRUE);
		set (button_obj_delbm, MUIA_Disabled, TRUE);
	} else {
		set (lv_obj_sizes, MUIA_Disabled, FALSE);
		set (string_obj_sizes, MUIA_Disabled, FALSE);
		SizeStringChange();
	}
*/
	if (!O->SpaceWidth || !O->YSizeFactor || !O->SymbolSet)	// Old .otag file from old T1Manager
	{
		set (button_obj_save, MUIA_Disabled, FALSE);
		return TRUE;
	}
	if ((O->SerifFlag != M->SerifFlag) ||
	    (O->StemWeight != M->StemWeight) ||
	    (O->HorizStyle != M->HorizStyle) ||
	    (O->IsFixed != M->IsFixed) ||
	    (O->SlantStyle != M->SlantStyle) ||
	    (O->SpaceWidth != M->SpaceWidth) ||
	    (O->YSizeFactor != M->YSizeFactor) ||
	    (O->InhibitAlgoStyle != M->InhibitAlgoStyle) ||
	    (O->SymbolSet != M->SymbolSet) ||
	    (O->SpaceFactor != M->SpaceFactor) ||
	    (O->OwnEncoding != M->OwnEncoding) ||
	    strcmp(O->FamilyName, M->FamilyName) ||
	    strcmp(O->BoldName, M->BoldName) ||
	    strcmp(O->ItalicName, M->ItalicName) ||
	    strcmp(O->BoldItalicName, M->BoldItalicName) ||
	    strcmp(O->OTagFileName, M->OTagFileName) ||
	    strcmp(O->Type1FileName, M->Type1FileName) ||
	    strcmp(O->AFMFileName, M->AFMFileName) ||
	    (O->AvailSizes.Count != M->AvailSizes.Count) ||
	    (AvailBMSizes.Count != WantedBMSizes.Count))
	{
		set (button_obj_save, MUIA_Disabled, FALSE);
		return TRUE;
	}
	for (i = 0; i < O->AvailSizes.Count; i++)
	{
		if (O->AvailSizes.Sizes[i] != M->AvailSizes.Sizes[i])
		{
			set (button_obj_save, MUIA_Disabled, FALSE);
			return TRUE;
		}
	}
	for (i = 0; i < AvailBMSizes.Count; i++)
	{
		if (AvailBMSizes.Sizes[i] != WantedBMSizes.Sizes[i])
		{
			set (button_obj_save, MUIA_Disabled, FALSE);
			return TRUE;
		}
	}
	set (button_obj_save, MUIA_Disabled, TRUE);
	return FALSE;
}

static BOOL create_modify_window(char *filename)
{
	char *s;
	static int Localized = FALSE;

	if (!Localized)
	{
		Widths[0]     = LString(MSG_WIDTH_PROPORTIONAL);
		Widths[1]     = LString(MSG_WIDTH_FIXED);

		Slants[0]     = LString(MSG_SLANT_UPRIGHT);
		Slants[1]     = LString(MSG_SLANT_ITALIC);
		Slants[2]     = LString(MSG_SLANT_LEFTITALIC);

		Serifs[0]     = LString(MSG_SERIFS_SERIF);
		Serifs[1]     = LString(MSG_SERIFS_SANSSERIF);

		Weights[0]    = LString(MSG_WEIGHT_ULTRATHIN);
		Weights[1]    = LString(MSG_WEIGHT_EXTRATHIN);
		Weights[2]    = LString(MSG_WEIGHT_THIN);
		Weights[3]    = LString(MSG_WEIGHT_EXTRALIGHT);
		Weights[4]    = LString(MSG_WEIGHT_LIGHT);
		Weights[5]    = LString(MSG_WEIGHT_DEMILIGHT);
		Weights[6]    = LString(MSG_WEIGHT_SEMILIGHT);
		Weights[7]    = LString(MSG_WEIGHT_BOOK);
		Weights[8]    = LString(MSG_WEIGHT_MEDIUM);
		Weights[9]    = LString(MSG_WEIGHT_SEMIBOLD);
		Weights[10]   = LString(MSG_WEIGHT_DEMIBOLD);
		Weights[11]   = LString(MSG_WEIGHT_BOLD);
		Weights[12]   = LString(MSG_WEIGHT_EXTRABOLD);
		Weights[13]   = LString(MSG_WEIGHT_BLACK);
		Weights[14]   = LString(MSG_WEIGHT_EXTRABLACK);
		Weights[15]   = LString(MSG_WEIGHT_ULTRABLACK);

		HStyles[0]    = LString(MSG_HORIZSTYLE_ULTRACOMPRESSED);
		HStyles[1]    = LString(MSG_HORIZSTYLE_EXTRACOMPRESSED);
		HStyles[2]    = LString(MSG_HORIZSTYLE_COMPRESSED);
		HStyles[3]    = LString(MSG_HORIZSTYLE_CONDENSED);
		HStyles[4]    = LString(MSG_HORIZSTYLE_NORMAL);
		HStyles[5]    = LString(MSG_HORIZSTYLE_SEMIEXPANDED);
		HStyles[6]    = LString(MSG_HORIZSTYLE_EXPANDED);
		HStyles[7]    = LString(MSG_HORIZSTYLE_EXTRAEXPANDED);

		SymbolSets[0] = LString(MSG_SYMBOLSET_UNICODE);
		SymbolSets[1] = LString(MSG_SYMBOLSET_STANDARD);
		SymbolSets[2] = LString(MSG_SYMBOLSET_CE);
		SymbolSets[3] = LString(MSG_SYMBOLSET_WINCYR);
		SymbolSets[4] = LString(MSG_SYMBOLSET_WINL1);
		SymbolSets[5] = LString(MSG_SYMBOLSET_PSISOL1);
		SymbolSets[6] = LString(MSG_SYMBOLSET_ISOL1);
		SymbolSets[7] = LString(MSG_SYMBOLSET_ISOL2);
		SymbolSets[8] = LString(MSG_SYMBOLSET_ISOL3);
		SymbolSets[9] = LString(MSG_SYMBOLSET_ISOL4);
		SymbolSets[10] = LString(MSG_SYMBOLSET_ISOCYRILLIC);
		SymbolSets[11] = LString(MSG_SYMBOLSET_ISOARABIC);
		SymbolSets[12] = LString(MSG_SYMBOLSET_ISOGREEK);
		SymbolSets[13] = LString(MSG_SYMBOLSET_ISOHEBREW);
		SymbolSets[14] = LString(MSG_SYMBOLSET_ISOL5);
		SymbolSets[15] = LString(MSG_SYMBOLSET_ISOL6);
		SymbolSets[16] = LString(MSG_SYMBOLSET_ISOTHAI);
		SymbolSets[17] = LString(MSG_SYMBOLSET_ISOL7);
		SymbolSets[18] = LString(MSG_SYMBOLSET_ISOL8);
		SymbolSets[19] = LString(MSG_SYMBOLSET_ISOL9);
		SymbolSets[20] = LString(MSG_SYMBOLSET_KOI8R);
		SymbolSets[21] = LString(MSG_SYMBOLSET_E2);

		Localized = TRUE;
	}

	window_obj_modify = WindowObject,
		MUIA_Window_ID, MAKE_ID('M','O','D','I'),
		MUIA_Window_Title, filename,
//		MUIA_Window_Menu, MUIV_Window_Menu_NoMenu,
		MUIA_Background, MUII_WindowBack,
		WindowContents, VGroup,
			Child, HGroup,
				Child, VGroup,
					GroupFrameT(LString(MSG_ATTRIB_GROUP_LABEL)),
					MUIA_Group_Columns, 2,
					Child, Label1(LString(MSG_WIDTH_LABEL)), Child, cycle_obj_fixed = Cycle(Widths),
					Child, Label1(LString(MSG_SLANT_LABEL)), Child, cycle_obj_slant = Cycle(Slants),
					Child, Label1(LString(MSG_SERIFS_LABEL)), Child, cycle_obj_serif = Cycle(Serifs),
					Child, Label1(LString(MSG_WEIGHT_LABEL)), Child, cycle_obj_weight = Cycle(Weights),
					Child, Label1(LString(MSG_HORIZSTYLE_LABEL)), Child, cycle_obj_hstyle = Cycle(HStyles),
/*
					Child, Label1(LString(MSG_SYMBOLSET_LABEL)),
					Child, lv_obj_symset = ListviewObject,
						MUIA_Listview_Input, TRUE,
						MUIA_Background, MUII_ListBack,
						MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None,
						MUIA_Listview_List, ListObject,
							ReadListFrame,
							MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
							MUIA_List_DestructHook, MUIV_List_DestructHook_String,
							MUIA_List_AdjustWidth, TRUE,
							MUIA_List_AutoVisible, TRUE,
							MUIA_List_SourceArray, SymbolSets,
							End,
						End,
*/
					Child, Label1(LString(MSG_SYMBOLSET_LABEL)),
					Child, VGroup, GroupFrame,
						Child, HGroup,
							Child, check_obj_symset = CheckMark(FALSE),
							Child, Label1(LString(MSG_SYMBOLSET_INTERNAL)),
							End,
						Child, cycle_obj_symset = Cycle(SymbolSets),
						Child, button_obj_symset = SimpleButton(LString(MSG_SYMBOLSET_GAD)),
						End,
					Child, Label2(LString(MSG_SPACEWIDTH_LABEL)), Child, string_obj_spacew = StringObject, MUIA_String_Accept, "0123456879", MUIA_String_MaxLen, 6, StringFrame, End,
					Child, Label1(LString(MSG_YSIZEFACTOR_LABEL)),
					Child, group_obj_ysizef = ColGroup(2), GroupFrame,
						Child, Label2(LString(MSG_POINTHEIGHT_LABEL)), Child, string_obj_ysizefph = StringObject, StringFrame, MUIA_String_Accept, "0123456879", MUIA_String_MaxLen, 6, End,
						Child, Label2(LString(MSG_BLACKHEIGHT_LABEL)), Child, string_obj_ysizefbh = StringObject, StringFrame, MUIA_String_Accept, "0123456879", MUIA_String_MaxLen, 6, End,
						End,
					End,
				Child, VGroup,
#ifdef INHIBITALGO
					Child, ColGroup(2),
						GroupFrameT(LString(MSG_INHIBITALGO_LABEL)),
						Child, Label1(LString(MSG_INHIBITBOLD_LABEL)), Child, check_obj_bold = CheckMark(TRUE),
						Child, Label1(LString(MSG_INHIBITITALIC_LABEL)), Child, check_obj_italic = CheckMark(FALSE),
						Child, Label1(LString(MSG_INHIBITEXTENDED_LABEL)), Child, check_obj_extend = CheckMark(TRUE),
						Child, Label1(LString(MSG_INHIBITUNDERLINED_LABEL)), Child, check_obj_underl = CheckMark(TRUE),
						End,
					Child, VGroup,
#endif
						GroupFrameT(LString(MSG_SIZES_GROUP_LABEL)),
						Child, lv_obj_sizes = ListviewObject,
							MUIA_Listview_Input, TRUE,
							MUIA_Background, MUII_ListBack,
							MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Default,
							MUIA_Listview_List, ListObject,
								ReadListFrame,
								MUIA_List_Format, ",",
								MUIA_List_DisplayHook, &H_SizesDisp,
								MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
								MUIA_List_DestructHook, MUIV_List_DestructHook_String,
								End,
							End,
						Child, ColGroup(2),
							Child, Label2(LString(MSG_SIZE_LABEL)),
							Child, string_obj_sizes = StringObject, StringFrame, MUIA_String_Accept, "0123456879", End,
							End,
						Child, button_obj_addsize = SimpleButton(LString(MSG_ADDSIZE_LABEL)),
						Child, button_obj_delsize = SimpleButton(LString(MSG_DELSIZE_LABEL)),
						Child, button_obj_addbm = SimpleButton(LString(MSG_ADDBITMAP_LABEL)),
						Child, button_obj_delbm = SimpleButton(LString(MSG_DELBITMAP_LABEL)),
#ifdef INHIBITALGO
						End,
#endif
					End,
				End,
#ifdef FAMILYNAMES
			Child, VGroup,
				GroupFrameT(LString(MSG_FAMILY_GROUP_LABEL)),
				MUIA_Group_Columns, 2,
				Child, Label2(LString(MSG_FAMILYNAME_LABEL)),
					Child, string_obj_family = StringObject,
						StringFrame,
						MUIA_String_MaxLen, 100,
						End,
				Child, Label2(LString(MSG_BOLDNAME_LABEL)),
					Child, PopaslObject,
						MUIA_Popasl_Type, ASL_FontRequest,
						MUIA_Popstring_String, string_obj_bname = String(0, MAXFONTNAME - 6),
						MUIA_Popstring_Button, PopButton(MUII_PopFile),
						ASLFO_TitleText, LString(MSG_BOLDNAME_FILEREQ_TITLE),
						End,
				Child, Label2(LString(MSG_ITALICNAME_LABEL)),
					Child, PopaslObject,
						MUIA_Popasl_Type, ASL_FontRequest,
						MUIA_Popstring_String, string_obj_iname = String(0, MAXFONTNAME - 6),
						MUIA_Popstring_Button, PopButton(MUII_PopFile),
						ASLFO_TitleText, LString(MSG_ITALICNAME_FILEREQ_TITLE),
						End,
				Child, Label2(LString(MSG_BOLDITALICNAME_LABEL)),
					Child, PopaslObject,
						MUIA_Popasl_Type, ASL_FontRequest,
						MUIA_Popstring_String, string_obj_biname = String(0, MAXFONTNAME - 6),
						MUIA_Popstring_Button, PopButton(MUII_PopFile),
						ASLFO_TitleText, LString(MSG_BOLDITALICNAME_FILERQ_TITLE),
						End,
				End,
#endif
			Child, group_obj_files = ColGroup(2),
				GroupFrameT(LString(MSG_FILES_GROUP_LABEL)),
				Child, Label2(LString(MSG_TYPE1FILE_LABEL)),
					Child, PopaslObject,
						MUIA_Popstring_String, string_obj_type1 = String(0, MAXFONTPATH),
						MUIA_Popstring_Button, pop_obj_type1 = PopButton(MUII_PopFile),
						ASLFR_TitleText, LString(MSG_TYPE1FILE_FILEREQ_TITLE),
						ASLFR_DoPatterns, TRUE,
						ASLFR_InitialPattern, "#?.(pfa|pfb)",
						End,
				Child, Label2(LString(MSG_AFMFILE_LABEL)),
					Child, PopaslObject,
						MUIA_Popstring_String, string_obj_afm = String(0, MAXFONTPATH),
						MUIA_Popstring_Button, pop_obj_afm = PopButton(MUII_PopFile),
						ASLFR_TitleText, LString(MSG_AFMFILE_FILEREQ_TITLE),
						ASLFR_DoPatterns, TRUE,
						ASLFR_InitialPattern, "#?.afm",
						End,
				End,
			Child, VSpace(2),
			Child, HGroup,
				MUIA_Group_SameSize, TRUE,
				Child, button_obj_save = SimpleButton(LString(MSG_SAVE_GAD)),
				Child, HSpace(0),
				Child, button_obj_cancel = SimpleButton(LString(MSG_CANCEL_GAD)),
				End,
			End,
		End;

	/*** window failed ? ***/
	if (!window_obj_modify) {
		MyErrorMsg(LString(MSG_ERROR_CREATE_MOD_WINDOW));
		return FALSE;
	}

// TetiSoft: Set up keyboard shortcuts if the localized labels contain a '_'
	if ((s = strchr(LString(MSG_WIDTH_LABEL), '_')) && s[1])
		set(cycle_obj_fixed, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SLANT_LABEL), '_')) && s[1])
		set(cycle_obj_slant, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SERIFS_LABEL), '_')) && s[1])
		set(cycle_obj_serif, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_WEIGHT_LABEL), '_')) && s[1])
		set(cycle_obj_weight, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_HORIZSTYLE_LABEL), '_')) && s[1])
		set(cycle_obj_hstyle, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SYMBOLSET_INTERNAL), '_')) && s[1])
		set(check_obj_symset, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SYMBOLSET_LABEL), '_')) && s[1])
		set(cycle_obj_symset, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SPACEWIDTH_LABEL), '_')) && s[1])
		set(string_obj_spacew, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_POINTHEIGHT_LABEL), '_')) && s[1])
		set(string_obj_ysizefph, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_BLACKHEIGHT_LABEL), '_')) && s[1])
		set(string_obj_ysizefbh, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_SIZE_LABEL), '_')) && s[1])
		set(string_obj_sizes, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_TYPE1FILE_LABEL), '_')) && s[1])
		set(string_obj_type1, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_AFMFILE_LABEL), '_')) && s[1])
		set(string_obj_afm, MUIA_ControlChar, tolower(s[1]));

	/*** connections & cycle ***/

	DoMethod(window_obj_modify,	MUIM_Notify,	MUIA_Window_CloseRequest,	TRUE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_CANCEL	);

	DoMethod(cycle_obj_fixed,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_FIXED		);
	DoMethod(cycle_obj_slant,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SLANT		);
	DoMethod(cycle_obj_serif,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SERIF		);
	DoMethod(cycle_obj_weight,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_WEIGHT	);
	DoMethod(cycle_obj_hstyle,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_HSTYLE	);
//	DoMethod(lv_obj_symset,		MUIM_Notify,	MUIA_List_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SYMSET	);
	DoMethod(check_obj_symset,	MUIM_Notify,	MUIA_Selected,			MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SYMSET	);
	DoMethod(cycle_obj_symset,	MUIM_Notify,	MUIA_Cycle_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SYMSET	);
//	DoMethod(lv_obj_symset,		MUIM_Notify,	MUIA_Listview_DoubleClick,	TRUE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SHOWSYMSET	);
	DoMethod(button_obj_symset,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SHOWSYMSET	);

	DoMethod(string_obj_spacew,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SPACEW	);
	DoMethod(string_obj_ysizefph,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_YSIZEFPH	);
	DoMethod(string_obj_ysizefbh,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_YSIZEFBH	);
#ifdef INHIBITALGO
	DoMethod(check_obj_bold,	MUIM_Notify,	MUIA_Selected,			MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_INHIBITALGO	);
	DoMethod(check_obj_italic,	MUIM_Notify,	MUIA_Selected,			MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_INHIBITALGO	);
	DoMethod(check_obj_extend,	MUIM_Notify,	MUIA_Selected,			MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_INHIBITALGO	);
	DoMethod(check_obj_underl,	MUIM_Notify,	MUIA_Selected,			MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_INHIBITALGO	);
#endif
	DoMethod(lv_obj_sizes,		MUIM_Notify,	MUIA_List_Active,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SELSIZECHANGE	);
	DoMethod(string_obj_sizes,	MUIM_Notify,	MUIA_String_Contents,		MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SIZECHANGE	);
	DoMethod(button_obj_addsize,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_ADDSIZE	);
	DoMethod(button_obj_delsize,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_DELSIZE	);
	DoMethod(button_obj_addbm,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_ADDBM		);
	DoMethod(button_obj_delbm,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_DELBM		);
#ifdef FAMILYNAMES
	DoMethod(string_obj_family,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_FAMILY	);
	DoMethod(string_obj_bname,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_BNAME		);
	DoMethod(string_obj_iname,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_INAME		);
	DoMethod(string_obj_biname,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_BINAME	);
#endif
	DoMethod(string_obj_type1,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_TYPE1FILE	);
	DoMethod(string_obj_afm,	MUIM_Notify,	MUIA_String_Acknowledge,	MUIV_EveryTime,	app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_AFMFILE	);

	DoMethod(button_obj_save,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_SAVE		);
	DoMethod(button_obj_cancel,	MUIM_Notify,	MUIA_Pressed,			FALSE,		app_obj,	2,	MUIM_Application_ReturnID,	ID_MODIFY_CANCEL	);

	set (cycle_obj_fixed, MUIA_ShortHelp,	LString(MSG_WIDTH_HELP));
	set (cycle_obj_slant, MUIA_ShortHelp,	LString(MSG_SLANT_HELP));
	set (cycle_obj_serif, MUIA_ShortHelp,	LString(MSG_SERIFS_HELP));
	set (cycle_obj_weight, MUIA_ShortHelp,	LString(MSG_WEIGHT_HELP));
	set (cycle_obj_hstyle, MUIA_ShortHelp,	LString(MSG_HORIZSTYLE_HELP));
//	set (lv_obj_symset, MUIA_ShortHelp,	LString(MSG_SYMBOLSET_HELP));
	set (check_obj_symset, MUIA_ShortHelp,	LString(MSG_SYMBOLINT_HELP));
	set (cycle_obj_symset, MUIA_ShortHelp,	LString(MSG_SYMBOLSET_HELP));
	set (button_obj_symset, MUIA_ShortHelp,	LString(MSG_SYMBOLSHOW_HELP));
	set (string_obj_spacew, MUIA_ShortHelp,	LString(MSG_SPACEWIDTH_HELP));
	set (group_obj_ysizef, MUIA_ShortHelp,	LString(MSG_YSIZEFACTOR_HELP));
	set (lv_obj_sizes, MUIA_ShortHelp,	LString(MSG_SIZES_LIST_HELP));
	set (string_obj_sizes, MUIA_ShortHelp,	LString(MSG_SIZE_HELP));
	set (button_obj_addsize, MUIA_ShortHelp,LString(MSG_ADDSIZE_HELP));
	set (button_obj_delsize, MUIA_ShortHelp,LString(MSG_DELSIZE_HELP));
	set (button_obj_addbm, MUIA_ShortHelp,	LString(MSG_ADDBITMAP_HELP));
	set (button_obj_delbm, MUIA_ShortHelp,	LString(MSG_DELBITMAP_HELP));
	set (string_obj_type1, MUIA_ShortHelp,	LString(MSG_TYPE1FILE_HELP));
	set (pop_obj_type1, MUIA_ShortHelp,	LString(MSG_TYPE1FILE_POPUP_HELP));
	set (string_obj_afm, MUIA_ShortHelp,	LString(MSG_AFMFILE_HELP));
	set (pop_obj_afm, MUIA_ShortHelp,	LString(MSG_AFMFILE_POPUP_HELP));
	set (button_obj_save, MUIA_ShortHelp,	LString(MSG_SAVE_HELP));
	set (button_obj_cancel, MUIA_ShortHelp,	LString(MSG_CANCEL_HELP));

	set (button_obj_addsize, MUIA_Disabled, TRUE);
	set (button_obj_delsize, MUIA_Disabled, TRUE);
	set (button_obj_addbm, MUIA_Disabled, TRUE);
	set (button_obj_delbm, MUIA_Disabled, TRUE);

	set(string_obj_sizes, MUIA_String_AttachedList, lv_obj_sizes);

// To fit on NTSC screen some objects must be allowed to disappear...
//	set (string_obj_afm, MUIA_VertDisappear, 2);
//	set (pop_obj_afm, MUIA_VertDisappear, 2);
//	set (string_obj_type1, MUIA_VertDisappear, 3);
//	set (pop_obj_type1, MUIA_VertDisappear, 3);
//	set (group_obj_files, MUIA_VertDisappear, 4);
//	set (cycle_obj_slant, MUIA_VertDisappear, 5);


	DoMethod(window_obj_modify, MUIM_Window_SetCycleChain,
		cycle_obj_fixed, cycle_obj_slant, cycle_obj_serif, cycle_obj_weight, cycle_obj_hstyle,
		/*lv_obj_symset,*/ check_obj_symset, cycle_obj_symset, button_obj_symset,
		string_obj_spacew, string_obj_ysizefph, string_obj_ysizefbh,
#ifdef INHIBITALGO
		check_obj_bold, check_obj_italic, check_obj_extend, check_obj_underl,
#endif
		lv_obj_sizes, string_obj_sizes, button_obj_addsize, button_obj_delsize, button_obj_addbm, button_obj_delbm,
#ifdef FAMILYNAMES
		string_obj_family, string_obj_bname, string_obj_iname, string_obj_biname,
#endif
		string_obj_type1, string_obj_afm,
		button_obj_save, button_obj_cancel,
		NULL);

	return TRUE;
}

static void close_modify_window(void)
{
	/*** close & remove window ***/
	set(window_obj_modify, MUIA_Window_Open, FALSE);
	DoMethod(app_obj, OM_REMMEMBER, window_obj_modify);
	MUI_DisposeObject(window_obj_modify);
	set (window_obj_main, MUIA_Window_Sleep, FALSE);
	mod_window_open = FALSE;
}

static BOOL open_modify_window(void)
{
	// TetiSoft: We assume that RenderPreview() has already read the .otag file
	struct TagItem *OTags = (struct TagItem *)OTagFileBuf;
	struct TagItem *tag;

	AvailBMSizes.Count = 0;
	DoAllAssigns(FontDirName, &ScanDir, &AddBitmapsToList);
	WantedBMSizes = AvailBMSizes;

	if (mod_window_open)
		return FALSE;
	if (!create_modify_window(ModifyPresets.OTagFileName))
		return FALSE;

	ModifyPresets.Type1FileName[0] = '\0';
	SetAttrs(cycle_obj_fixed,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     0,	TAG_DONE, 0);	// proportional
	SetAttrs(cycle_obj_slant,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     0,	TAG_DONE, 0);	// upright
	SetAttrs(cycle_obj_serif,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     0,	TAG_DONE, 0);	// serifs
	SetAttrs(cycle_obj_weight,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     7,	TAG_DONE, 0);	// book
	SetAttrs(cycle_obj_hstyle,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     4,	TAG_DONE, 0);	// normal
	SetAttrs(check_obj_symset,	MUIA_NoNotify, TRUE, MUIA_Disabled, TRUE,	TAG_DONE, 0);	// No internal encoding
	SetAttrs(cycle_obj_symset,	MUIA_NoNotify, TRUE, MUIA_Cycle_Active,     6,	TAG_DONE, 0);	// SymbolSet ISO 8859-1 Latin1
	SetAttrs(string_obj_spacew,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "0",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_ysizefph,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "0",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_ysizefbh,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "0",	TAG_DONE, 0);	// unknown
#ifdef INHIBITALGO
	SetAttrs(check_obj_bold,	MUIA_NoNotify, TRUE, MUIA_Selected, TRUE,	TAG_DONE, 0);	// boldening not supported
	SetAttrs(check_obj_italic,	MUIA_NoNotify, TRUE, MUIA_Selected, FALSE,	TAG_DONE, 0);	// slanting supported
	SetAttrs(check_obj_extend,	MUIA_NoNotify, TRUE, MUIA_Selected, TRUE,	TAG_DONE, 0);	// extending not supported
	SetAttrs(check_obj_underl,	MUIA_NoNotify, TRUE, MUIA_Selected, TRUE,	TAG_DONE, 0);	// underlining not supported
#endif
	SetAttrs(string_obj_sizes,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
#ifdef FAMILYNAMES
	SetAttrs(string_obj_family,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_bname,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_iname,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_biname,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
#endif
	SetAttrs(string_obj_type1,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown
	SetAttrs(string_obj_afm,	MUIA_NoNotify, TRUE, MUIA_String_Contents, "",	TAG_DONE, 0);	// unknown

	while(tag = NextTagItem(&OTags))
	{
		switch(tag->ti_Tag)	
		{
		case OT_FileIdent:
			break;
		case OT_Engine:
			break;
		case OT_Family:
			stccpy(ModifyPresets.FamilyName, (char *)tag->ti_Data, sizeof(ModifyPresets.FamilyName));
#ifdef FAMILYNAMES
			SetAttrs(string_obj_family,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.FamilyName, TAG_DONE, 0);
#endif
			break;
		case OT_BName:
			stccpy(ModifyPresets.BoldName, (char *)tag->ti_Data, sizeof(ModifyPresets.BoldName));
#ifdef FAMILYNAMES
			SetAttrs(string_obj_bname,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.BoldName, TAG_DONE, 0);
#endif
			break;
		case OT_IName:
			stccpy(ModifyPresets.ItalicName, (char *)tag->ti_Data, sizeof(ModifyPresets.ItalicName));
#ifdef FAMILYNAMES
			SetAttrs(string_obj_iname,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.ItalicName, TAG_DONE, 0);
#endif
			break;
		case OT_BIName:
			stccpy(ModifyPresets.BoldItalicName, (char *)tag->ti_Data, sizeof(ModifyPresets.BoldItalicName));
#ifdef FAMILYNAMES
			SetAttrs(string_obj_biname,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.BoldItalicName, TAG_DONE, 0);
#endif
			break;
		case OT_SymbolSet:
		{
			int i;
			ModifyPresets.SymbolSet = tag->ti_Data;
			switch (ModifyPresets.SymbolSet)
			{
				case UNICODE:
					i = 0;
					break;
				case STANDARDENCODING:
					i = 1;
					break;
				case CEENCODING:
					i = 2;
					break;
				case WINCYRILLICENCODING:
					i = 3;
					break;
				case WINLATIN1ENCODING:
					i = 4;
					break;
				case PSISOLATIN1ENCODING:
					i = 5;
					break;
				default:
					MyErrorMsg1(LString(MSG_ERROR_UNKNOWN_SYSMBOLSET), ModifyPresets.SymbolSet);
					/* fall through */
				case ISOLATIN1ENCODING:
					i = 6;
					break;
				case ISOLATIN2ENCODING:
					i = 7;
					break;
				case  ISOLATIN3ENCODING:
					i = 8;
					break;
				case  ISOLATIN4ENCODING:
					i = 9;
					break;
				case  ISOCYRILLICENCODING:
					i = 10;
					break;
				case  ISOARABICENCODING:
					i = 11;
					break;
				case  ISOGREEKENCODING:
					i = 12;
					break;
				case  ISOHEBREWENCODING:
					i = 13;
					break;
				case  ISOLATIN5ENCODING:
					i = 14;
					break;
				case  ISOLATIN6ENCODING:
					i = 15;
					break;
				case  ISOTHAIENCODING:
					i = 16;
					break;
				case  ISOLATIN7ENCODING:
					i = 17;
					break;
				case  ISOLATIN8ENCODING:
					i = 18;
					break;
				case  ISOLATIN9ENCODING:
					i = 19;
					break;
				case  KOI8RENCODING:
					i = 20;
					break;
				case  E2ENCODING:
					i = 21;
					break;
				case BUILTINENCODING:
					i = 22;
					SetAttrs(check_obj_symset, MUIA_NoNotify, TRUE, MUIA_Selected, TRUE, TAG_DONE, 0);
					set(check_obj_symset, MUIA_Disabled, FALSE);
					set(cycle_obj_symset, MUIA_Disabled, TRUE);
					break;
			}
			if (i < NRENCODINGS)
				SetAttrs(cycle_obj_symset, MUIA_NoNotify, TRUE, MUIA_Cycle_Active, i, TAG_DONE, 0);
			break;
		}
		case OT_YSizeFactor:
		{
			ModifyPresets.YSizeFactor = tag->ti_Data;
			SetAttrs(string_obj_ysizefph,  MUIA_NoNotify, TRUE, MUIA_String_Integer, ModifyPresets.YSizeFactor >> 16, TAG_DONE, 0);
			SetAttrs(string_obj_ysizefbh,  MUIA_NoNotify, TRUE, MUIA_String_Integer, ModifyPresets.YSizeFactor & 0xffff, TAG_DONE, 0);
			break;
		}
		case OT_SpaceWidth:
			ModifyPresets.SpaceWidth = tag->ti_Data;
			SetAttrs(string_obj_spacew,  MUIA_NoNotify, TRUE, MUIA_String_Integer, ModifyPresets.SpaceWidth, TAG_DONE, 0);
			break;
		case OT_IsFixed:
			ModifyPresets.IsFixed = tag->ti_Data;
			SetAttrs(cycle_obj_fixed,  MUIA_NoNotify, TRUE, MUIA_Cycle_Active, ModifyPresets.IsFixed ? 1 : 0, TAG_DONE, 0);
			break;
		case OT_SerifFlag:
			ModifyPresets.SerifFlag = tag->ti_Data;
			SetAttrs(cycle_obj_serif,  MUIA_NoNotify, TRUE, MUIA_Cycle_Active, ModifyPresets.SerifFlag ? 0 : 1, TAG_DONE, 0);
			break;
		case OT_StemWeight:
		{
			int index;

			ModifyPresets.StemWeight = tag->ti_Data;
			if (tag->ti_Data <= 15)
				index = 0;
			else if (tag->ti_Data <= 31)
				index = 1;
			else if (tag->ti_Data <= 47)
				index = 2;
			else if (tag->ti_Data <= 63)
				index = 3;
			else if (tag->ti_Data <= 79)
				index = 4;
			else if (tag->ti_Data <= 95)
				index = 5;
			else if (tag->ti_Data <= 111)
				index = 6;
			else if (tag->ti_Data <= 127)
				index = 7;
			else if (tag->ti_Data <= 143)
				index = 8;
			else if (tag->ti_Data <= 159)
				index = 9;
			else if (tag->ti_Data <= 175)
				index = 10;
			else if (tag->ti_Data <= 191)
				index = 11;
			else if (tag->ti_Data <= 207)
				index = 12;
			else if (tag->ti_Data <= 223)
				index = 13;
			else if (tag->ti_Data <= 239)
				index = 14;
			else
				index = 15;
			SetAttrs(cycle_obj_weight, MUIA_NoNotify, TRUE, MUIA_Cycle_Active, index, TAG_DONE, 0);
			break;
		}
		case OT_SlantStyle:
			ModifyPresets.SlantStyle = tag->ti_Data;
			SetAttrs(cycle_obj_slant, MUIA_NoNotify, TRUE, MUIA_Cycle_Active, tag->ti_Data, TAG_DONE, 0);
			break;
		case OT_HorizStyle:
		{
			int index;

			ModifyPresets.HorizStyle = tag->ti_Data;
			if (tag->ti_Data <= 31)
				index = 0;
			else if (tag->ti_Data <= 63)
				index = 1;
			else if (tag->ti_Data <= 95)
				index = 2;
			else if (tag->ti_Data <= 127)
				index = 3;
			else if (tag->ti_Data <= 159)
				index = 4;
			else if (tag->ti_Data <= 191)
				index = 5;
			else if (tag->ti_Data <= 223)
				index = 6;
			else
				index = 7;
			SetAttrs(cycle_obj_hstyle, MUIA_NoNotify, TRUE, MUIA_Cycle_Active, index, TAG_DONE, 0);
			break;
		}
		case OT_SpaceFactor:
			ModifyPresets.SpaceFactor = tag->ti_Data;
			break;
		case OT_InhibitAlgoStyle:
			ModifyPresets.InhibitAlgoStyle = tag->ti_Data;
#ifdef INHIBITALGO
			SetAttrs(check_obj_bold,   MUIA_NoNotify, TRUE, MUIA_Selected, ModifyPresets.InhibitAlgoStyle & FSF_BOLD,	TAG_DONE, 0);
			SetAttrs(check_obj_italic, MUIA_NoNotify, TRUE, MUIA_Selected, ModifyPresets.InhibitAlgoStyle & FSF_ITALIC,	TAG_DONE, 0);
			SetAttrs(check_obj_extend, MUIA_NoNotify, TRUE, MUIA_Selected, ModifyPresets.InhibitAlgoStyle & FSF_EXTENDED,	TAG_DONE, 0);
			SetAttrs(check_obj_underl, MUIA_NoNotify, TRUE, MUIA_Selected, ModifyPresets.InhibitAlgoStyle & FSF_UNDERLINED,	TAG_DONE, 0);
#endif
			break;
		case OT_AvailSizes:
		{
			int i;
			struct AvailSizeList *list;
			char string[20];
			list = (struct AvailSizeList *)tag->ti_Data;
			ModifyPresets.AvailSizes = *list;
			list = &ModifyPresets.AvailSizes;
			DoMethod(lv_obj_sizes, MUIM_List_Clear);
			for(i=0; i < AvailBMSizes.Count; i++)		// Add BM sizes to size list
				AddSize(list, AvailBMSizes.Sizes[i]);
			for(i=0; i < list->Count; i++)
			{
				sprintf(string, "%ld", list->Sizes[i]);
				DoMethod(lv_obj_sizes, MUIM_List_InsertSingle, &string, MUIV_List_Insert_Bottom);
			}
			break;
		}
		case OT_SpecCount:
			break;
		case OT_Spec1_PFABFileName:	/* file name of the pfa/pfb file */
			stccpy(ModifyPresets.Type1FileName, (char *)tag->ti_Data, sizeof(ModifyPresets.Type1FileName));
			SetAttrs(string_obj_type1,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.Type1FileName, TAG_DONE, 0);
			break;
		case OT_Spec2_AFMFileName:	/* the filename of the AFM file */
			stccpy(ModifyPresets.AFMFileName, (char *)tag->ti_Data, sizeof(ModifyPresets.AFMFileName));
			SetAttrs(string_obj_afm,  MUIA_NoNotify, TRUE, MUIA_String_Contents, ModifyPresets.AFMFileName, TAG_DONE, 0);
			break;
		case OT_Spec6_OwnEncoding:
			ModifyPresets.OwnEncoding = tag->ti_Data;
			if (ModifyPresets.OwnEncoding)
				set(check_obj_symset, MUIA_Disabled, FALSE);
			break;
		default:
			MyErrorMsg1(LString(MSG_ERROR_UNKNOWN_TAG), tag->ti_Tag);
			break;
		}
	}

	OTagPresets = ModifyPresets;

	if (ModifyPresets.OwnEncoding == 0xffff)	// old .otag file
	{
		ModifyPresets.OwnEncoding = HasOwnEncoding(ModifyPresets.Type1FileName);
		if (ModifyPresets.OwnEncoding)
		{
			set(check_obj_symset, MUIA_Disabled, FALSE);
			if (ModifyPresets.SymbolSet != BUILTINENCODING)
			{
				ModifyPresets.SymbolSet = BUILTINENCODING;
				SetAttrs(check_obj_symset, MUIA_NoNotify, TRUE, MUIA_Selected, TRUE, TAG_DONE, 0);
				set(cycle_obj_symset, MUIA_Disabled, TRUE);
			}
		}
	}

	PreviewModified();
	DidChange();

	set (window_obj_main, MUIA_Window_Sleep, TRUE);
	DoMethod(app_obj, OM_ADDMEMBER, window_obj_modify);
	set(window_obj_modify, MUIA_Window_Open, TRUE);
	set(window_obj_modify, MUIA_Window_ActiveObject, cycle_obj_serif);	// Width and Slant must not be changed normally
	mod_window_open = TRUE;
	return TRUE;
}

void UpdateDisplay(void)
{
	int x;

	/* Clear the current list of fonts, and update */
	get(cycle_obj_dirs, MUIA_Cycle_Active, &x);

	set (window_obj_main, MUIA_Window_Sleep, TRUE);
	DoMethod(listview_obj, MUIM_List_Clear, 0);
	DoAllAssigns(fontdirparts[x], &ScanDir, &CheckFile);
	set (window_obj_main, MUIA_Window_Sleep, FALSE);
}

// TetiSoft: Display hook for AvailSizes listview
static LONG __saveds __asm SizesDispFunc(register __a0 struct Hook *hook,
					 register __a1 char *sizestr,
					 register __a2 char **array)
{
	static char buf[20];
	int i, found = FALSE;
	long size = atol(sizestr);
	strcpy(buf, MUIX_R);
	strcat(buf, sizestr);
	*array++ = buf;
	for(i=0; i < WantedBMSizes.Count; i++)
	{
		if (size == WantedBMSizes.Sizes[i])
		{
			found = TRUE;
			break;
		}
	}
	if (found)
		*array = LString(MSG_SIZES_LIST_BITMAP);
	else
		*array = "";
	return 0;
}

ULONG __saveds __asm AddManyFonts(register __a0 struct Hook *hook, 
				register __a2 APTR object,
				register __a1 APTR message)
{
	struct AppMessage *AppM = *(struct AppMessage **)message;
	int args,i,x;
	int ok, fail;	// TetiSoft
	BPTR olddir;
	char Buffer[64];

	if (AppM)
	{
		args = AppM->am_NumArgs;
		olddir = CurrentDir(AppM->am_ArgList[0].wa_Lock);
		get(cycle_obj_dirs, MUIA_Cycle_Active, &x);
		set(window_obj_main,MUIA_Window_Activate,TRUE);
		for (i=0, ok=0, fail=0; i < args; i++)
		{
			if (AppM->am_ArgList[i].wa_Name && AppM->am_ArgList[i].wa_Name[0])
			{
				CurrentDir(AppM->am_ArgList[i].wa_Lock);
				if (T1_InstallFont(AppM->am_ArgList[i].wa_Name, fontdirparts[x], &InstallPresets, FALSE))
					ok++;
				else
					fail++;
			}
		}
		CurrentDir(olddir);
		UpdateDisplay();
		sprintf(Buffer,LString(MSG_MULTIINSTALL_BODY), ok, fail);
		MUI_Request(app_obj, NULL, 0L, LString(MSG_MULTIINSTALL_TITLE), LString(MSG_REQ_OK), Buffer);
	}
	return NULL;
}

/*************************************************************/
/* Main */
/*************************************************************/
int main(int argc, char *argv[])
{
	struct DiskObject *DiskObject;
	BOOL running = TRUE;
	extern struct ExecBase *SysBase;
	char *s;
	int i;

#define DUMMY	NULL
	static struct NewMenu Menu[] =
	{
		{ NM_TITLE, DUMMY,       NULL,  0, 0, (APTR)0                              },
		{ NM_ITEM , DUMMY,       DUMMY, 0, 0, (APTR)ID_MENU_ABOUT                  },
		{ NM_ITEM , NM_BARLABEL, NULL,  0, 0, (APTR)0                              },
		{ NM_ITEM , DUMMY,       DUMMY, 0, 0, (APTR)MUIV_Application_ReturnID_Quit },
		{ NM_END  , NULL,        NULL,  0, 0, (APTR)0                              },
	};

#undef LocaleBase
#define LocaleBase LInfo.li_LocaleBase
	if (LInfo.li_LocaleBase = OpenLibrary("locale.library", __oslibversion))
		LInfo.li_Catalog = OpenCatalog(NULL, "T1Manager.catalog", OC_BuiltInLanguage, "english", OC_Version, CATVERSION, TAG_DONE);

	Menu[0].nm_Label   = LString(MSG_PROJECT_MENU);
	Menu[1].nm_Label   = LString(MSG_PROJECT_ABOUT);
	Menu[1].nm_CommKey = LString(MSG_PROJECT_ABOUT_SHORTCUT);
	Menu[3].nm_Label   = LString(MSG_PROJECT_QUIT);
	Menu[3].nm_CommKey = LString(MSG_PROJECT_QUIT_SHORTCUT);

#if 0	// TetiSoft: No longer necessary, specified __oslibversion for SAS/C auto-open feature
	/* check for V37 and fail if anything less */
	if (SysBase->LibNode.lib_Version < 37)
	{
		Write(Output(), "T1Manager requires Kickstart V37 or higher.\n", 44);
		CloseCatalog(LInfo.li_Catalog);
		if (LInfo.li_LocaleBase)
			CloseLibrary(LInfo.li_LocaleBase);
		exit(RETURN_FAIL);
	}
#endif

// TetiSoft: Open here, request a higher version than 0, AND EXIT IF IT FAILS...
	if ((MUIMasterBase = OpenLibrary("muimaster.library", MUIMASTER_VMIN)) == NULL)
	{
		Write(Output(), LString(MSG_ERROR_MUIMASTER), strlen(LString(MSG_ERROR_MUIMASTER)));
		CloseCatalog(LInfo.li_Catalog);
		if (LInfo.li_LocaleBase)
			CloseLibrary(LInfo.li_LocaleBase);
		exit(RETURN_FAIL);
	}

	for (i = 0; i < 256; i++)
		sprintf(PageNumbers[i], "%04lx - %04lx", i * 256, i * 256 + 255);

	for (i = 0; i <= 7; i++)
		PageStrings[i] = LString(MSG_PAGE_0 + i);
	PageStrings[8] =  LString(MSG_PAGE_UNKNOWN);
	for (i = 9; i <= 19; i++)
		PageStrings[i] = LString(MSG_PAGE_9 - 9 + i);
	PageStrings[20] =  LString(MSG_PAGE_20_21);
	PageStrings[21] =  LString(MSG_PAGE_20_21);
	PageStrings[22] =  LString(MSG_PAGE_22);
	PageStrings[23] =  LString(MSG_PAGE_23);
	PageStrings[24] =  LString(MSG_PAGE_24);
	for (i = 25; i <= 29; i++)
		PageStrings[i] = LString(MSG_PAGE_UNKNOWN);
	for (i = 30; i <= 40; i++)
		PageStrings[i] = LString(MSG_PAGE_30 - 30 + i);
	for (i = 41; i <= 45; i++)
		PageStrings[i] = LString(MSG_PAGE_UNKNOWN);
	for (i = 46; i <= 51; i++)
		PageStrings[i] = LString(MSG_PAGE_46 - 46 + i);
	for (i = 52; i <= 77; i++)
		PageStrings[i] = LString(MSG_PAGE_52_77);
	for (i = 78; i <= 159; i++)
		PageStrings[i] = LString(MSG_PAGE_78_159);
	for (i = 160; i <= 163; i++)
		PageStrings[i] = LString(MSG_PAGE_160_163);
	PageStrings[164] =  LString(MSG_PAGE_164);
	for (i = 165; i <= 171; i++)
		PageStrings[i] = LString(MSG_PAGE_UNKNOWN);
	for (i = 172; i <= 215; i++)
		PageStrings[i] = LString(MSG_PAGE_172_215);
	for (i = 216; i <= 218; i++)
		PageStrings[i] = LString(MSG_PAGE_216_218);
	PageStrings[219] =  LString(MSG_PAGE_219);
	for (i = 220; i <= 223; i++)
		PageStrings[i] = LString(MSG_PAGE_220_223);
	for (i = 224; i <= 248; i++)
		PageStrings[i] = LString(MSG_PAGE_224_248);
	PageStrings[249] =  LString(MSG_PAGE_249_250);
	PageStrings[250] =  LString(MSG_PAGE_249_250);
	PageStrings[251] =  LString(MSG_PAGE_251);
	PageStrings[252] =  LString(MSG_PAGE_252_253);
	PageStrings[253] =  LString(MSG_PAGE_252_253);
	PageStrings[254] =  LString(MSG_PAGE_254);
	PageStrings[255] =  LString(MSG_PAGE_255);

	/* check for V39 to see if we can use V39 functions AllocBitMap and FreeBitMap */
	if (SysBase->LibNode.lib_Version < 39)
		can_use_V39_funcs = 0;

	H_AddManyFonts.h_Entry = (HOOKFUNC)AddManyFonts;
	H_SizesDisp.h_Entry = (HOOKFUNC)SizesDispFunc;
	
	/* Create an array of the parts in the fonts: assign */
	DoAllAssigns("Fonts:", &AddFontdir, NULL);

// TetiSoft: Open once is enough
	if ((Type1Base = OpenLibrary("type1.library", T1LIBVERSION)) == NULL)
		MyErrorMsg1(LString(MSG_ERROR_TYPE1), T1LIBVERSION);

// TetiSoft: Preview text selectable
	DiskObject=GetDiskObject("PROGDIR:T1Manager");
	if (DiskObject &&
	    (PreviewText = FindToolType(DiskObject->do_ToolTypes, "PreviewText")) &&
	    (strlen(PreviewText) > 0))
		;
	else
		PreviewText = LString(MSG_PREVIEWTEXTDEFAULT);
	if (DiskObject &&
	    (PreviewText2 = FindToolType(DiskObject->do_ToolTypes, "PreviewText2")) &&
	    (strlen(PreviewText2) > 0))
		;
	else
		PreviewText2 = LString(MSG_PREVIEWTEXT2DEFAULT);
	if (DiskObject)
	{
		char *s = FindToolType(DiskObject->do_ToolTypes, "BitmapSizes");
		if (s)
		{
			char sizes[100];
			InstallPresets.AvailSizes.Count = 0;
			stccpy(sizes, s, 100);
			s = sizes;
			while((*s != '\0') && (*s != '\n') && (*s != '\r'))
			{
				while((*s == ' ') || (*s == '\t'))
					s++;
				AddSize(&InstallPresets.AvailSizes, atol(s));
				while((*s != '\0') && (*s != '\n') && (*s != '\r') && (*s != ' ') && (*s != '\t'))
					s++;
			}
			if (InstallPresets.AvailSizes.Count == 0)
			{
				InstallPresets.AvailSizes.Count = 1;
				InstallPresets.AvailSizes.Sizes[0] = 12;
			}
		}
	}
	if (DiskObject)
	{
		char *s = FindToolType(DiskObject->do_ToolTypes, "QuickInstall");
		if (s && (!stricmp(s, "true") || !stricmp(s, "yes")))
			QuickInstall = TRUE;
	}

	/* create GUI stuff */
	app_obj = ApplicationObject,
		MUIA_Application_Title,		"T1Manager",
// TetiSoft: After 29.1.2000 __AMIGADATE__ is one day in the future...
		MUIA_Application_Version,	"$VER: T1Manager " VERSION " " __AMIGADATE__,
		MUIA_Application_Copyright,	LString(MSG_COPYRIGHT),
		MUIA_Application_Author,	LString(MSG_AUTHORS),
		MUIA_Application_Description,	LString(MSG_DESCRIPTION),
		MUIA_Application_Base,		"T1Manager",
		MUIA_Application_DiskObject,	DiskObject,
		MUIA_Application_Menustrip,	MUI_MakeObject(MUIO_MenustripNM,Menu,0),

		SubWindow, window_obj_main = WindowObject,
			MUIA_Window_Title,	"T1Manager",
			MUIA_Window_ID,		MAKE_ID('T', '1', 'M', 'A'),
			MUIA_Window_AppWindow, TRUE,
			MUIA_Background, MUII_WindowBack,
			WindowContents, VGroup,

				Child, ColGroup(2),
					Child, Label2(LString(MSG_FONTDRAWER_LABEL)),
					Child, cycle_obj_dirs = CycleObject,
						MUIA_Font, MUIV_Font_Button,
						MUIA_Cycle_Entries, fontdirparts,
						MUIA_ObjectID, 1,
						End,
					End,

				Child, listview_obj = ListviewObject,
					MUIA_Listview_Input, TRUE,
					MUIA_Background, MUII_ListBack,
					MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Default,
					MUIA_Listview_List, ListObject, ReadListFrame,
						MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
						MUIA_List_DestructHook, MUIV_List_DestructHook_String,
						End,
					End,

				Child, ColGroup(2),	// TetiSoft
					Child, Label2(LString(MSG_FONTNAME_LABEL)),
					Child, string_obj_name = StringObject, MUIA_String_MaxLen, MAXFONTNAME - 6, MUIA_String_Reject, ":/\\`[]|#?$*\r\n\t", StringFrame, End,
					End,

//				Child, VSpace(2),

				Child, HGroup,
					Child, button_obj_install = SimpleButton(LString(MSG_INSTALL_GAD)),
					Child, button_obj_modify = SimpleButton(LString(MSG_MODIFY_GAD)),	// TetiSoft
					Child, button_obj_remove = SimpleButton(LString(MSG_REMOVE_GAD)),
					End,

//				Child, VSpace(2),

				Child, HGroup,
					MUIA_Weight, 16,
					Child, VGroup,
						Child, VSpace(0),
						Child, txt_obj_preview = TextObject,
							MUIA_Background, MUII_TextBack,
							MUIA_Text_PreParse, MUIX_R,
							MUIA_Text_Contents, LString(MSG_PREVIEW_LABEL_INIT),
							MUIA_Weight, 0,
							End,
						Child, VSpace(0),
						End,
					Child, bm_obj_preview = BitmapObject,
						TextFrame,
						MUIA_Background, MUII_TextBack,
						End,
					End,
				End,
			End,
		End;

	if (app_obj==NULL)
	{
		if (DiskObject)
			FreeDiskObject (DiskObject);
		if (Type1Base)
			CloseLibrary(Type1Base);
		FreeFontdirparts();			// TetiSoft: Forgotten...
		CloseLibrary(MUIMasterBase);		// TetiSoft: Forgotten...
		CloseCatalog(LInfo.li_Catalog);
		if (LInfo.li_LocaleBase)
			CloseLibrary(LInfo.li_LocaleBase);
		exit (RETURN_FAIL);
	}

// TetiSoft: Set up keyboard shortcuts if the localized labels contain a '_'
	if ((s = strchr(LString(MSG_FONTDRAWER_LABEL), '_')) && s[1])
		set(cycle_obj_dirs, MUIA_ControlChar, tolower(s[1]));
	if ((s = strchr(LString(MSG_FONTNAME_LABEL), '_')) && s[1])
		set(string_obj_name, MUIA_ControlChar, tolower(s[1]));

	/*
	 * setup stuff for event handling
	 */
	DoMethod (window_obj_main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
		app_obj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

	DoMethod (button_obj_install, MUIM_Notify, MUIA_Pressed, FALSE,
		app_obj, 2, MUIM_Application_ReturnID, ID_INSTALL);

	DoMethod (string_obj_name, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,	// TetiSoft
		app_obj, 2, MUIM_Application_ReturnID, ID_RENAME);

	DoMethod (button_obj_modify, MUIM_Notify, MUIA_Pressed, FALSE,	// TetiSoft
		app_obj, 2, MUIM_Application_ReturnID, ID_MODIFY);

	DoMethod (button_obj_remove, MUIM_Notify, MUIA_Pressed, FALSE,
		app_obj, 2, MUIM_Application_ReturnID, ID_REMOVE);

	DoMethod (cycle_obj_dirs, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		app_obj, 2, MUIM_Application_ReturnID, ID_CYCLE);

	DoMethod (listview_obj, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		app_obj, 2, MUIM_Application_ReturnID, ID_DOUBLECLICK);

	DoMethod (listview_obj, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
		app_obj, 2, MUIM_Application_ReturnID, ID_SELECTCHANGE);

	DoMethod (window_obj_main, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
		window_obj_main, 3, MUIM_CallHook, &H_AddManyFonts, MUIV_TriggerValue);

// TetiSoft: Redraw if necessary, doesn't work...
//	DoMethod (window_obj_main, MUIM_Notify, MUIA_Window_Height, MUIV_EveryTime,
//		app_obj, 2, MUIM_Application_ReturnID, ID_REDRAW_PREVIEW);
//	DoMethod (window_obj_main, MUIM_Notify, MUIA_Window_Width, MUIV_EveryTime,
//		app_obj, 2, MUIM_Application_ReturnID, ID_REDRAW_PREVIEW);

// TetiSoft: Disable this when nothing selected
	set (string_obj_name,MUIA_Disabled,TRUE);
	set (button_obj_modify,MUIA_Disabled,TRUE);
	set (button_obj_remove,MUIA_Disabled,TRUE);

// TetiSoft: Attach string to listview to enable scrolling with crsr up/down
	set(string_obj_name, MUIA_String_AttachedList, listview_obj);

// TetiSoft: bubble help
	set (cycle_obj_dirs, MUIA_ShortHelp,	LString(MSG_FONTDRAWER_HELP));
	set (listview_obj, MUIA_ShortHelp,	LString(MSG_FONTLIST_HELP));
	set (string_obj_name, MUIA_ShortHelp,	LString(MSG_FONTNAME_HELP));
	set (button_obj_install, MUIA_ShortHelp,LString(MSG_INSTALL_GAD_HELP));
	set (button_obj_modify, MUIA_ShortHelp,	LString(MSG_MODIFY_GAD_HELP));
	set (button_obj_remove, MUIA_ShortHelp,	LString(MSG_REMOVE_GAD_HELP));
	set (txt_obj_preview, MUIA_ShortHelp,	LString(MSG_PREVIEW_LABEL_HELP));
	set (bm_obj_preview, MUIA_ShortHelp,	LString(MSG_PREVIEW_HELP));

	/* set cycle chain for keyboard control */
	DoMethod (window_obj_main, MUIM_Window_SetCycleChain,
		cycle_obj_dirs, listview_obj, string_obj_name,
		button_obj_install, button_obj_modify, button_obj_remove,
		/* cycle_obj_pages, */ NULL);


	/* Load a previously saved configuration from env: */
	DoMethod(app_obj, MUIM_Application_Load, MUIV_Application_Load_ENV);


	/* init display */
	set (window_obj_main,MUIA_Window_Open,TRUE);
	set (window_obj_main,MUIA_Window_ActiveObject, cycle_obj_dirs);


	/* event loop */
	DoAllAssigns(fontdirparts[0], &ScanDir, &CheckFile);

	while (running)
	{
		ULONG signals = 0;
		switch (DoMethod(app_obj, MUIM_Application_Input, &signals))
		{
			case MUIV_Application_ReturnID_Quit:
				running = FALSE;

				/* Save our configuration */
				DoMethod(app_obj, MUIM_Application_Save, MUIV_Application_Save_ENVARC);
				DoMethod(app_obj, MUIM_Application_Save, MUIV_Application_Save_ENV);

				break;

			case ID_INSTALL:
			{
				LONG x;

				/* Get the active font: path from the cycle gad */
				get(cycle_obj_dirs, MUIA_Cycle_Active, &x);

				/* Install a font */
				InstallFont(window_obj_main, fontdirparts[x]);

				/* Clear the current list of fonts, and update */
//				DoMethod(listview_obj, MUIM_List_Clear, 0);
//				DoAllAssigns(fontdirparts[x], &ScanDir, &CheckFile);
				UpdateDisplay();

				break;
			}

			case ID_REMOVE:
			{
				LONG x = MUIV_List_NextSelected_Start;
				LONG fp;
				char *ch;
				int Mod = 0, Opt = 0;
				char Mess[256];

				/* Get the active font: path from the cycle gad */
				get(cycle_obj_dirs, MUIA_Cycle_Active, &fp);

				/* Find the active entry in the listview */
				for (;;)
				{
					DoMethod(listview_obj, MUIM_List_NextSelected,&x);
					if (x == MUIV_List_NextSelected_End) break;

					DoMethod(listview_obj, MUIM_List_GetEntry, x, &ch);
					if (!Mod || Opt == 1)
					{
						// Remove == 1, Skip = 2, All = 3, Cancel = 0
						sprintf(Mess, LString(MSG_REMOVE_BODY), ch);
						Opt = MUI_Request(app_obj, NULL, 0L, LString(MSG_REMOVE_TITLE), LString(MSG_REMOVE_OPTIONS), Mess);
						if (!Opt) break;
						if (Opt == 2)
						{
							Opt = 1;
							continue;
						}
					}

					/* Remove the font */
					if (*ch)
					{
						RemoveFont(window_obj_main, fontdirparts[fp], ch);
						Mod++;
					}
				}
				if (Mod)
				{
					UpdateDisplay();
					if (Mod > 1)
					{
						sprintf(Mess, LString(MSG_MULTIREMOVE_BODY), Mod);
						MUI_Request(app_obj, NULL, 0L, LString(MSG_MULTIREMOVE_TITLE), LString(MSG_REQ_OK), Mess);

						// TetiSoft: MUI_Request seems to catch the SELECTCHANGE msg...
						set (string_obj_name,MUIA_Disabled,TRUE);
						set (button_obj_modify,MUIA_Disabled,TRUE);
						set (button_obj_remove,MUIA_Disabled,TRUE);
					}
				}
				break;
			}

			case ID_CYCLE:
			{
//				LONG x;

				/* Get the active font: path from the cycle gad */
//				get(cycle_obj_dirs, MUIA_Cycle_Active, &x);

				/* Clear the current list of fonts, and update */
//				DoMethod(listview_obj, MUIM_List_Clear, 0);
//				DoAllAssigns(fontdirparts[x], &ScanDir, &CheckFile);
				UpdateDisplay();
				break;
			}

			case ID_SELECTCHANGE:
			{
// TetiSoft: Enable Rename, Modify and Remove Buttons only when active entry exists
				int a = MUIV_List_Active_Off;
				get (listview_obj, MUIA_List_Active, &a);
/*
				if (engine && (currentpreviewfont[0] != '\0'))
				{
					CloseEngine(engine);
					engine = NULL;
				}
*/
				/* If a preview is displayed, then remove it */
				if ((bitmap) && (currentpreviewfont[0] != '\0'))
				{
					SetAttrs(bm_obj_preview, MUIA_NoNotify, TRUE, MUIA_Bitmap_Bitmap, NULL, TAG_DONE, 0);
					currentpreviewfont[0] = '\0';
				}
				if (a == MUIV_List_Active_Off) {
					set (string_obj_name,MUIA_Disabled,TRUE);
					set (button_obj_modify,MUIA_Disabled,TRUE);
					set (button_obj_remove,MUIA_Disabled,TRUE);
					currentpreviewfont[0] = '\0';
					set(string_obj_name, MUIA_String_Contents, "");
				} else {
					char *fontname;
					DoMethod(listview_obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fontname);
					set(string_obj_name, MUIA_String_Contents, fontname);
					set (string_obj_name,MUIA_Disabled,FALSE);
					set (button_obj_remove,MUIA_Disabled,FALSE);
					set (button_obj_modify,MUIA_Disabled,FALSE);
				}
				break;
			}
			
//			case ID_REDRAW_PREVIEW:
			default:		// TetiSoft: This is a hack, didn't find a way how
						// to ask MUI to notify us when the size of the Bitmap
						// object changed, so we check here in the input loop...
				if (currentpreviewfont[0] == '\0')
					break;
				else
				{
					LONG newpreviewwidth, newpreviewheight, newencpreviewheight;
					if (enc_window_open)
					{
						get(bm_obj_enc, MUIA_Height, &newencpreviewheight);
						if (encpreviewheight != newencpreviewheight)
							update_enc_window(blFontName);
					}
					get(bm_obj_preview, MUIA_Width, &newpreviewwidth);
					get(bm_obj_preview, MUIA_Height, &newpreviewheight);
					if ((previewwidth == newpreviewwidth) && (previewheight == newpreviewheight))
						break;
					/* fall through */
				}

			/* Maybe fall throuh */
			case ID_DOUBLECLICK:
			{
				char *fontname;
				LONG x;

				/* Get the active font: path from the cycle gad */
				get(cycle_obj_dirs, MUIA_Cycle_Active, &x);

				/* Find the active entry in the listview */
				DoMethod(listview_obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fontname);
				if (fontname)
				{
/*
					if (engine && (currentpreviewfont[0] != '\0'))
					{
						CloseEngine(engine);
						engine = NULL;
					}
*/
					stccpy(currentpreviewfont, fontname, 79);
					if (*fontname)
						PreviewFont(window_obj_main, fontdirparts[x], fontname, NULL);
				}
				break;
			}

// TetiSoft: Rename function. Sorry, no multiselect currently...
			case ID_RENAME:
			{
				LONG fp;
				char *fontnamelv;
				char *fontnamest;

				/* Get the active font: path from the cycle gad */
				get(cycle_obj_dirs, MUIA_Cycle_Active, &fp);

				/* Find the active entry in the listview */
				DoMethod(listview_obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fontnamelv);

				get(string_obj_name, MUIA_String_Contents, &fontnamest);
				if (fontnamelv && fontnamest)
					if (*fontnamelv && *fontnamest)
						if (strcmp(fontnamelv, fontnamest))
							if (RenameFont(fontdirparts[fp], fontnamelv, fontnamest))
								UpdateDisplay();
				break;
			}

// TetiSoft: Modify window. Sorry, no multiselect currently...
			case ID_MODIFY:
			{
				char *fontname;
				LONG x;

				/* Get the active font: path from the cycle gad */
				get(cycle_obj_dirs, MUIA_Cycle_Active, &x);

				/* Find the active entry in the listview */
				DoMethod(listview_obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fontname);
				if (*fontname)
				{
					stccpy(blFontDir, fontdirparts[x], sizeof(blFontDir));	// for bitline
					stccpy(blFontName, fontname, sizeof(blFontName));	// for bitline

					ModifyPresets = InstallPresets;
					strcpy(ModifyPresets.OTagFileName, fontdirparts[x]);
					AddPart(ModifyPresets.OTagFileName, fontname, sizeof(ModifyPresets.OTagFileName));

					stccpy(FontDirName, ModifyPresets.OTagFileName, sizeof(FontDirName));
					strcat(ModifyPresets.OTagFileName, ".otag");

					if (strcmp(currentpreviewfont, fontname) != 0)
					{
/*
						if (engine && (currentpreviewfont[0] != '\0'))
						{
							CloseEngine(engine);
							engine = NULL;
						}
*/
						stccpy(currentpreviewfont, fontname, 79);
						ReadOTagFile(ModifyPresets.OTagFileName);
					}
					if (OTagFileBuf)
						open_modify_window();
				}
				break;
			}
			case ID_MODIFY_FIXED:
			{
				ULONG index;
				get(cycle_obj_fixed, MUIA_Cycle_Active, &index);
				if (index == 0)
					ModifyPresets.IsFixed = FALSE;
				else
					ModifyPresets.IsFixed = TRUE;
				ModifyPresets.SpaceWidth = 0;	// must be recalculated
				SetAttrs(string_obj_spacew,  MUIA_NoNotify, TRUE, MUIA_String_Integer, 0, TAG_DONE, 0);
				PreviewModified();
				DidChange();
				if (enc_window_open)
					update_enc_window(blFontName);
				break;
			}
			case ID_MODIFY_SERIF:
			{
				int index;
				get(cycle_obj_serif, MUIA_Cycle_Active, &index);
				ModifyPresets.SerifFlag = index ? FALSE : TRUE;
				DidChange();
				break;
			}
			case ID_MODIFY_SLANT:
				get(cycle_obj_slant, MUIA_Cycle_Active, &ModifyPresets.SlantStyle);
				DidChange();
				break;

			case ID_MODIFY_WEIGHT:
			{
				int index;
				get(cycle_obj_weight, MUIA_Cycle_Active, &index);
				switch(index)
				{
				case 0:
					ModifyPresets.StemWeight = OTS_UltraThin;
					break;
				case 1:
					ModifyPresets.StemWeight = OTS_ExtraThin;
					break;
				case 2:
					ModifyPresets.StemWeight = OTS_Thin;
					break;
				case 3:
					ModifyPresets.StemWeight = OTS_ExtraLight;
					break;
				case 4:
					ModifyPresets.StemWeight = OTS_Light;
					break;
				case 5:
					ModifyPresets.StemWeight = OTS_DemiLight;
					break;
				case 6:
					ModifyPresets.StemWeight = OTS_SemiLight;
					break;
				case 7:
				default :
					ModifyPresets.StemWeight = OTS_Book;
					break;
				case 8:
					ModifyPresets.StemWeight = OTS_Medium;
					break;
				case 9:
					ModifyPresets.StemWeight = OTS_SemiBold;
					break;
				case 10:
					ModifyPresets.StemWeight = OTS_DemiBold;
					break;
				case 11:
					ModifyPresets.StemWeight = OTS_Bold;
					break;
				case 12:
					ModifyPresets.StemWeight = OTS_ExtraBold;
					break;
				case 13:
					ModifyPresets.StemWeight = OTS_Black;
					break;
				case 14:
					ModifyPresets.StemWeight = OTS_ExtraBlack;
					break;
				case 15:
					ModifyPresets.StemWeight = OTS_UltraBlack;
					break;
				}
				DidChange();
				break;
			}

			case ID_MODIFY_HSTYLE:
			{
				int index;
				get(cycle_obj_hstyle, MUIA_Cycle_Active, &index);
				switch(index)
				{
				case 0:
					ModifyPresets.HorizStyle = OTH_UltraCompressed;
					break;
				case 1:
					ModifyPresets.HorizStyle = OTH_ExtraCompressed;
					break;
				case 2:
					ModifyPresets.HorizStyle = OTH_Compressed;
					break;
				case 3:
					ModifyPresets.HorizStyle = OTH_Condensed;
					break;
				case 4:
				default:
					ModifyPresets.HorizStyle = OTH_Normal;
					break;
				case 5:
					ModifyPresets.HorizStyle = OTH_SemiExpanded;
					break;
				case 6:
					ModifyPresets.HorizStyle = OTH_Expanded;
					break;
				case 7:
					ModifyPresets.HorizStyle = OTH_ExtraExpanded;
					break;
				}
				DidChange();
				break;
			}

			case ID_MODIFY_SYMSET:
			{
				int intern;

				get(check_obj_symset, MUIA_Selected, &intern);
				if (intern)
				{
					ModifyPresets.SymbolSet = BUILTINENCODING;
					set(cycle_obj_symset, MUIA_Disabled, TRUE);
				} else {
					int index;

					set(cycle_obj_symset, MUIA_Disabled, FALSE);
					get(cycle_obj_symset, MUIA_Cycle_Active, &index);
					switch(index)
					{
					case 0:
						ModifyPresets.SymbolSet = UNICODE;
						break;
					case 1:
						ModifyPresets.SymbolSet = STANDARDENCODING;
						break;
					case 2:
						ModifyPresets.SymbolSet = CEENCODING;
						break;
					case 3:
						ModifyPresets.SymbolSet = WINCYRILLICENCODING;
						break;
					case 4:
						ModifyPresets.SymbolSet = WINLATIN1ENCODING;
						break;
					case 5:
						ModifyPresets.SymbolSet = PSISOLATIN1ENCODING;
						break;
					case 6:
					default:
						ModifyPresets.SymbolSet = ISOLATIN1ENCODING;
						break;
					case 7:
						ModifyPresets.SymbolSet = ISOLATIN2ENCODING;
						break;
					case 8:
						ModifyPresets.SymbolSet = ISOLATIN3ENCODING;
						break;
					case 9:
						ModifyPresets.SymbolSet = ISOLATIN4ENCODING;
						break;
					case 10:
						ModifyPresets.SymbolSet = ISOCYRILLICENCODING;
						break;
					case 11:
						ModifyPresets.SymbolSet = ISOARABICENCODING;
						break;
					case 12:
						ModifyPresets.SymbolSet = ISOGREEKENCODING;
						break;
					case 13:
						ModifyPresets.SymbolSet = ISOHEBREWENCODING;
						break;
					case 14:
						ModifyPresets.SymbolSet = ISOLATIN5ENCODING;
						break;
					case 15:
						ModifyPresets.SymbolSet = ISOLATIN6ENCODING;
						break;
					case 16:
						ModifyPresets.SymbolSet = ISOTHAIENCODING;
						break;
					case 17:
						ModifyPresets.SymbolSet = ISOLATIN7ENCODING;
						break;
					case 18:
						ModifyPresets.SymbolSet = ISOLATIN8ENCODING;
						break;
					case 19:
						ModifyPresets.SymbolSet = ISOLATIN9ENCODING;
						break;
					case 20:
						ModifyPresets.SymbolSet = KOI8RENCODING;
						break;
					case 21:
						ModifyPresets.SymbolSet = E2ENCODING;
						break;
					}
				}
				ModifyPresets.SpaceWidth = 0;	// must be recalculated
				SetAttrs(string_obj_spacew,    MUIA_NoNotify, TRUE, MUIA_String_Integer, 0, TAG_DONE, 0);
				ModifyPresets.YSizeFactor = 0;	// must be recalculated
				SetAttrs(string_obj_ysizefph,  MUIA_NoNotify, TRUE, MUIA_String_Integer, 0, TAG_DONE, 0);
				SetAttrs(string_obj_ysizefbh,  MUIA_NoNotify, TRUE, MUIA_String_Integer, 0, TAG_DONE, 0);
				PreviewModified();
				DidChange();
				if (enc_window_open)
					update_enc_window(blFontName);
				break;
			}

			case ID_MODIFY_SHOWSYMSET:
				if (enc_window_open)
				{
					struct Window *window;
					get(window_obj_enc, MUIA_Window, &window);
					if (window)
						WindowToFront(window);
				}
				update_enc_window(blFontName);
				break;

			case ID_MODIFY_SPACEW:
			{
				LONG SpaceWidth;
				get(string_obj_spacew, MUIA_String_Integer, &SpaceWidth);
				if (SpaceWidth != ModifyPresets.SpaceWidth)
				{
					ModifyPresets.SpaceWidth = SpaceWidth;
					if (ModifyPresets.IsFixed || !SpaceWidth)
						PreviewModified();
					DidChange();
					if (ModifyPresets.IsFixed)
						update_enc_window(blFontName);
				}
				break;
			}

			case ID_MODIFY_YSIZEFPH:
			case ID_MODIFY_YSIZEFBH:
			{
				ULONG YSizeFactorPH, YSizeFactorBH, YSizeFactor;
				get(string_obj_ysizefph, MUIA_String_Integer, &YSizeFactorPH);
				get(string_obj_ysizefbh, MUIA_String_Integer, &YSizeFactorBH);
				YSizeFactor = (YSizeFactorPH << 16) | (YSizeFactorBH & 0xffff);
				if (YSizeFactor != ModifyPresets.YSizeFactor)
				{
					if ((YSizeFactorBH == 0) ||
					    (YSizeFactorPH == 0) ||
					    (((YSizeFactorPH * 100) / YSizeFactorBH) <
					     (((ModifyPresets.YSizeFactor >> 16) * 100) / (ModifyPresets.YSizeFactor & 0xffff))) ||
					    (MUI_Request(app_obj, NULL, 0, LString(MSG_REQ_WARNTITLE), LString(MSG_REQ_OK_CANCEL),
							LString(MSG_YSIZEFACTOR_INC_WARNING)) == 1))
					{
						ModifyPresets.YSizeFactor = YSizeFactor;
						PreviewModified();
						DidChange();
//						if (enc_window_open)
							update_enc_window(blFontName);
					} else {
						SetAttrs(string_obj_ysizefph, MUIA_NoNotify, TRUE, MUIA_String_Integer, ModifyPresets.YSizeFactor >> 16,    TAG_DONE, 0);
						SetAttrs(string_obj_ysizefbh, MUIA_NoNotify, TRUE, MUIA_String_Integer, ModifyPresets.YSizeFactor & 0xffff, TAG_DONE, 0);
					}
				}
				break;
			}
#ifdef INHIBITALGO
			case ID_MODIFY_INHIBITALGO:
			{
				ULONG bold, italic, extended, underlined;
				get(check_obj_bold,   MUIA_Selected, &bold);
				get(check_obj_italic, MUIA_Selected, &italic);
				get(check_obj_extend, MUIA_Selected, &extended);
				get(check_obj_underl, MUIA_Selected, &underlined);
				ModifyPresets.InhibitAlgoStyle &= ~(FSF_BOLD|FSF_ITALIC|FSF_EXTENDED|FSF_UNDERLINED);
				ModifyPresets.InhibitAlgoStyle |= (bold ? FSF_BOLD : 0) | (italic ? FSF_ITALIC : 0) | (extended ? FSF_EXTENDED : 0) | (underlined ? FSF_UNDERLINED : 0);
				if (!bold || !extended || !underlined)
					MyWarningMsg(LString(MSG_INHIBITALGO_WARNING));
				DidChange();
				break;
			}
#endif
			case ID_MODIFY_SELSIZECHANGE:
			{
				int a = MUIV_List_Active_Off;
				get (lv_obj_sizes, MUIA_List_Active, &a);

				if (a == MUIV_List_Active_Off)
					set(string_obj_sizes, MUIA_String_Contents, "");
				else {
					char *sizestr;
					DoMethod(lv_obj_sizes, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &sizestr);
					set(string_obj_sizes, MUIA_String_Contents, sizestr);
				}
				break;
			}

			case ID_MODIFY_SIZECHANGE:
				SizeStringChange();
				break;

			case ID_MODIFY_ADDSIZE:
			{
				LONG size;
				int i;
				char string[20];
				get(string_obj_sizes, MUIA_String_Integer, &size);
				if (AddSize(&ModifyPresets.AvailSizes, size))
				{
					DoMethod(lv_obj_sizes, MUIM_List_Clear);
					for(i=0; i < ModifyPresets.AvailSizes.Count; i++)
					{
						sprintf(string, "%ld", ModifyPresets.AvailSizes.Sizes[i]);
						DoMethod(lv_obj_sizes, MUIM_List_InsertSingle, &string, MUIV_List_Insert_Bottom);
					}
					set (button_obj_addsize,MUIA_Disabled,TRUE);
					DidChange();
				}
				break;
			}

			case ID_MODIFY_DELSIZE:
			{
				int i;
				char string[20];
				LONG x = MUIV_List_NextSelected_Start;
				int Deleted = 0;
				char *strptr;
				for(;;)
				{
					DoMethod(lv_obj_sizes, MUIM_List_NextSelected, &x);
					if (x == MUIV_List_NextSelected_End) break;
					DoMethod(lv_obj_sizes, MUIM_List_GetEntry, x, &strptr);
					if (*strptr)
					{
						if (DelSize(&ModifyPresets.AvailSizes, atol(strptr)))
						{
							Deleted++;
							DelSize(&WantedBMSizes, atol(strptr));
						}
					}
				}
				if (Deleted)
				{
					DoMethod(lv_obj_sizes, MUIM_List_Clear);
					for(i=0; i < ModifyPresets.AvailSizes.Count; i++)
					{
						sprintf(string, "%ld", ModifyPresets.AvailSizes.Sizes[i]);
						DoMethod(lv_obj_sizes, MUIM_List_InsertSingle, &string, MUIV_List_Insert_Bottom);
					}
					set (button_obj_delsize,MUIA_Disabled,TRUE);
					set (button_obj_delbm,MUIA_Disabled,TRUE);
					DidChange();
				}
				break;
			}

			case ID_MODIFY_ADDBM:
			{
				int i;
				char string[20];
				LONG x = MUIV_List_NextSelected_Start;
				int Added = 0;
				char *strptr;
				for(;;)
				{
					DoMethod(lv_obj_sizes, MUIM_List_NextSelected, &x);
					if (x == MUIV_List_NextSelected_End) break;
					DoMethod(lv_obj_sizes, MUIM_List_GetEntry, x, &strptr);
					if (*strptr)
						if (AddSize(&WantedBMSizes, atol(strptr)))
							Added++;
				}
				if (Added)
				{
					DoMethod(lv_obj_sizes, MUIM_List_Clear);
					for(i=0; i < ModifyPresets.AvailSizes.Count; i++)
					{
						sprintf(string, "%ld", ModifyPresets.AvailSizes.Sizes[i]);
						DoMethod(lv_obj_sizes, MUIM_List_InsertSingle, &string, MUIV_List_Insert_Bottom);
					}
					set (button_obj_addsize,MUIA_Disabled,TRUE);
					set (button_obj_addbm,MUIA_Disabled,TRUE);
					DidChange();
				}
				break;
			}

			case ID_MODIFY_DELBM:
			{
				int i;
				char string[20];
				LONG x = MUIV_List_NextSelected_Start;
				int Deleted = 0;
				char *strptr;
				for(;;)
				{
					DoMethod(lv_obj_sizes, MUIM_List_NextSelected, &x);
					if (x == MUIV_List_NextSelected_End) break;
					DoMethod(lv_obj_sizes, MUIM_List_GetEntry, x, &strptr);
					if (*strptr)
						if (DelSize(&WantedBMSizes, atol(strptr)))
							Deleted++;
				}
				if (Deleted)
				{
					DoMethod(lv_obj_sizes, MUIM_List_Clear);
					for(i=0; i < ModifyPresets.AvailSizes.Count; i++)
					{
						sprintf(string, "%ld", ModifyPresets.AvailSizes.Sizes[i]);
						DoMethod(lv_obj_sizes, MUIM_List_InsertSingle, &string, MUIV_List_Insert_Bottom);
					}
					set (button_obj_delsize,MUIA_Disabled,TRUE);
					set (button_obj_delbm,MUIA_Disabled,TRUE);
					DidChange();
				}
				break;
			}
#ifdef FAMILYNAMES
			case ID_MODIFY_FAMILY:
			{
				char *Family;
				get(string_obj_family, MUIA_String_Contents, &Family);
				if (strcmp(Family, ModifyPresets.FamilyName))
				{
					stccpy(ModifyPresets.FamilyName, Family, sizeof(ModifyPresets.FamilyName));
					DidChange();
				}
				break;
			}

			case ID_MODIFY_BNAME:
			{
				char *bname, *slashptr;
				char buf[MAXFONTNAME];
				get(string_obj_bname, MUIA_String_Contents, &bname);
				stccpy(buf, bname, MAXFONTNAME);
				slashptr = strchr(buf, '/');
				if (slashptr)
				{
					*slashptr = '\0';
					set(string_obj_bname, MUIA_String_Contents, buf);
				}
				else if (strcmp(bname, ModifyPresets.BoldName))
				{
					stccpy(ModifyPresets.BoldName, bname, sizeof(ModifyPresets.BoldName));
					DidChange();
				}
				break;
			}

			case ID_MODIFY_INAME:
			{
				char *iname, *slashptr;
				char buf[MAXFONTNAME];
				get(string_obj_iname, MUIA_String_Contents, &iname);
				stccpy(buf, iname, MAXFONTNAME);
				slashptr = strchr(buf, '/');
				if (slashptr)
				{
					*slashptr = '\0';
					set(string_obj_iname, MUIA_String_Contents, buf);
				}
				else if (strcmp(iname, ModifyPresets.ItalicName))
				{
					stccpy(ModifyPresets.ItalicName, iname, sizeof(ModifyPresets.ItalicName));
					DidChange();
				}
				break;
			}

			case ID_MODIFY_BINAME:
			{
				char *biname, *slashptr;
				char buf[MAXFONTNAME];
				get(string_obj_biname, MUIA_String_Contents, &biname);
				stccpy(buf, biname, MAXFONTNAME);
				slashptr = strchr(buf, '/');
				if (slashptr)
				{
					*slashptr = '\0';
					set(string_obj_biname, MUIA_String_Contents, buf);
				}
				else if (strcmp(biname, ModifyPresets.BoldItalicName))
				{
					stccpy(ModifyPresets.BoldItalicName, biname, sizeof(ModifyPresets.BoldItalicName));
					DidChange();
				}
				break;
			}
#endif
			case ID_MODIFY_TYPE1FILE:
			{
				char *type1file;
				get(string_obj_type1, MUIA_String_Contents, &type1file);
				if (strcmp(type1file, ModifyPresets.Type1FileName) != 0)
				{
/*
					if (engine)
					{
						CloseEngine(engine);
						engine = NULL;
					}
*/
					stccpy(ModifyPresets.Type1FileName, type1file, sizeof(ModifyPresets.Type1FileName));
					PreviewModified();
					DidChange();
					if (enc_window_open)
						update_enc_window(blFontName);
				}
				break;
			}

			case ID_MODIFY_AFMFILE:
			{
				char *afmfile;
				get(string_obj_afm, MUIA_String_Contents, &afmfile);
				if (strcmp(afmfile, ModifyPresets.AFMFileName))
				{
					stccpy(ModifyPresets.AFMFileName, afmfile, sizeof(ModifyPresets.AFMFileName));
					PreviewModified();
					DidChange();
				}
				break;
			}

			case ID_MODIFY_SAVE:
			{
				LONG YSizeFactorPH;
				LONG YSizeFactorBH;
				LONG x;
				char *fontname;
				BPTR lock;
				char *buf;

// We must first scan the string gadgets that were changed without hitting return and which don't notify all changes...
				get(string_obj_ysizefph, MUIA_String_Integer, &YSizeFactorPH);
				get(string_obj_ysizefbh, MUIA_String_Integer, &YSizeFactorBH);
				ModifyPresets.YSizeFactor = (YSizeFactorPH << 16) | YSizeFactorBH;
				get(string_obj_spacew, MUIA_String_Integer, &ModifyPresets.SpaceWidth);
				get(string_obj_type1, MUIA_String_Contents, &buf);
				stccpy(ModifyPresets.Type1FileName, buf, sizeof(ModifyPresets.Type1FileName));
				get(string_obj_afm, MUIA_String_Contents, &buf);
				stccpy(ModifyPresets.AFMFileName, buf, sizeof(ModifyPresets.AFMFileName));

				if (DidChange())
				{
					if ((ModifyPresets.Type1FileName[0] != '\0') &&
					    ((lock = Lock(ModifyPresets.Type1FileName, ACCESS_READ)) != NULL))
					{
						UnLock(lock);
						lock = NULL;
						if (!ModifyPresets.IsFixed && (ModifyPresets.AFMFileName[0] != '\0') &&
						    ((lock = Lock(ModifyPresets.AFMFileName, ACCESS_READ)) == NULL))
							MyErrorMsg(LString(MSG_ERROR_AFM_NOT_FOUND));
						else
						{
							int RebuildBitmaps = FALSE;
							UnLock(lock);
							if ((OTagPresets.IsFixed != ModifyPresets.IsFixed) ||
							    (OTagPresets.SlantStyle != ModifyPresets.SlantStyle) ||
							    (OTagPresets.StemWeight != ModifyPresets.StemWeight) ||
							    (OTagPresets.SymbolSet != ModifyPresets.SymbolSet) ||
							    (OTagPresets.YSizeFactor != ModifyPresets.YSizeFactor) ||
							    (ModifyPresets.IsFixed && (OTagPresets.SpaceWidth != ModifyPresets.SpaceWidth)))
//								WantedBMSizes.Count = 0;	// Force delete bitmaps generated from old settings
								RebuildBitmaps = TRUE;	// Force delete bitmaps generated from old settings
							/* Get the active font: path from the cycle gad */
							get(cycle_obj_dirs, MUIA_Cycle_Active, &x);
							/* Find the active entry in the listview */
							DoMethod(listview_obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fontname);
							stccpy(currentpreviewfont, fontname, 79);
							if (ModifyPresets.AvailSizes.Count == 0)
							{
								ModifyPresets.AvailSizes.Count = 1;
								ModifyPresets.AvailSizes.Sizes[0] = 12;
							}
							set(window_obj_modify, MUIA_Window_Sleep, TRUE);
							if (T1_InstallFont(ModifyPresets.Type1FileName, fontdirparts[x], &ModifyPresets, TRUE))
								HandleBitmaps(&AvailBMSizes, &WantedBMSizes, RebuildBitmaps);
							if (*fontname)
								PreviewFont(window_obj_main, fontdirparts[x], fontname, NULL);
							close_enc_window();
							close_modify_window();
						}
					} else
						MyErrorMsg(LString(MSG_ERROR_TYPE1_NOT_FOUND));
				} else {
					close_enc_window();
					close_modify_window();
				}
				break;
			}
			case ID_MODIFY_CANCEL:
				close_enc_window();
				close_modify_window();
/*
				if (engine && (strcmp(OTagPresets.Type1FileName, ModifyPresets.Type1FileName) != '\0'))
				{
					CloseEngine(engine);
					engine = NULL;
				}
*/
				PreviewFont(window_obj_main, blFontDir, blFontName, NULL);
				break;

			case ID_ENC_CLOSE:
				close_enc_window();
				break;

			case ID_ENC_PAGE:
				update_enc_window(blFontName);
				break;

			case ID_MENU_ABOUT:
			{
				char buf[300];
				sprintf(buf, "T1Manager %s\n%s", VERSION, LString(MSG_ABOUT));
				MUI_Request(app_obj, window_obj_main, 0, NULL, LString(MSG_REQ_OK), buf);
				break;
			}
		}

		if (running && signals)
			Wait(signals);
	}

	if (engine)
		CloseEngine(engine);
	if (UnicodeArray)
		FreeVec(UnicodeArray);

	/* free the preview bitmap */
//	if (bitmap) FreeBitMap(bitmap);
	if (bitmap) MyFreeBitMap(bitmap, bitmapwidth, bitmapheight);
	if (encbitmap) MyFreeBitMap(encbitmap, encbmwidth, encbmheight);

	/* free file requester, moved by TetiSoft */
	if (FileRequester)
		MUI_FreeAslRequest (FileRequester);

	if (OTagFileBuf)
		FreeVec(OTagFileBuf);

	/* remove GUI stuff */
	MUI_DisposeObject(app_obj);
	if (DiskObject) FreeDiskObject(DiskObject);

	/* free some allocations */
	FreeFontdirparts();

	/* close our libraries */
	if (Type1Base)
		CloseLibrary(Type1Base);
	CloseLibrary(MUIMasterBase);
	CloseCatalog(LInfo.li_Catalog);
	if (LInfo.li_LocaleBase)
		CloseLibrary(LInfo.li_LocaleBase);
	exit (RETURN_OK);
}


#ifdef PARMDEBUG
void DebugBltTemplate(UWORD *SrcTemplate, WORD SrcX, WORD SrcMod, struct RastPort *rp, WORD DstX, WORD DstY, WORD SizeX, WORD SizeY, char ch)
{
	char ReqText[256];

	sprintf(ReqText, "ch='%lc'\nSrcTemplate=%lx\nSrcX=%ld\nSrcMod=%ld\nrp=%lx\nDstX=%ld\nDstY=%ld\nSizeX=%ld\nSizeY=%ld\n", (LONG) ch, (LONG) SrcTemplate, (LONG) SrcX, (LONG) SrcMod, (LONG) rp, (LONG) DstX, (LONG) DstY, (LONG) SizeX, (LONG) SizeY);
	(void)MUI_Request(app_obj, NULL, 0L, "BltTemplate parms", "Ok", ReqText);
}
#endif


/*************************************************************/
/* InstallFont */
/* select a file to install with the asl.library */
/*************************************************************/
static BOOL InstallFont(APTR ParentWindow, char *destdrawer)
{
	BOOL Result;
	int i;
	BPTR olddir;

	if (window == NULL)	// TetiSoft
	{
		get(ParentWindow, MUIA_Window, &window);
		if (window == NULL) return FALSE;
	}

	if (FileRequester == NULL)	// TetiSoft
	{
		if ((FileRequester=(struct FileRequester *) MUI_AllocAslRequestTags(ASL_FileRequest,
				ASLFR_RejectIcons,  	TRUE,
				ASLFR_Window,   	window,
//				ASLFR_InitialDrawer,	"psfonts:",
				ASLFR_DoMultiSelect,	TRUE,
				ASLFR_DoPatterns,	TRUE,
				ASLFR_TitleText,	LString(MSG_TYPE1FILES_FILEREQ_TITLE),
				ASLFR_InitialPattern,	"#?.(pfa|pfb)",
				TAG_DONE))==NULL)
			return FALSE;

	}
	set (ParentWindow,MUIA_Window_Sleep,TRUE);
	Result=MUI_AslRequest((APTR)FileRequester,NULL);

	if (Result)
	{
		int ok, fail;		// TetiSoft
		char Buffer[64];	// TetiSoft

		olddir = CurrentDir(FileRequester->fr_ArgList[0].wa_Lock);
		for (i=0, ok=0, fail=0; i < FileRequester->fr_NumArgs; i++)
		{
			CurrentDir(FileRequester->fr_ArgList[i].wa_Lock);
			if (T1_InstallFont(FileRequester->fr_ArgList[i].wa_Name, destdrawer, &InstallPresets, FALSE))
				ok++;
			else
				fail++;
		}
		CurrentDir(olddir);
		sprintf(Buffer, LString(MSG_MULTIINSTALL_BODY), ok, fail);
		if (i > 1) MUI_Request(app_obj, NULL, 0L, LString(MSG_MULTIINSTALL_TITLE), LString(MSG_REQ_OK), Buffer);
	}

	set (ParentWindow,MUIA_Window_Sleep,FALSE);

	return Result;
}


// TetiSoft: Added rename function
/*************************************************************/
/* RenameFont */
/* rename an installed font */
/*************************************************************/
static LONG *CreateNoSizesPtr[1] = {NULL};
static BOOL RenameFont(char *fontdrawer, char *oldfontname, char *newfontname)
{
	char filename[MAXFONTNAME];
	char newfilename[MAXFONTNAME];
	BPTR DirLock, oldDirLock, fLock;
	int afShortage, afSize;
	struct AvailFontsHeader *afh;
	int i;

	afSize = 1024;
	do
	{
		afh = (struct AvailFontsHeader *)AllocMem(afSize, 0);
		if (afh)
		{
			afShortage = AvailFonts((STRPTR)afh, afSize, AFF_MEMORY|AFF_DISK);
			if (afShortage)
			{
				FreeMem(afh, afSize);
				afSize += afShortage;
			}
		} else {
			MyErrorMsg(LString(MSG_ERROR_NOMEM_AVAILFONTS));
			return FALSE;
		}
	} while (afShortage);
	strcpy(newfilename, newfontname);
	strcat(newfilename, ".font");
	for (i = 0; i < afh->afh_NumEntries; i++)
	{
		struct AvailFonts *af = (struct AvailFonts *)(&afh[1]);
		if (!stricmp(af[i].af_Attr.ta_Name, newfilename))
		{
			MyErrorMsg1(LString(MSG_ERROR_FONT_EXISTS), newfontname);
			FreeMem(afh, afSize);
			return FALSE;
		}
	}

	FreeMem(afh, afSize);

	DirLock = Lock(fontdrawer, ACCESS_READ);
	if (!DirLock)
		return FALSE;
	oldDirLock = CurrentDir(DirLock);
	if (!oldDirLock)
	{
		UnLock(DirLock);
		return FALSE;
	}

	/* Rename the font directory if it exists */
	fLock = Lock(oldfontname, ACCESS_READ);
	if (fLock)
	{
		UnLock(fLock);
		if (!Rename(oldfontname, newfontname))
		{
			MyErrorMsg1(LString(MSG_ERROR_RENAME_DIR), oldfontname);
			CurrentDir(oldDirLock);
			UnLock(DirLock);
			return FALSE;
		}
	}

	/* Rename the .font file if it exists */
	strcpy(filename, oldfontname);
	strcat(filename, ".font");
	fLock = Lock(filename, ACCESS_READ);
	if (fLock)
	{
		UnLock(fLock);
		strcpy(newfilename, newfontname);
		strcat(newfilename, ".font");
		if (!Rename(filename, newfilename))
		{
			MyErrorMsg1(LString(MSG_ERROR_RENAME_FILE), filename);
			Rename(newfontname, oldfontname);	// Rename back font directory if it exists
			CurrentDir(oldDirLock);
			UnLock(DirLock);
			return FALSE;
		}
	}

	/* Rename the existing .otag file */
	strcpy(filename, oldfontname);
	strcat(filename, ".otag");
	strcpy(newfilename, newfontname);
	strcat(newfilename, ".otag");
	if (!Rename(filename, newfilename))
	{
		MyErrorMsg1(LString(MSG_ERROR_RENAME_FILE), filename);
		Rename(newfontname, oldfontname);	// Rename back font directory if it exists
		strcpy(filename, oldfontname);
		strcat(filename, ".font");
		strcpy(newfilename, newfontname);
		strcat(newfilename, ".font");
		Rename(newfilename, filename);		// Rename back .font file if it exists
		CurrentDir(oldDirLock);
		UnLock(DirLock);
		return FALSE;
	}

// Unnecessary since the name in the bitmap file is only a placeholder
//	/* Delete all files in the bitmap directory, they contain the old font name */
//	DoAllAssigns(newfontname, &ScanDir, &DeleteBitmaps);
//
//	/* Overwrite the old .font file, it may contain the old font name */
//	strcpy(filename, newfontname);
//	strcat(filename, ".font");
//	if (fontfile = Open(filename, MODE_NEWFILE))
//	{
//		Write(fontfile, fontfiledata, sizeof(fontfiledata));
//		Close(fontfile);
//	}
//	else
//	{
//		MyErrorMsg1(LString(MSG_ERROR_CREATE_FILE), filename);
//		CurrentDir(oldDirLock);
//		UnLock(DirLock);
//		return FALSE;
//	}

	/* Create a new .font file (with the new name inside if there are bitmap fonts) */
	bitline(fontdrawer, newfontname, &CreateNoSizesPtr[0]);

	CurrentDir(oldDirLock);
	UnLock(DirLock);
	return TRUE;
}


/*************************************************************/
/* RemoveFont */
/* remove an installed font */
/*************************************************************/
static BOOL RemoveFont(APTR ParentWindow, char *destdrawer, char *fontname)
{
	char filename[MAXFONTPATH], *ch;
	BPTR lock;

//	if (MUI_Request(app_obj, ParentWindow, 0, NULL, "Remove|*Cancel",
//		"Warning: are you sure it is\nokay to remove\n%s\nfrom your system?\n",
//		fontname) == 1)
	{
		/* Construct the name of the bitmap directory */
		strcpy(filename, destdrawer);
		AddPart(filename, fontname, sizeof(filename));

		/* Delete all files in the bitmap directory */
// The following causes problems(E-hits). Most likely because I shouldn't be calling DoAllAssigns
// with a path rather than an assign.  In any event, it isn't really necessary, as I
// certainly don't make bitmaps, and don't plan to anytime soon.  Consider this omission
// a matter of laziness.  I'll get to this someday.
//
/* TetiSoft: uncommented the line after fixing ScanDir() */
		DoAllAssigns(filename, &ScanDir, &DeleteBitmaps);
//
// Ignore any error code from the following.

		/* Delete the bitmap directory, now that it is empty */

// TetiSoft: report errors
//		DeleteFile(filename);
		lock = Lock(filename, ACCESS_READ);
		if (lock)
		{
			UnLock(lock);
			if (!DeleteFile(filename))
				MyErrorMsg1(LString(MSG_ERROR_DELETE_DIR), filename);
		}

		/* Construct the name of the .font file */
		strcat(filename, ".font");

		/* Delete the .font file */

// TetiSoft: report errors
//		DeleteFile(filename);
		lock = Lock(filename, ACCESS_READ);
		if (lock)
		{
			UnLock(lock);
			if (!DeleteFile(filename))
				MyErrorMsg1(LString(MSG_ERROR_DELETE_FONT_FILE), filename);
		}

		/* Construct the name of the .otag file */
		ch = filename;
		while (*ch != '\0') ch++;
		ch -= 5;
		strcpy(ch, ".otag");

// TetiSoft: report errors
//		DeleteFile(filename);
		lock = Lock(filename, ACCESS_READ);
		if (lock)
		{
			UnLock(lock);
			if (!DeleteFile(filename))
				MyErrorMsg1(LString(MSG_ERROR_DELETE_OTAG_FILE), filename);
		}

		return TRUE;

	}

//	return FALSE;
}


/*************************************************************/
/* PreviewFont */
/* Display a preview of the current font */
/*************************************************************/
static BOOL PreviewFont(APTR ParentWindow, char *destdrawer, char *fontname, struct TagItem *AddOTags)
{
	char filename[MAXFONTPATH];
	char buf[20];
	LONG width, height, ileft, itop, iright, ibottom;
	struct RastPort rp;
	BOOL erasebitmap;
	BOOL rc = TRUE;
	ULONG YSizeFactor;
	ULONG SpaceWidth;
	int pixelheight, ptheight = 0;
	int fixedwidth = 0;
	int IsFixed;

	/* Construct the name of the otag file */
	strcpy(filename, destdrawer);
	AddPart(filename, fontname, sizeof(filename));
	strcat(filename, ".otag");

	/* Get the preview box size */
	get(bm_obj_preview, MUIA_InnerTop, &itop);
	get(bm_obj_preview, MUIA_InnerBottom, &ibottom);
	get(bm_obj_preview, MUIA_Height, &previewheight);
	height = previewheight;
	height -= (itop + ibottom);
	get(bm_obj_preview, MUIA_InnerLeft, &ileft);
	get(bm_obj_preview, MUIA_InnerRight, &iright);
	get(bm_obj_preview, MUIA_Width, &previewwidth);
	width = previewwidth;
	width -= (ileft + iright);
	// Now we must subtract the frame itself, didn't find a way to find out the thickness, assume 1...
	width -= 2;
	height -= 2;
	
//	pixelheight = height / 2 - 4;	// 2 pixels each on top and bottom for safety
	pixelheight = height / 2;

	/*
	 * Allocate our bitmap
	 * if it is already allocated, make sure it is the right size
	 */
	if ((bitmap != NULL) && ((bitmapwidth != width) || (bitmapheight != height)))
	{

// TetiSoft: We must free the current size, not the wanted...
//		MyFreeBitMap(bitmap, width, height);
		MyFreeBitMap(bitmap, bitmapwidth, bitmapheight);

		bitmap = NULL;
	}
	if (pixelheight < 4)
		return FALSE;
	if (bitmap == NULL)
	{
		bitmap = MyAllocBitMap(width, height);
		bitmapwidth = width;
		bitmapheight = height;
		InitBitMap(bitmap, 1, width, height);
		erasebitmap = FALSE;
	}
	else
		erasebitmap = TRUE;


	/* Construct a rastport structure using above bitmap data, for rendering */
	InitRastPort(&rp);
	rp.BitMap = bitmap;
	if (erasebitmap) EraseRect(&rp, 0, 0, width-1, height-1);

	IsFixed = YSizeFactor = SpaceWidth = 0;
	if (AddOTags)	// Called from modify window
	{
		YSizeFactor = ModifyPresets.YSizeFactor;
		SpaceWidth = ModifyPresets.SpaceWidth;
		IsFixed = ModifyPresets.IsFixed;
	} else {	// Called from main window
		struct TagItem *OTags;
		struct TagItem *tag;

		if (!ReadOTagFile(filename))
			rc = FALSE;
		else
		{
			OTags = (struct TagItem *)OTagFileBuf;
			while(tag = NextTagItem(&OTags))
			{
				switch (tag->ti_Tag)
				{
					case OT_YSizeFactor:
						YSizeFactor = tag->ti_Data;
						break;
					case OT_SpaceWidth:
						SpaceWidth = tag->ti_Data;
						break;
					case OT_IsFixed:
						IsFixed = tag->ti_Data;
						break;
				}
			}
		}
	}
	if (rc)
		if ((YSizeFactor & 0xffff0000) && (YSizeFactor & 0xffff))
			ptheight =  (pixelheight * (YSizeFactor >> 16)) / (YSizeFactor & 0xffff);
		else
			rc = FALSE;	// We could draw outside of our rastport if ascenders or descenders are higher than nominal...
	if (rc && !SpaceWidth && IsFixed)
		rc = FALSE;
	if (rc && IsFixed)
		fixedwidth = (SpaceWidth * ptheight * 72) / (2540 * 250);
	if (rc)
		/* Call lower level function to do the rendering */
		rc = RenderPreview(filename, ptheight, pixelheight, fixedwidth, &rp, 0, 0, width, height, PreviewText, PreviewText2, AddOTags);
	if (!rc)
		pixelheight = ptheight = 0;

	sprintf(buf, LString(MSG_PREVIEW_LABEL_CHANGE), pixelheight, ptheight);
	set(txt_obj_preview, MUIA_Text_Contents, buf);

	/* Update the displayed image, even if empty */
	SetAttrs(bm_obj_preview,
		 MUIA_NoNotify, TRUE,
		 MUIA_Bitmap_Width, width,
		 MUIA_Bitmap_Height, height,
		 MUIA_Bitmap_Bitmap, bitmap,
		 TAG_DONE, 0);

	return rc;
}

static struct TagItem PreviewTags[6];
static void PreviewModified(void)	// TetiSoft
{
	BPTR lock;
	FIXED SpaceWidth;
	ULONG YSizeFactor;
	int SWok, YSok;

	if (ModifyPresets.Type1FileName[0] == '\0')
	{
		MyErrorMsg(LString(MSG_ERROR_NO_TYPE1FILE));
		return;
	}
	if ((lock = Lock(ModifyPresets.Type1FileName, ACCESS_READ)) == NULL)
	{
		MyErrorMsg(LString(MSG_ERROR_TYPE1_NOT_FOUND));
		return;
	}
	UnLock(lock);
	SWok = (ModifyPresets.SpaceWidth != 0);
	YSok = (((ModifyPresets.YSizeFactor & 0xffff0000) != 0) && ((ModifyPresets.YSizeFactor & 0xffff) != 0));
	if (!SWok || !YSok) {
		if (CalcSpaceWidthYSizeFactor(window_obj_modify,
					      ModifyPresets.Type1FileName,
					      ModifyPresets.IsFixed,
					      ModifyPresets.SymbolSet,
					      &SpaceWidth, &YSizeFactor))
		{
			if (!SWok)
			{
				ModifyPresets.SpaceWidth  = SpaceWidth;
				SetAttrs(string_obj_spacew,   MUIA_NoNotify, TRUE, MUIA_String_Integer, SpaceWidth,           TAG_DONE, 0);
			}
			if (!YSok)
			{
				ModifyPresets.YSizeFactor = YSizeFactor;
				SetAttrs(string_obj_ysizefph, MUIA_NoNotify, TRUE, MUIA_String_Integer, YSizeFactor >> 16,    TAG_DONE, 0);
				SetAttrs(string_obj_ysizefbh, MUIA_NoNotify, TRUE, MUIA_String_Integer, YSizeFactor & 0xffff, TAG_DONE, 0);
			}
		}
	}
	PreviewTags[0].ti_Tag	= OT_Spec1_PFABFileName;
	PreviewTags[0].ti_Data	= (ULONG)&ModifyPresets.Type1FileName;
	PreviewTags[1].ti_Tag	= OT_Spec2_AFMFileName;
	PreviewTags[1].ti_Data	= (ULONG)&ModifyPresets.AFMFileName;
	PreviewTags[2].ti_Tag	= OT_IsFixed;
	PreviewTags[2].ti_Data	= ModifyPresets.IsFixed;
	PreviewTags[3].ti_Tag	= OT_SymbolSet;
	PreviewTags[3].ti_Data	= ModifyPresets.SymbolSet;
	PreviewTags[4].ti_Tag	= ModifyPresets.SpaceWidth ? OT_SpaceWidth : TAG_IGNORE;
	PreviewTags[4].ti_Data	= ModifyPresets.SpaceWidth;
	PreviewTags[5].ti_Tag	= TAG_DONE;
	PreviewTags[5].ti_Data	= 0;
	PreviewFont(window_obj_main, blFontDir, blFontName, &PreviewTags[0]);
}


/*************************************************************/
/* MyErrorMsg */
/* display an error with muimaster.library/MUI_Request */
/*************************************************************/
void MyErrorMsg(char *ErrorMsg)
{
	(void)MUI_Request(app_obj, NULL, 0L, LString(MSG_REQ_ERRORTITLE), LString(MSG_REQ_OK), ErrorMsg);
}

// TetiSoft
void MyWarningMsg(char *WarningMsg)
{
	(void)MUI_Request(app_obj, NULL, 0L, LString(MSG_REQ_WARNTITLE), LString(MSG_REQ_OK), WarningMsg);
}

/*************************************************************/
/* Add font to listview, given name of otag file and */
/* the memory copy of the otag file */
/*************************************************************/
void AddFontToListview(char *otagname, char *filebuf)
{
	char fontname[MAXFONTPATH], *ch;

	strcpy(fontname, otagname);
	ch = fontname;
	while (*ch && (*ch != '.')) ch++;
	if (*ch == '.') *ch = '\0';
	ch = fontname;
	DoMethod(listview_obj, MUIM_List_Insert, &ch, 1, MUIV_List_Insert_Sorted);

	return;
}


/*************************************************************/
/* Allocate a single plane bitmap, using either V39 or V37 */
/* functions as appropriate. */
/* Returns NULL on error */
/*************************************************************/
static struct BitMap *MyAllocBitMap(int width, int height)
{
	struct BitMap *bitMap/* = NULL*/;	// TetiSoft

	if (can_use_V39_funcs == 1)
	{
		bitMap = AllocBitMap(width, height, 1, BMF_CLEAR, NULL);
	}
	else
	{
		bitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap), MEMF_CLEAR);
		if (bitMap)
		{
			InitBitMap(bitMap, 1, width, height);
			bitMap->Planes[0] = (PLANEPTR) AllocRaster(width, height);
			if (bitMap->Planes[0] == NULL)
			{
				FreeVec(bitMap);
				bitMap = NULL;
			}
		}
	}

	return bitMap;
}


/*************************************************************/
/* Free a single plane bitmap, using V39 or V37 functions as */
/* appropriate. Can be called with a NULL input. */
/*************************************************************/
static void MyFreeBitMap(struct BitMap *bitMap, int width, int height)
{
	if (bitMap)
	{
		if (can_use_V39_funcs == 1)
		{
			FreeBitMap(bitMap);
		}
		else
		{
			FreeRaster(bitMap->Planes[0], width, height);
			FreeVec(bitMap);
		}
	}
}

// TetiSoft: Add a bitmap size to sizelist
static int AddSize(struct AvailSizeList *list, long size)
{
	int i;
	if (!list || !size || (size <= 0) || (size > 124) || (list->Count >= OT_MAXAVAILSIZES))
		return FALSE;
	for(i = 0; i < list->Count; i++)
	{
		if (size == list->Sizes[i])
			return FALSE;
		else if (size < list->Sizes[i])
		{
			int j;
			for(j = list->Count; j >= i; j--)
				list->Sizes[j] = list->Sizes[j-1];
			list->Sizes[i] = size;
			list->Count++;
			return TRUE;
		}
	}
	list->Sizes[i] = size;
	list->Count++;
	return TRUE;
}

// TetiSoft: Delete a bitmap size from sizelist
static int DelSize(struct AvailSizeList *list, long size)
{
	int i;
	if (!list)
		return FALSE;
	for(i = 0; i < list->Count; i++)
	{
		if (size == list->Sizes[i])
		{
			for(; i < (list->Count - 1); i++)
				list->Sizes[i] = list->Sizes[i+1];
			list->Count--;
			return TRUE;
		}
	}
	return FALSE;
}

// TetiSoft: Add bitmap file to bitmap list
static void AddBitmapsToList(char *filename, int filesize)
{
	char *ch;

	if (filename)
	{
		for (ch = filename; *ch != '\0'; ch++)
			if ((*ch < '0') || (*ch > '9'))
				break;

		/* Filename is numeric */
		if ((ch != filename) && (*ch == '\0'))
			AddSize(&AvailBMSizes, atol(filename));
	}
}

// TetiSoft: Delete unwanted and create wanted bitmaps
static LONG CreateSizes[OT_MAXAVAILSIZES + 1];
static LONG *CreateSizesPtr[OT_MAXAVAILSIZES + 1];
static void HandleBitmaps(struct AvailSizeList *there, struct AvailSizeList *wanted, int RebuildBitmaps)
{
	int i, j, found, create = 0;

	for (i = 0; i < there->Count; i++)
	{
		for (j = 0, found = FALSE; j < wanted->Count; j++)
		{
			if (there->Sizes[i] == wanted->Sizes[j])
			{
				found = TRUE;
				break;
			}
		}
		if (!found || RebuildBitmaps)
			DeleteBitmap(there->Sizes[i]);
	}
	if (there->Count && !wanted->Count && !DeleteFile(FontDirName))	// Delete empty font directory
		MyErrorMsg1(LString(MSG_ERROR_DELETE_DIR), FontDirName);
	if (RebuildBitmaps && there->Count)
	{
		int afShortage, afSize;
		struct AvailFontsHeader *afh;
		int j = 0, fontexists;
		static char fontfilename[MAXFONTPATH];

		SystemTags("C:Avail >NIL: FLUSH", TAG_END, 0);	// flush old unused bitmap fonts from memory

/* TetiSoft: We must ensure that no bitmap font of a size we want to create is currently used */
		afSize = 1024;
		do
		{
			afh = (struct AvailFontsHeader *)AllocMem(afSize, 0);
			if (afh)
			{
				afShortage = AvailFonts((STRPTR)afh, afSize, AFF_MEMORY|AFF_BITMAP);
				if (afShortage)
				{
					FreeMem(afh, afSize);
					afSize += afShortage;
				}
			} else {
				MyErrorMsg(LString(MSG_ERROR_NOMEM_AVAILFONTS));
				strcpy(fontfilename, blFontDir);
				AddPart(fontfilename, blFontName, MAXFONTPATH);
				strcat(fontfilename, ".font");
				OverWriteFontFile(fontfilename);
				if (!DeleteFile(FontDirName))	// Delete empty font directory
					MyErrorMsg1(LString(MSG_ERROR_DELETE_DIR), FontDirName);
				return;	// Don't create anything
			}
		} while (afShortage);

		strcpy(fontfilename, blFontName);
		strcat(fontfilename, ".font");
		for (i = 0, fontexists = FALSE; (i < afh->afh_NumEntries) && !fontexists; i++)
		{
			struct AvailFonts *af = (struct AvailFonts *)(&afh[1]);
			if (!stricmp(af[i].af_Attr.ta_Name, fontfilename))
			{
				for (j = 0; j < there->Count; j++)
				{
					if (there->Sizes[j] == af[i].af_Attr.ta_YSize)
					{
						fontexists = TRUE;
						break;
					}
				}
			}
		}
		FreeMem(afh, afSize);
		if (fontexists)
		{
			MyWarningMsg1(LString(MSG_ERROR_BITMAPINUSE), there->Sizes[j]);
			strcpy(fontfilename, blFontDir);
			AddPart(fontfilename, blFontName, MAXFONTPATH);
			strcat(fontfilename, ".font");
			OverWriteFontFile(fontfilename);
			if (!DeleteFile(FontDirName))	// Delete empty font directory
				MyErrorMsg1(LString(MSG_ERROR_DELETE_DIR), FontDirName);
			return;	// Don't create anything
		}
	}
	if (RebuildBitmaps)
		there->Count = 0;
	for (i = 0; i < wanted->Count; i++)
	{
		for (j = 0, found = FALSE; j < there->Count; j++)
		{
			if (wanted->Sizes[i] == there->Sizes[j])
			{
				found = TRUE;
				break;
			}
		}
		if (!found) {
			CreateSizes[create] = wanted->Sizes[i];
			CreateSizesPtr[create] = &CreateSizes[create];
			create++;
		}
	}
	if (create)
	{
		CreateSizes[create] = 0;
		CreateSizesPtr[create] = NULL;
		bitline(blFontDir, blFontName, &CreateSizesPtr[0]);
	}
}

// TetiSoft: Delete unwanted bitmap file
static void DeleteBitmap(long size)
{
	static char filename[300];
	sprintf(filename, "%s/%ld", FontDirName, size);
	if (!DeleteFile(filename))
		MyErrorMsg1(LString(MSG_ERROR_DELETE_BITMAP_FILE), filename);
}

// TetiSoft: Overwrite .font file if bitmap file creation failed
static unsigned char fontfiledata[] = {0x0f, 0x03, 0x00, 0x00};	// Outline-font associated bitmap font with NO sizes
static void OverWriteFontFile(char *fontfilename)
{
	BPTR fontfile;
	if (fontfile = Open(fontfilename, MODE_NEWFILE))
	{
		if (Write(fontfile, fontfiledata, sizeof(fontfiledata)) != sizeof(fontfiledata))
		{
			MyErrorMsg1(LString(MSG_ERROR_WRITE), fontfilename);
			Close(fontfile);
			DeleteFile(fontfilename);
			return;
		}
		Close(fontfile);
	} else
		MyErrorMsg1(LString(MSG_ERROR_CREATE_FILE), fontfilename);
}
