/* test.c - program to demonstrate/test the ListWindow Package */
/*          by Paul T. Miller                                  */
/*                (Link with listwin_pak.o and graphics_pak.o) */

#include <intuition/intuition.h>
#include "graphics_pak.h"
#include "listwin_pak.h"

#define SCREEN_WIDTH    640
#define SCREEN_HEIGHT   200
#define SCREEN_DEPTH    2
#define SCREEN_TITLE    "ListWindow Test"
#define WIN_X           0
#define WIN_Y           11
#define WIN_W           223
#define WIN_H           85
#define MIN_WIDTH       100
#define MIN_HEIGHT      66
#define MAX_WIDTH       350
#define MAX_HEIGHT      SCREEN_HEIGHT

struct NewWindow nw;

struct Screen *screen = NULL;
struct Window *listwin = NULL;

UBYTE *namelist[] = {
   "Long Sword", "Short Sword", "Dagger", "Javelin", "Club", "Mace",
   "Broad Sword", "Axe", "Bow", "Sling-Shot", "Spear", "Staple Gun",
   "Shotgun", "Meat Cleaver", "Scyth"
};

UBYTE listbuffer[40];      /* this is where a selected name will be copied */

SHORT names = 15;

void main(void);
void abort(char *);
void setup(void);
void setup_display(void);
void closedown(void);
void close_display(void);
void handle_input(void);

void main()
{
   setup();
   handle_input();
}

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

void setup()
{
   OpenLibraries(GFXBASE|INTUITIONBASE);     /* graphics_pak.o */

   /* we want the listwindow to respond to SHIFT+key scrolling */
   InitListWindowPackage();

   setup_display();
}

void closedown()
{
   CloseListWindowPackage();     /* we initialized it, so deinitialize it */
   close_display();
   CloseLibraries();                         /* graphics_pak.o */
}

void setup_display()
{
   static struct NewScreen ns;
   static UWORD colortable[] = {0x0000, 0x0FFF, 0x000D, 0x0E90};
   ULONG flags, IDCMPflags;

   setmem(&ns, sizeof(struct NewScreen), 0);

   ns.Width = SCREEN_WIDTH;
   ns.Height = SCREEN_HEIGHT;
   ns.Depth = SCREEN_DEPTH;
   ns.DetailPen = 0;
   ns.BlockPen = 1;
   ns.ViewModes = HIRES;
   ns.Type = CUSTOMSCREEN;
   ns.Font = NULL;
   ns.DefaultTitle = SCREEN_TITLE;

   screen = (struct Screen *)OpenScreen(&ns);
   if (!screen)
      abort("Can't open Custom screen.");

   LoadRGB4(&screen->ViewPort, &colortable[0], 1L<<SCREEN_DEPTH);

   setmem(&nw, sizeof(struct NewWindow), 0L);

   IDCMPflags = RAWKEY | GADGETUP | GADGETDOWN | NEWSIZE | CLOSEWINDOW;

   flags = WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | WINDOWSIZING |
           WINDOWCLOSE | ACTIVATE;

   /* set up your list-window like any other window. */
   nw.LeftEdge = WIN_X;
   nw.TopEdge = WIN_Y;
   nw.Width = WIN_W;
   nw.Height = WIN_H;
   nw.DetailPen = -1;
   nw.BlockPen = -1;
   nw.IDCMPFlags = IDCMPflags;
   nw.Flags = flags;
   nw.Title = "A List Window";
   nw.FirstGadget = NULL;
   nw.Screen = screen;
   nw.Type = CUSTOMSCREEN;
   nw.MinWidth = MIN_WIDTH;         /* if you need to change the size, */
   nw.MinHeight = MIN_HEIGHT;       /* be sure to set these */
   nw.MaxWidth = MAX_WIDTH;
   nw.MaxHeight = MAX_HEIGHT;

   /* just call OpenListWindow(), just like OpenWindow() */

   listwin = (struct Window *)OpenListWindow(&nw);
   if (!listwin)
      abort("Can't open List Window.");

   /* Now initialize your list window  with your name list */
   InitListWindow(listwin, namelist, names, 0);
}

void close_display()
{
   if (listwin) CloseListWindow(listwin);
   if (screen) CloseScreen(screen);
}

void handle_input(void)
{
   struct IntuiMessage *message, copy;
   ULONG class;
   USHORT code, qualifier;
   struct Gadget *gadget;
   struct Window *win;
   SHORT num;

   while (1)
   {
      WaitPort(listwin->UserPort);
      while (message = (struct IntuiMessage *)GetMsg(listwin->UserPort))
      {
         class = message->Class;
         code = message->Code;
         qualifier = message->Qualifier;
         win = message->IDCMPWindow;
         gadget = (struct Gadget *)message->IAddress;

         /* make a copy of the message to send to the ListWindow handler */
         movmem(message, &copy, sizeof(struct IntuiMessage));

         ReplyMsg((struct Message *)message);

         /* check to see if the message was directed to the list-window */
         if (win == listwin)
         {
            /* if so, pass a pointer to the copied message, and a pointer to
               the buffer for a possible selected name */

            num = HandleListWindow(&copy, listbuffer);
            switch (num)
            {
               case CLOSE_LISTWINDOW:  /* won't get this if no CLOSEGADGET */
                  abort("");
                  break;
               case GOT_NAME:       /* name selected, or select-scrolled */
                  printf("%s", listbuffer);

                  /* use your own routines to find the actual data accessed
                     via the selected name */

                  for (num = 0; num < names; num++)
                     if (strcmp(listbuffer, namelist[num]) == NULL)
                        printf("  namelist[%d] = %s\n", num, namelist[num]);
                  break;
            }
         }

         /* now handle your other windows, or special-case handling of the
            list window */

         switch (class)
         {
            case CLOSEWINDOW:
               break;
            case MENUPICK:
               break;
            case RAWKEY:
               break;
         }
      }
   }
}
