/*
 * Dynamic Intuition menu functions
 * from the author of PDTerm
 */

#include "exec/types.h"
#include "exec/memory.h"
#include "graphics/text.h"
#include "intuition/intuition.h"
#define	MEMFLAGS (LONG) (MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)

extern	char	*AllocMem();
extern	LONG	FreeMem();

/*
 * Create an instance of an Intuitext structure
 * containing text, positioned at (left,top)
 */

struct IntuiText *NewIText(text, left, top)
char *text;
int left, top;
{
	struct IntuiText *newtext = NULL;

	newtext = (struct IntuiText *)
		AllocMem((LONG) sizeof(*newtext), MEMFLAGS);
	newtext->IText = (UBYTE *)text;
	newtext->FrontPen = 0;
	newtext->BackPen = 1;
	newtext->DrawMode = JAM2;
	newtext->LeftEdge = left;
	newtext->TopEdge = top;
	newtext->ITextFont = NULL;
	newtext->NextText = NULL;

	return(newtext);
}

/*
 * Add an Intuitext structure to the end of
 * list of them, returning a pointer to the
 * new Intuitext.
 */

struct IntuiText *AddIText(IText, text)
struct IntuiText *IText;
char *text;
{
	struct IntuiText *newtext = NULL;

	newtext = (struct IntuiText *)
		AllocMem((LONG) sizeof(*newtext), MEMFLAGS);
                
	newtext->IText = (UBYTE *)text;
	newtext->FrontPen = IText->FrontPen;
	newtext->BackPen  = IText->BackPen;
	newtext->DrawMode = IText->DrawMode;
	newtext->LeftEdge = IText->LeftEdge;
	newtext->TopEdge  = IText->TopEdge + 11;
	newtext->ITextFont = IText->ITextFont;
	newtext->NextText = NULL;
	IText->NextText   = newtext;

	return(newtext);
}

/*
 * Dispose of a lise of IntuiText structures
 */

DisposeIText(IText)
struct IntuiText *IText;
{
	struct IntuiText *cur, *next;

	cur = IText;
	for(next = cur->NextText; cur != NULL; next = next->NextText) {
		FreeMem(cur,(LONG) sizeof(*cur));
		cur = next;
	}
}


/*
 * Dynamic menu constructor functions
 */

#define InterMenuWidth 15

/*
 * Create a new menu structure.
 */

struct Menu *NewMenu(menuname, width, height)
char *menuname;
int width, height;
{
	struct Menu *menu = NULL;

	menu = (struct Menu *)
		AllocMem((LONG) sizeof(*menu), MEMFLAGS);

	menu->NextMenu = NULL;
	menu->LeftEdge = 0;
	menu->TopEdge = 0;
	menu->Width = width;
	menu->Height = height;
	menu->Flags = MENUENABLED;
	menu->MenuName = menuname;
	menu->FirstItem = NULL;

	return(menu);
}

/*
 * Create a new menu and add it to
 * the end of the list of menus.
 */
struct Menu *AddMenu(menus, MenuName, width, height)
struct Menu *menus;
char *MenuName;
int width, height;
{
	struct Menu *newmenu;

	newmenu = NewMenu(MenuName, width, height);
	newmenu->LeftEdge = menus->LeftEdge + menus->Width + InterMenuWidth;
	menus->NextMenu = newmenu;
	return(newmenu);
}

/*
 * Create a new menu item
 */

struct MenuItem *NewMenuItem(name, width, height)
char *name;
int width, height;
{
	struct MenuItem *newitem = NULL;
	struct IntuiText *NewIText(), *newtext = NULL;

	newitem = (struct MenuItem *)
		AllocMem((LONG) sizeof(*newitem), MEMFLAGS);

	newtext = NewIText(name,0,1);

	newitem->NextItem = NULL;
	newitem->ItemFill = (APTR) newtext;
	newitem->LeftEdge = 0;
	newitem->TopEdge = 0;
	newitem->Width = width;
	newitem->Height = height;
	newitem->Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
	newitem->MutualExclude = 0;
	newitem->SelectFill = NULL;
	newitem->Command = 0;
	newitem->SubItem = NULL;
	newitem->NextSelect = 0;

	return(newitem);
}

/*
 * Start the menu item list for a menu.
 */

struct MenuItem *AddNewMenuItem(menu, name, width, height)
struct Menu *menu;
char *name;
int width, height;
{
	struct MenuItem *newitem, *NewMenuItem();

	newitem = NewMenuItem(name, width, height);
	menu->FirstItem = newitem;
	return(newitem);
}

/*
 * Add to a menu item list
 */

struct MenuItem *AddItem(items, name)
struct MenuItem *items;
char *name;
{
	struct MenuItem *newitem, *NewMenuItem();

	newitem = NewMenuItem(name, items->Width, items->Height);
	newitem->TopEdge = items->TopEdge + items->Height;
	newitem->LeftEdge = items->LeftEdge;
	items->NextItem = newitem;
	return(newitem);
}

/*
 * Start a list of subitems for a menu item.
 */

struct MenuItem *AddNewSubItem(item, name, width, height)
struct MenuItem *item;
char *name;
int width, height;
{
	struct MenuItem *newitem, *NewMenuItem();

	newitem = NewMenuItem(name, width, height);
	item->SubItem = newitem;
	newitem->LeftEdge = item->Width;
	return(newitem);
}

/*
 * Dispose of a menu item.
 */

DisposeItem(item)
struct MenuItem *item;
{
	DisposeIText((struct ItuiText *)item->ItemFill);
	FreeMem(item,(LONG) sizeof(*item));
}

/*
 * Dispose of a list of menu items.
 */

DisposeItems(items)
struct MenuItem *items;
{
	struct MenuItem *cur, *next;

	cur = items;
	for(next = cur->NextItem; cur != NULL; next = next->NextItem){
		DisposeItem(cur);
		cur = next;
	}
}

/*
 * Dispose of a single menu
 */
DisposeMenu(menu)
struct Menu *menu;
{
	DisposeItems(menu->FirstItem);
	FreeMem(menu,(LONG) sizeof(*menu));
}

/*
 * Get rid of a menu list.
 */
DisposeMenus(menus)
struct Menu *menus;
{
	struct Menu *cur, *next;

	cur = menus;
	for(next = cur->NextMenu; cur != NULL; next = next->NextMenu){
		DisposeMenu(cur);
		cur = next;
	}
}

