/***************************************************************************
 * NewMenus for 1.3 demo program (uses newmenus.o NewMenu function module  *
 *    written by Paul Miller for AmigaWorld Tech Journal                   *
 *                                                                         *
 * note that that this file is basically identical to demo.c, except that  *
 * 2.0 and gadtool features have been removed, as well as those not        *
 * supported by this implementation of NewMenus for 1.3                    *
 ***************************************************************************/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

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

#include "newmenus.h"

typedef void (*FUNCPTR)(void);

struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;

struct Screen *screen = NULL;
struct Window *window = NULL;
struct Menu *menu = NULL;

struct NewWindow nw = {
   20, 20, 400, 100,
   -1, -1,
   CLOSEWINDOW | REFRESHWINDOW | MENUPICK,
   ACTIVATE | WINDOWDRAG | WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING |
      SIMPLE_REFRESH,
   NULL, NULL,
   "NewMenus for 1.3!",
   NULL,
   NULL,
   50, 50, -1, -1,
   WBENCHSCREEN
};


/* function prototypes for routines accessed with NewMenu UserData */
void NewProject(void);
void OpenProject(void);
void CloseProject(void);
void SaveProject(void);
void SaveAsProject(void);
void PrintProject(void);
void Quit(void);


/* NewMenu menu declaration */
struct NewMenu newmenu[] =
{
   {NM_TITLE, "Project",     0 , 0, 0, 0},
   {  NM_ITEM, "New...",    "N", 0, 0, (APTR)NewProject},
   {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0},
   {  NM_ITEM, "Open...",   "O", 0, 0, (APTR)OpenProject},
   {  NM_ITEM, "Close",      0,  0, 0, (APTR)CloseProject},
   {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0},
   {  NM_ITEM, "Save",      "S", 0, 0, (APTR)SaveProject},
   {  NM_ITEM, "Save As...","A", 0, 0, (APTR)SaveAsProject},
   {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0},
   {  NM_ITEM, "Print",     "P", 0, 0, (APTR)PrintProject},
   {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0},
   {  NM_ITEM, "Quit...",   "Q", 0, 0, (APTR)Quit},

   {NM_TITLE, "Edit",        0 , 0, 0, 0},
   {  NM_ITEM, "Undo",      "Z", 0, 0, 0},
   {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0},
   {  NM_ITEM, "Cut",       "X", 0, 0, 0},
   {  NM_ITEM, "Copy",      "C", 0, 0, 0},
   {  NM_ITEM, "Paste",     "V", 0, 0, 0},

   {NM_END, 0, 0, 0, 0, 0},
};


/* function prototypes */
void setup(void);
void closedown(void);
void open_libraries(void);
void close_libraries(void);
void abort(char *);
void handle_input(void);
void handle_menu(UWORD);

void main(argc, argv)
int argc;
char *argv[];
{
   setup();
   handle_input();
}

void setup()
{
   ULONG lock;
   ULONG error;

   open_libraries();

   /* attempt to get access to the WorkBench screen */
   /* (hope that IntuitionBase->ActiveScreen is the WorkBench screen */
   lock = LockIBase(0);
   screen = IntuitionBase->ActiveScreen;
   UnlockIBase(lock);
   if (!screen)
      abort("Couldn't get access to the WorkBench screen.");

   /* build the menu-strip */
   menu = CreateMenus(newmenu, GTMN_FrontPen, 0,
                               GTMN_SecondaryError, &error,
                               TAG_DONE);
   if (!menu)
   {
      printf("CreateMenus: SecondaryError = %ld\n", error);
      abort("Couldn't create the menu strip.");
   }

   /* note that no GTMN_TextAttr is passed here - this implementation
      currently works with the 8x8 ROMfont only */

   if (!LayoutMenus(menu, NULL, TAG_DONE))
      abort("Couldn't lay-out the menu stirp.");

   nw.Screen = screen;
   window = (struct Window *)OpenWindow(&nw);
   if (!window)
      abort("Couldn't open window.");

   SetMenuStrip(window, menu);
}

void open_libraries()
{
   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
   if (!GfxBase)
      abort("Couldn't open graphics.library.");

   IntuitionBase = (struct IntuitionBase *)
                             OpenLibrary("intuition.library", 0L);
   if (!IntuitionBase)
      abort("Couldn't open intuition.library.");
}

void close_libraries()
{
   if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
   if (GfxBase) CloseLibrary((struct Library *)GfxBase);
}

void closedown()
{
   if (window)
   {
      ClearMenuStrip(window);
      CloseWindow(window);
   }
   if (menu) FreeMenus(menu);

   close_libraries();
}

void abort(txt)
char *txt;
{
   closedown();
   if (txt)
      puts(txt);
   exit(0);
}

void handle_input()
{
   struct IntuiMessage *message;
   ULONG class;
   UWORD code;

   while (1)
   {
      WaitPort(window->UserPort);
      while (message = (struct IntuiMessage *)GetMsg(window->UserPort))
      {
         class = message->Class;
         code = message->Code;

         ReplyMsg((struct Message *)message);

         switch (class)
         {
            case CLOSEWINDOW:
               printf("CLOSEWINDOW.\n");
               abort(NULL);
               break;
            case MENUPICK:
               handle_menu(code);
               break;
            case REFRESHWINDOW:
               BeginRefresh(window);
               EndRefresh(window, TRUE);
               break;
         }
      }
   }
}

void handle_menu(code)
UWORD code;
{
   struct MenuItem *item;
   FUNCPTR funcptr;

   printf("MENUPICK:  ");

   /* traverse the selected-item list, calling functions attached by item's
      UserData pointer (if available) */

   while (code != MENUNULL)
   {
      item = (struct MenuItem *)ItemAddress(menu, code);

      /* does item have a function pointer in the UserData field? */
      funcptr = (FUNCPTR)GTMENUITEM_USERDATA(item);
      if (funcptr)
         funcptr();
      else
         printf("NO FUNCTION (id=%d)  ", ITEMNUM(code));

      code = item->NextSelect;
   }
   printf("\n");
}

/* NewMenu UserData functions */

void NewProject()
{
   printf("NEW  ");
}

void OpenProject()
{
   printf("OPEN  ");
}

void CloseProject()
{
   printf("CLOSE  ");
}

void SaveProject()
{
   printf("SAVE  ");
}

void SaveAsProject()
{
   printf("SAVEAS  ");
}

void PrintProject()
{
   printf("PRINT  ");
}

void Quit()
{
   printf("QUIT\n\n");
   abort("");
}
