/*
 *  Simple Demonstration Program Using Pop-up Menus
 *
 *  Written by Derek Zahn (Gambit Software, Madison WI), July 1987
 *
 *  This code is freely distributable and is blessed by its author for
 *  inclusion, in this form or any other, into Amiga programs,
 *  commercial or non-commercial.  If this is done, no credit must be
 *  given to me (although I wouldn't mind).
 *
 *  I think that the movmem() function used here is Manx-specific.  This
 *  code developed and tested under 1.2 and Manx C v. 3.40a
 */

/* include files */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#include "popmenu.h"

extern LONG PopChoose();  /* the Pop-up Menu call */

extern VOID CloseLibrary(), CloseWindow(), ReplyMsg(), FreeMem();
extern struct IntuiMessage *GetMsg();
extern struct Window *OpenWindow();
extern APTR OpenLibrary(), AllocMem();

/* This is the window in which the pop-up menus will appear */

struct NewWindow demo_window = {
	100, 50,
	300, 50,
	(UBYTE) -1, (UBYTE) -1,
	MOUSEBUTTONS | CLOSEWINDOW,
	ACTIVATE | RMBTRAP | WINDOWCLOSE | WINDOWDRAG,
	NULL,
	NULL,
	(UBYTE *) "Pop-up menu demo",
	NULL,
	NULL,
	0, 0,
	0, 0,
	WBENCHSCREEN
};

/* Following are the two images that are used in the demo menu */

#define PIC2SIZE 240
USHORT *chipped_pic2;

USHORT demo_pic2_imageData[] =
{
0xFFFF,0xFFFF,0xFF80,0xFFFF,0xFFFF,0xFF80,
0xFC1F,0xC1FC,0x1F80,0xF80F,0x80F8,0x0F80,
0xF007,0x0070,0x0780,0xE082,0x0820,0x8380,
0xF007,0x0070,0x0780,0xF80F,0x80F8,0x0F80,
0xFC1F,0xC1FC,0x1F80,0xFEBF,0xF7FE,0xBF80,
0xFF7F,0xEBFF,0x7F80,0xFC1F,0xC1FC,0x1F80,
0xF80F,0x80F8,0x0F80,0xF007,0x0070,0x0780,
0xE082,0x0820,0x8380,0xF007,0x0070,0x0780,
0xF80F,0x80F8,0x0F80,0xFC1F,0xC1FC,0x1F80,
0xFFFF,0xFFFF,0xFF80,0xFFFF,0xFFFF,0xFF80,

0x0000,0x0000,0x0000,0x03E0,0x3E03,0xE000,
0x0410,0x4104,0x1000,0x0BE8,0xBE8B,0xE800,
0x1635,0x6356,0x3400,0x2EBA,0xEBAE,0xBA00,
0x1635,0x6356,0x3400,0x0BE8,0xBE8B,0xE800,
0x0410,0x4104,0x1000,0x03E0,0x3E03,0xE000,
0x03E0,0x3E03,0xE000,0x0410,0x4104,0x1000,
0x0BE8,0xBE8B,0xE800,0x1635,0x6356,0x3400,
0x2EBA,0xEBAE,0xBA00,0x1635,0x6356,0x3400,
0x0BE8,0xBE8B,0xE800,0x0410,0x4104,0x1000,
0x03E0,0x3E03,0xE000,0x0000,0x0000,0x0000
};
struct Image demo_pic2_image =
{
10,0,          /* LeftEdge, TopEdge */
41,20,2,      /* Width, Height, Depth */
NULL,        /* filled in later */
3,0,        /* PlanePick, PlaneOnOff */
NULL,        /* Pointer to next Image */
};

#define PIC1SIZE 96
USHORT *chipped_pic1;

USHORT demo_pic1_imageData[] =
{
0xFFFF,0xFFFF,0xC000,0xFFFC,0x07FF,0xC000,
0xFFFB,0xFBFF,0xC000,0xE007,0xFC01,0xC000,
0xE007,0xFC01,0xC000,0xFFFB,0xFBFF,0xC000,
0xFFFC,0x07FF,0xC000,0xFFFF,0xFFFF,0xC000,

0x0000,0x0000,0x0000,0x0002,0x0000,0x0000,
0x0004,0x3400,0x0000,0x1FF8,0x6000,0x0000,
0x0000,0x63FE,0x0000,0x0004,0x6400,0x0000,
0x0002,0x0000,0x0000,0x0000,0x0000,0x0000
};

