#include <stdio.h>
#include <X10/Xlib.h>
#include "MenuMgr.h"

#define gray_width 16
#define gray_height 16
static unsigned short gray_bits[] = {
   0xaaaa, 0x5555, 0xaaaa, 0x5555,
   0xaaaa, 0x5555, 0xaaaa, 0x5555,
   0xaaaa, 0x5555, 0xaaaa, 0x5555,
   0xaaaa, 0x5555, 0xaaaa, 0x5555};

#include "menuicon.bitmap"

MenuBarPtr	menubar;
Window		icon, pw, sw;
FontInfo *	fi;

extern int	mm_debug;
extern Defaults	mm_Defs;
extern FontFamily	mm_Fonts;

#define max(a,b)	((a) > (b) ? (a) : (b))

static int Done = 0;

main(argc,argv)

	int	argc;
	char *	argv[];
{
int	i,n;
char *	list;
char *	fontname = "helv12";
char	fn[64];
char *	iconname;
XEvent	event;
int	HandleName();
int	HandleMenu();
Bitmap	graybitmap;
Pixmap	graypixmap;
Bitmap	iconbitmap;
Pixmap	iconpixmap;
int	twidth, theight;
char *	display_name;
char *	getenv();
DefsPtr	d = &mm_Defs;
XKeyPressedEvent *kev;
char *	keystr;
WindowInfo	pwi, swi;

	mm_debug = 0;

	if( XOpenDisplay()==NULL )
	{
		if( display_name = getenv("DISPLAY") )
			fprintf(stderr,"%s: unable to open display < %s >.\n",
				argv[0],display_name);
		else
			fprintf(stderr,"%s: DISPLAY variable not set!\n",
				argv[0]);
		exit(1);			
	}

	graybitmap = XStoreBitmap(gray_width,gray_height,gray_bits );
	graypixmap = XMakePixmap( graybitmap,BlackPixel,WhitePixel );
	iconbitmap = XStoreBitmap(menuicon_width,menuicon_height,menuicon_bits );
	iconpixmap = XMakePixmap( iconbitmap,BlackPixel,WhitePixel );
	if( (fi = XOpenFont( fontname )) == NULL )
	{
		fprintf(stderr,"%s: couln't open font %s\n",argv[0],fontname);
		exit(-1);
	}

	pw = XCreateWindow( RootWindow, 200,200,400,400,
		1,BlackPixmap,graypixmap );

	sprintf(fn,"%s: MENU",argv[0]);
	twidth = max( XStringWidth( fn, fi, 0, 0 ), menuicon_width ) + 10;
	theight = menuicon_height + fi->height + 15;
	icon = XCreateWindow( RootWindow, DisplayWidth()-(100+twidth),100,
		twidth, theight,
		2,BlackPixmap,WhitePixmap );
	XSetIconWindow( pw, icon );
	XSelectInput( icon, ExposeWindow|ExposeRegion|ButtonPressed );
	XStoreName( icon, fn );

	mm_InitMenus(argv[0]);
	menubar = mm_GetMenuBar( argv[0], 1, "Visual Courseware Group" );
	if( !menubar )
		exit(1);

	sw = XCreateWindow( pw, 0,400-mm_MBarsHeight(d,mm_Fonts),
		400,mm_MBarsHeight(d,mm_Fonts),
		0,graypixmap,WhitePixmap );

	mm_SetNameCallback( menubar, HandleName );
	mm_SetMenuCallback( menubar, HandleMenu );	
	mm_AttachMenuBar( menubar, sw );

	/* note: since the menu is in a sub-window, we
		will have to resize the subwindow when
		the parent gets resized */

	XSelectInput( pw, KeyPressed|ExposeWindow|ExposeRegion );
	XMapWindow(pw);
	XMapSubwindows(pw);
	XMapWindow(sw);
	XMapSubwindows(sw);

	while(!Done)
	{
		XNextEvent(&event);
		mm_HandleEvent(&event);
		if( event.window == pw && 
			(event.type == KeyPressed) ) 
		{
			kev = (XKeyPressedEvent *)&event;
			if( kev->detail & MetaMask )
			{
				kev->detail &= ~MetaMask;
				keystr = XLookupMapping(kev,&n);
				if( n==1 )
					mm_MenuKey(menubar,(int)(*keystr));
			}				
		}
		else if( event.window == pw &&
			(event.type == ExposeWindow) && !event.subwindow )
		{
			/* check to see if the parent has been resized */
			XQueryWindow( pw, &pwi );
			XQueryWindow( sw, &swi );

			if( swi.width != pwi.width ||
			    swi.y != (pwi.height-mm_MBarsHeight(d,mm_Fonts)) )
				XConfigureWindow( sw, 
					0,
					pwi.height-mm_MBarsHeight(d,mm_Fonts),
					pwi.width, 
					swi.height
					);
		}
		else if( event.window == icon )
		{
			if( event.type == ExposeRegion
			|| event.type == ExposeWindow )
			{
				XPixmapPut( icon, 0,0,
				twidth/2 - menuicon_width/2,5,
				menuicon_width,menuicon_height,
				iconpixmap,GXcopy,AllPlanes);
				XFetchName( icon, &iconname );
				XTextMask( icon, 5,
					menuicon_height+10,
					fn,strlen(fn),
					fi->id,BlackPixel);
			}
			else if( event.type == ButtonPressed )
			{
				IconXlate( icon );
			}
		}
	}
}

