/*
 *
 * $VER: Dynamic.c 1.1 (20.2.98)
 *
 * Popup Menu example program
 *
 * ©1996-1998 Henrik Isaksson
 * All Rights Reserved.
 *
 * Run and click the mouse in the window!
 *
 */

#include <intuition/intuition.h>
#include <exec/memory.h>

#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <libraries/pm.h>
#include <proto/pm.h>

struct IntuitionBase	*IntuitionBase;
struct GfxBase		*GfxBase;
struct PopupMenuBase	*PopupMenuBase;

struct Window *w;	// This window is only needed to find out when and where the menu should appear.
			// The font in this window's rastport will be used for the menu.

struct PopupMenu * __saveds __asm SubConstructFunc(register __a0 struct Hook *hook,
				     register __a2 struct PopupMenu *selected)
{
	struct PopupMenu *newpm;
	char bfr[128];

	// Don't try to open windows, requesters or printing text from this
	// hook, wich is called while the menu is still open. (ofcourse)
	// The display might be locked!

	// A random number to prove that it works...
	sprintf(bfr, "Random number: %ld", rand());

	newpm=PM_MakeMenu(
		PMItem("It works"),	PMEnd,
		PMItem("Yes, it does!"), PMEnd,
		PMItem(bfr),		PMEnd,
	PMEnd;		

	if(newpm) {
		if(selected->Sub) {
			// We don't have to worry about freeing the new menu,
			// as it will be freed automatically. But we do have
			// to take care of the old menu, since the library
			// won't know it exists.
			PM_FreePopupMenu(selected->Sub);
		}
		selected->Sub=newpm;
	}

	return selected->Sub;	// If you return NULL, no menu will be opened.
}

struct Hook SubConstruct;

struct PopupMenu *MakeTestMenu(void);

void main()
{
	struct IntuiMessage *im,imsg;
	struct PopupMenu *p;
	BOOL r=TRUE;

	SubConstruct.h_Entry=(HOOKFUNC)SubConstructFunc;
	SubConstruct.h_Data=NULL;	// User Data - you can put anything you like to here.

	PopupMenuBase=(struct PopupMenuBase *)OpenLibrary(POPUPMENU_NAME,POPUPMENU_VERSION);			// Open the library
	if(PopupMenuBase) {
		IntuitionBase=(struct IntuitionBase *)PopupMenuBase->pmb_IntuitionBase;	// We let popupmenu.library open the libraries we need
		GfxBase=(struct GfxBase *)PopupMenuBase->pmb_GfxBase;			// They remain valid until the library is closed!

		p=MakeTestMenu(); // Declared at the end of this file.

		if(p) {
			w=OpenWindowTags(NULL,	WA_IDCMP,	IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_VANILLAKEY,	// Open a little window
					WA_RMBTrap,	TRUE,
					WA_DragBar,	TRUE,
					WA_Width,	150,
					WA_Height,	100,
					WA_Left,	0,
					WA_Top,		100,
					WA_Title,	"Dynamic Menus",
					WA_CloseGadget,	TRUE,
					TAG_DONE);
			if(w) {
				while(r) {
					WaitPort(w->UserPort);						// Wait for a message
					while((im=(struct IntuiMessage *)GetMsg(w->UserPort))) {	// Get the message
						CopyMem(im,&imsg,sizeof(struct IntuiMessage));		// Copy the contents of it
						ReplyMsg((struct Message *)im);				// Reply the message

						if(imsg.Class==IDCMP_MOUSEBUTTONS) {
							PM_OpenPopupMenu(w,
								PM_Menu,		p,
								TAG_DONE);
						}
						if(imsg.Class==IDCMP_CLOSEWINDOW) r=FALSE;		// See if the user wants to quit
					}
				}
				CloseWindow(w);
			} else printf("Window error!\n");
			PM_FreePopupMenu(p);
		} else printf("Menu error!\n");
		CloseLibrary((struct Library *)PopupMenuBase);
	}
}

struct PopupMenu *MakeTestMenu()
{
	struct PopupMenu *p;

	p=PM_MakeMenu(
		PMItem("Dynamic submenu"),
			PM_SubConstruct,	&SubConstruct,
			PMSimpleSub,
				PMInfo("This won't work unless"),	End,	// this will be shown if the demo doesn't work
				PMInfo("you get version 7.4!"),		End,	// (maybe an old version of the library)
			End,
		End,
	End;

	return p;
}