struct Image demo_pic1_image =
{
10,1,          /* LeftEdge, TopEdge */
34,8,2,      /* Width, Height, Depth */
NULL,  /* Set Later */
3,0,        /* PlanePick, PlaneOnOff */
NULL,        /* Pointer to next Image */
};

/* This is the list of demo menu MenuItems.  Note the use of the flags and */
/* the effects they have on what is displayed.                             */

struct IntuiText demo_text6_text = {
	(UBYTE) 0, (UBYTE) 1,
	JAM1,
	(SHORT) 2 + CHECKWIDTH, (SHORT) 2,
	NULL,
	(UBYTE *) "Mut Ex 3",
	NULL
};

struct MenuItem demo_text6 = {
	NULL,
	(SHORT) 0, (SHORT) 90,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT),
	(LONG) 0x0c0,
	(APTR) &demo_text6_text,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct IntuiText demo_text5_text = {
	(UBYTE) 0, (UBYTE) 1,
	JAM1,
	(SHORT) 2 + CHECKWIDTH, (SHORT) 2,
	NULL,
	(UBYTE *) "Mut Ex 2",
	NULL
};

struct MenuItem demo_text5 = {
	&demo_text6,
	(SHORT) 0, (SHORT) 80,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT),
	(LONG) 0x140,
	(APTR) &demo_text5_text,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct IntuiText demo_text4_text = {
	(UBYTE) 0, (UBYTE) 1,
	JAM1,
	(SHORT) 2 + CHECKWIDTH, (SHORT) 2,
	NULL,
	(UBYTE *) "Mut Ex 1",
	NULL
};

struct MenuItem demo_text4 = {
	&demo_text5,
	(SHORT) 0, (SHORT) 70,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT),
	(LONG) 0x180,
	(APTR) &demo_text4_text,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct IntuiText demo_text3_text = {
	(UBYTE) 2, (UBYTE) 1,
	JAM1,
	(SHORT) 2, (SHORT) 2,
	NULL,
	(UBYTE *) "Shadow",
	NULL
};