int
HandleName( mbp )

	MenuBarPtr	mbp;
{
	printf("Hit NameBar of menubar <%s>\n",mbp->mbarName);
	IconXlate( pw );
	return 0;
}

int
HandleMenu( mp, item )

	MenuPtr		mp;
	int		item;
{
ItemPtr		ip;
int		checked;
static int	cur = 0;
char		str[32];
MenuPtr		nmp;
int		i;

#define	FILE_MENU	1
#define	EDIT_MENU	2
#define VIEW_MENU	3
#define SPECIAL_MENU	4
#define NEW_MENU	100

	ip = mm_GetItemHandle( mp, item );
	if( !ip )
		return 0;

	switch( mp->menuID )
	{
	case FILE_MENU:
		switch( item )
		{
		case 1:		/* open */

			if( cur==0 )
			{
				cur++;
				nmp = mm_NewMenu(NEW_MENU,"New");
				mm_AppendItem( nmp, "[*]Item 1;[*]Item 2" );
				mm_InsertMenu( menubar, nmp, 1 ); /* becomes first */
				mm_DrawMenuBar( menubar ); /* refresh the display */
				break;
			}
			else
				nmp = mm_GetMHandle(menubar,NEW_MENU);

			ip = mm_NewItem();
			sprintf(str,"Open%d",cur++);
			mm_SetItemLabel( ip, str );
			mm_InsertItem( nmp, ip, 2 );	/* before the second */
			
			if( nmp->menuItemCount > 2 )	/* are there things to close? */
				mm_EnableItem( mp, 2 );		/* turn Close on */
			mm_DrawMenuBar( menubar ); /* refresh the display */
			break;
		case 2:		/* close */
			nmp = mm_GetMHandle(menubar,NEW_MENU);
			mm_DeleteItem( nmp, mm_GetItemHandle(nmp,2) );
			if( nmp->menuItemCount == 2 )
				mm_DisableItem( mp, 2 );	/* turn close off */
			mm_DrawMenuBar( menubar );  /* update display */
			break;
		case 3:		/* wrap words */
			mm_SetItemCheck( ip, !mm_GetItemCheck( ip ) );
			break;
		case 4:		/* eject */
			break;
		case 5: 	/* kill self */
			break;
		default:
			break;
		}
		break;
	case EDIT_MENU:
		switch( item )
		{
		case 1:		/* Undo */
			break;
		case 2:		/* dash */
			break;
		case 3:		/* cut */
			break;
		case 4:		/* copy */
			break;
		case 5:		/* paste */
			break;
		case 6:		/* dash */
			break;
		case 7:		/* weird stuff */
			break;
		default:
			break;
		}
		break;
	case VIEW_MENU:
		switch( item )
		{
		case 1:		/* by name */
			break;
		case 2:		/* by size */
			break;
		case 3:		/* by icon */
			break;
		default:	/* by icon */
			break;
		}
		break;
	case SPECIAL_MENU:
		switch( item )
		{
		case 1:		/* Blow Up Computer */
			break;
		case 2:		/* Shut Down */
			Done = 1;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
	return 0;
}

int
IconXlate( w )

	Window	w;
{
WindowInfo	wi1, wi2;
int		steps = 20;
int		xs,ys,ws,hs,i,j;

	XQueryWindow( w, &wi1 );
	if( !wi1.assoc_wind )
	{
		fprintf(stderr,"IconXlate: window has no associate\n");
		return -1;
	}

	XQueryWindow( wi1.assoc_wind, &wi2 );
	XUnmapWindow( w );
	XFlush();

	for( j=0, i=0; i<steps; i++ )
	{
		xs = (wi2.x - wi1.x)/steps;
		ys = (wi2.y - wi1.y)/steps;
		ws = (wi2.width - wi1.width)/steps;
		hs = (wi2.height - wi1.height)/steps;

		DrawBox( RootWindow,
			wi1.x + (i*xs),
			wi1.y + (i*ys),
			wi1.width + (i*ws),
			wi1.height + (i*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );

		if( i>2 )
		{
		DrawBox( RootWindow,
			wi1.x + (j*xs),
			wi1.y + (j*ys),
			wi1.width + (j*ws),
			wi1.height + (j*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );
		j++;
		}

		XFlush();
		mpause(20);
	}

	for( ; j<steps; j++ )
		DrawBox( RootWindow,
			wi1.x + (j*xs),
			wi1.y + (j*ys),
			wi1.width + (j*ws),
			wi1.height + (j*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );
	
	XMapWindow( wi1.assoc_wind );
	return 0;
}

int
DrawBox( win, x,y, w,h, thickness, pixel, func, planes )

	Window 	win;
	int	x,y,w,h,thickness,pixel,func,planes;
{
static Vertex	vlist[5];

	vlist[0].x = x;
	vlist[0].y = y;
	vlist[1].x = (x+w)-1;
	vlist[1].y = y;
	vlist[2].x = (x+w)-1;
	vlist[2].y = (y+h)-1;
	vlist[3].x = x;
	vlist[3].y = (y+h)-1;
	vlist[4].x = x;
	vlist[4].y = y;
	XDraw( win, vlist, 5, thickness, thickness, pixel, func, planes );
	return 0;
}

