/* Launch.c - © 1991 Arnie Cachelin, HyperActive InterMedia       */
/* execute() commands from customized buttons */
/* 08 Aug 1991 At 20:34:49 */
/* Many of the following includes are actually useful... i hope */
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/exec.h>
#include <intuition/gadgetclass.h>
#include <intuition/screens.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>

#define DEFAULT_LENGTH 12
#define DEFAULT_NUMBER 1
#define MIN_LENGTH 4
#define MAX_NUMBER 9
#define MAX_LENGTH 20
#define XMARGIN 8
#define YMARGIN 8

struct IconBase     *IconBase=NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct GadToolsBase *GadToolsBase = NULL;
struct Window *WBWindow = NULL;
struct Screen *WBScreen = NULL;
APTR vi = NULL;
extern struct WBStartup   *WBenchMsg;
struct  DiskObject *dob = NULL;
struct Gadget *currgad = NULL;
struct Gadget *gadlist = NULL;
char  *txt,*cmd[MAX_NUMBER];

struct NewGadget ng = {
    15, 25,
    165, 95,
    "",
    NULL,
    1,
    PLACETEXT_IN,
    NULL,
    NULL
};

Terminate(int returnvalue)
{
    if(dob) FreeDiskObject(dob);
    if (gadlist) FreeGadgets(gadlist);
    if (vi) FreeVisualInfo(vi);
    if (WBWindow) CloseWindow (WBWindow);
    if (WBScreen != NULL) UnlockPubScreen (NULL, WBScreen);
    if (GadToolsBase) CloseLibrary ((struct Library *)GadToolsBase);
    if(IconBase) CloseLibrary((struct Library *)IconBase);
    if (IntuitionBase) CloseLibrary ((struct Library *)IntuitionBase);
    exit (returnvalue);
    return(0);
}

void Bummer(char *errmsg)
{
    puts(errmsg);
    Terminate(5);
}

void Initialize()
{
  UBYTE   namebuf[MAXPUBSCREENNAME];
    IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 36);
    if (IntuitionBase == NULL)
        Terminate(30);

    IconBase = (struct IconBase *) OpenLibrary ("icon.library", 36);
    if (IconBase == NULL)
        Terminate(30);

    GadToolsBase = (struct GadToolsBase *) OpenLibrary ("gadtools.library", 36);
    if (GadToolsBase == NULL) Terminate(30);
    GetDefaultPubScreen(namebuf);  /* Use namebuf=NULL for Workbench screen!  */
    WBScreen = LockPubScreen(namebuf);
    if (WBScreen == NULL) Terminate(30);

    vi = GetVisualInfo (WBScreen, TAG_DONE);
    if (vi == NULL)
        Terminate(30);

    ng.ng_VisualInfo = vi;
    currgad = CreateContext (&gadlist);
    ng.ng_TextAttr = WBScreen->Font;
		ng.ng_Height = (WBScreen->Font->ta_YSize *4)/3;
}

void handleIDCMP(struct Window *win)
{
    struct IntuiMessage *message = NULL;
    struct Gadget *gad = NULL;
    ULONG class, signals, signalmask;
    WORD code;

    signalmask = 1L << win->UserPort->mp_SigBit;
    while (1)
    {
        signals = Wait(signalmask);
        if (signals & signalmask)
            while (message = (struct IntuiMessage *)GT_GetIMsg(win->UserPort))
            {
                class = message->Class;
                code = (WORD)message->Code;
                gad = (struct Gadget *) message->IAddress;
                GT_ReplyIMsg(message);
/* 								printf("Gadget: %d,  Code: %d\n",gad->GadgetID,code); */
                switch(class)
                {
                    case CLOSEWINDOW:
                       Terminate(0);
                    case GADGETUP:
                      Execute(cmd[gad->GadgetID],NULL,NULL);
				    				default:
                       break;
                }
            }
    }
}

struct Gadget *AddButton(int x,int y,char *txt,int id)
{
 		ng.ng_GadgetText=txt;
 		ng.ng_TopEdge= y;
 		ng.ng_LeftEdge= x;
 		ng.ng_GadgetID= id;
    return(currgad=CreateGadget(BUTTON_KIND, currgad, &ng, TAG_DONE));
}

void main(int argc, char *argv[])
{
    int   width=DEFAULT_LENGTH,count=DEFAULT_LENGTH,TlType=0,c,
          cols,rows,x=XMARGIN,y=YMARGIN;
    char  *name;

    Initialize();
    if(argc)   /* If CLI start, get icon anyway... */
      dob = (struct  DiskObject *)GetDiskObject(name=argv[0]);
    else        /* Started from Workbench */
       /* Get program icon using name in WB Startup Msg */
      dob=(struct  DiskObject *)GetDiskObject(name=WBenchMsg->sm_ArgList->wa_Name);
    if (dob==0) Bummer("No Icon Found!");

    if (txt=(char *)FindToolType(dob->do_ToolTypes,"WIDTH"))
    {   /* Check user supplied text length  */
       if ( !(width=atol(txt)) || width<MIN_LENGTH ) width=DEFAULT_LENGTH;
       else if (width>MAX_LENGTH) width=MAX_LENGTH;
       TlType++;
    }
    else width=DEFAULT_LENGTH;
    width *= WBScreen->RastPort.TxWidth;
    ng.ng_Width = width;

    if (txt=(char *)FindToolType(dob->do_ToolTypes,"COUNT"))
    {   /* Check user supplied text NUMBER, 1 is always MIN */
       if ( !(count=atol(txt)) ) count=DEFAULT_NUMBER;
       else if (count>MAX_NUMBER) count=MAX_NUMBER;
       TlType++;
    }
    else count=DEFAULT_NUMBER;

    if (count>8) cols = 3;              /* How to arrange these buttons..  */
    else if (count>5) cols=(count+1)>>1;
    else cols=count;
    rows=(count%cols ? count/cols + 1: count/cols);    /* 7 is the pain... */

    for(c=0;c<count && dob->do_ToolTypes[TlType] ;c++)  /* Loop through ttypes  */
    {
      x=XMARGIN + (c%cols)*(width+XMARGIN);
      y=YMARGIN + (c/cols)*(ng.ng_Height+YMARGIN);
      txt=dob->do_ToolTypes[TlType++];
      if (dob->do_ToolTypes[TlType]) cmd[c]=(char *)dob->do_ToolTypes[TlType++];
      else cmd[c]=""; /*  This may not be necessary...  */
      if(!AddButton(x,y,txt,c)) Bummer("Cant Add That One!");
    }

    WBWindow = OpenWindowTags (NULL, WA_Title, (ULONG)name,
        WA_Flags, (ULONG)SMART_REFRESH|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|ACTIVATE,
        WA_InnerHeight, YMARGIN + rows*(ng.ng_Height+YMARGIN),
        WA_InnerWidth, cols*(width+XMARGIN)+XMARGIN,
        WA_AutoAdjust, TRUE,
        WA_GimmeZeroZero, TRUE,
        WA_IDCMP, (ULONG)CLOSEWINDOW|BUTTONIDCMP,
        TAG_DONE);

    AddGList (WBWindow, gadlist, -1, -1, NULL);
    RefreshGList(WBWindow->FirstGadget, WBWindow, NULL, (UWORD)-1);
    GT_RefreshWindow (WBWindow, NULL);
    handleIDCMP (WBWindow);
}