struct MenuItem demo_text3 = {
	&demo_text4,
	(SHORT) 0, (SHORT) 60,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT),
	(LONG) 0,
	(APTR) &demo_text3_text,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct MenuItem demo_image3 = {
	&demo_text3,
	(SHORT) 5, (SHORT) 40,
	(SHORT) 60, (SHORT) 20,
	(USHORT) (HIGHBOX | ITEMENABLED),
	(LONG) 0,
	(APTR) &demo_pic2_image,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct MenuItem demo_image2 = {
	&demo_image3,
	(SHORT) 0, (SHORT) 30,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (HIGHBOX),
	(LONG) 0,
	(APTR) &demo_pic1_image,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct IntuiText demo_text2_text = {
	(UBYTE) 0, (UBYTE) 1,
	JAM1,
	(SHORT) 2 + CHECKWIDTH, (SHORT) 2,
	NULL,
	(UBYTE *) "Text 2",
	NULL
};

struct IntuiText demo_text2_alt = {
	(UBYTE) 3, (UBYTE) 1,
	JAM1,
	(SHORT) 2 + CHECKWIDTH, (SHORT) 2,
	NULL,
	(UBYTE *) "tEXT 2",
	NULL
};

struct MenuItem demo_text2 = {
	&demo_image2,
	(SHORT) 0, (SHORT) 20,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT | HIGHIMAGE | ITEMENABLED | CHECKIT | MENUTOGGLE),
	(LONG) 0,
	(APTR) &demo_text2_text,
	(APTR) &demo_text2_alt,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct MenuItem demo_image1 = {
	&demo_text2,
	(SHORT) 0, (SHORT) 10,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (HIGHCOMP | ITEMENABLED),
	(LONG) 0,
	(APTR) &demo_pic1_image,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

struct IntuiText demo_text1_text = {
	(UBYTE) 0, (UBYTE) 1,
	JAM1,
	(SHORT) 2, (SHORT) 2,
	NULL,
	(UBYTE *) "Text 1",
	NULL
};

struct MenuItem demo_text1 = {
	&demo_image1,
	(SHORT) 0, (SHORT) 0,
	(SHORT) 100, (SHORT) 10,
	(USHORT) (ITEMTEXT | HIGHBOX | ITEMENABLED),
	(LONG) 0,
	(APTR) &demo_text1_text,
	NULL,
	(BYTE) 0,
	NULL,
	(USHORT) 0
};

/* This menu is attached to the Right mouse button.  It shows the use of a */
/* title, and the POPPOINTREL and POPTIDY flags for menu positioning.      */

struct Menu demo_menu1 = {
	NULL,
	(SHORT) -1 * ((102 + POPTITLEHEIGHT) / 2),
	(SHORT) -1 * POPTITLEHEIGHT / 2,
	(SHORT) 100, (SHORT) 102 + POPTITLEHEIGHT,
	(USHORT) (MENUENABLED | POPTIDY | POPPOINTREL | POPRIGHTBUTTON | 
	  POPTRIGGERUP),
	(BYTE *) "Sample",
	&demo_text1
};

/* This menu is attached to the Left mouse button.  It is title-less (note */
/* that it is shorter than the one with the title).  This demonstrates the */
/* POPREMEMBER flag and the lack of POPTIDY.  Note that it uses the same   */
/* MenuItems as demo_menu1; this is only a demo, and that was easy         */

struct Menu demo_menu2 = {
	NULL,
	(SHORT) 0, (SHORT) 0,
	(SHORT) 100, (SHORT) 102,
	(USHORT) (MENUENABLED | POPPOINTREL | POPLEFTBUTTON | 
	  POPTRIGGERUP | POPREMEMBER),
	NULL,
	&demo_text1
};

/* In order to use the pop-up menus, the application MUST make the         */
/* following declarations.                                                 */

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

main()
{
	struct Window *win;
	SHORT val, class, code;
	struct IntuiMessage *message;

	/* The libraries MUST be opened in this or a similar manner in     */
	/* order to use pop-up menus.                                      */

	IntuitionBase = (struct IntuitionBase *) 
	  OpenLibrary("intuition.library", 0L);
	if(!IntuitionBase)
		exit(0);
	GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L);
	if(!GfxBase) {
		CloseLibrary(IntuitionBase);
		exit(0);
	}

	win = OpenWindow(&demo_window);
	if(!win) {
		CloseLibrary(IntuitionBase);
		CloseLibrary(GfxBase);
	}

	/* make sure the image data is in CHIP ram */

	chipped_pic1 = (USHORT *) AllocMem((LONG) PIC1SIZE, MEMF_CHIP);
	movmem(&demo_pic1_imageData[0], chipped_pic1, PIC1SIZE);
	demo_pic1_image.ImageData = chipped_pic1;
	chipped_pic2 = (USHORT *) AllocMem((LONG) PIC2SIZE, MEMF_CHIP);
	movmem(&demo_pic2_imageData[0], chipped_pic2, PIC2SIZE);
	demo_pic2_image.ImageData = chipped_pic2;

	while(1) {
		Wait((ULONG) 1L << win->UserPort->mp_SigBit);
		while(message = GetMsg(win->UserPort)) {
			class = message->Class;
			code = message->Code;
			ReplyMsg(message);
			switch(class) {
			  case MOUSEBUTTONS:
			  	switch(code) {
				  case SELECTDOWN:
					val = (SHORT) PopChoose(&demo_menu2,
					  win);
					printf("val %d\n", val);
					break;
				  case MENUDOWN:
					val = (SHORT) PopChoose(&demo_menu1,
					  NULL);
					printf("val %d\n", val);
					break;
				  default:
				  	break;
				}
				break;
			  case CLOSEWINDOW:
			  	CloseWindow(win);
				CloseLibrary(IntuitionBase);
				CloseLibrary(GfxBase);
				FreeMem(chipped_pic1, (LONG) PIC1SIZE);
				FreeMem(chipped_pic2, (LONG) PIC2SIZE);
				exit(0);
			  default:
			  	break;
			}
		}

	}
}
