/******************************\
*    >>> KickShell V1.1 <<<    *
*------------------------------*
*       ©1988 by ARTSOFT       *
*   written by Holger Schemel  *
\******************************/

#include <intuition/intuition.h>
extern void *OpenLibrary(), *OpenWindow(), *GetMsg();

struct IntuitionBase *IntuitionBase;
struct IntuiMessage *Nachricht;
struct Window *win;

/*----------   Initialisierungen   ----------*/

SHORT Koord2[] = { 0,0, 21,0, 21,11, 0,11, 0,0 };
SHORT Koord4[] = { 0,0, 37,0, 37,11, 0,11, 0,0 };
SHORT KoordG[] = { 0,0, 158,0, 158,11, 0,11, 0,0 };

#define IT1 1,1,JAM1,2,1,NULL
#define IT2 1,1,JAM1,-76,1,NULL
struct IntuiText tEdit = { IT1,(UBYTE *)"Edit",NULL };
struct IntuiText tMake = { IT1,(UBYTE *)"Make",NULL };
struct IntuiText tcc   = { IT1,(UBYTE *)"cc",NULL };
struct IntuiText tas   = { IT1,(UBYTE *)"as",NULL };
struct IntuiText tln   = { IT1,(UBYTE *)"ln",NULL };
struct IntuiText tSave = { IT1,(UBYTE *)"Save",NULL };
struct IntuiText tGo   = { IT1,(UBYTE *)"Go",NULL };
struct IntuiText tsave = { IT2,(UBYTE *)"SaveDir.:",NULL };
struct IntuiText twork = { IT2,(UBYTE *)"Workfile:",NULL };
struct IntuiText tcomp = { IT2,(UBYTE *)"cc opts.:",NULL };
struct IntuiText tlink = { IT2,(UBYTE *)"ln opts.:",NULL };

struct Border b2 = { -1,-1,1,0,JAM1,5,&Koord2[0],NULL };
struct Border b4 = { -1,-1,1,0,JAM1,5,&Koord4[0],NULL };
struct Border bG = { -3,-2,1,0,JAM1,5,&KoordG[0],NULL };

#define GD2 GADGHCOMP,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,(APTR)&b2,NULL
#define GD4 GADGHCOMP,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,(APTR)&b4,NULL
struct Gadget Edit =
{
   NULL,8,13,36,10,
   GD4,&tEdit,0,0,1,0
};
struct Gadget Make =
{
   &Edit,51,13,36,10,
   GD4,&tMake,0,0,2,0
};
struct Gadget cc =
{
   &Make,94,13,20,10,
   GD2,&tcc,0,0,3,0
};
struct Gadget as =
{
   &cc,121,13,20,10,
   GD2,&tas,0,0,4,0
};
struct Gadget ln =
{
   &as,148,13,20,10,
   GD2,&tln,0,0,5,0
};
struct Gadget Save =
{
   &ln,175,13,36,10,
   GD4,&tSave,0,0,6,0
};
struct Gadget Go =
{
   &Save,218,13,20,10,
   GD2,&tGo,0,0,7,0
};

UBYTE saveBuffer[20]="df1:",undoBuffer[20];
UBYTE workBuffer[20],compBuffer[20],linkBuffer[20]="-lc";

#define SI  undoBuffer,0,19,0,0,0,0,0,0,NULL,0,NULL
struct StringInfo saveInfo = { saveBuffer,SI };
struct StringInfo workInfo = { workBuffer,SI };
struct StringInfo compInfo = { compBuffer,SI };
struct StringInfo linkInfo = { linkBuffer,SI };

#define GD  GADGHCOMP,RELVERIFY,STRGADGET,(APTR)&bG,NULL
struct Gadget save =
{
   &Go,83,29,172,10,GD,&tsave,
   0,(APTR)&saveInfo,8,0
};
struct Gadget work =
{
   &save,83,43,172,10,GD,&twork,
   0,(APTR)&workInfo,9,0
};
struct Gadget comp =
{
   &work,83,57,172,10,GD,&tcomp,
   0,(APTR)&compInfo,10,0
};
struct Gadget link =
{
   &comp,83,71,172,10,GD,&tlink,
   0,(APTR)&linkInfo,11,0
};

struct NewWindow newwin =
{
   390,22,246,84,0,1,
   CLOSEWINDOW|GADGETUP,
   WINDOWCLOSE|NOCAREREFRESH|WINDOWDRAG|WINDOWDEPTH,
   &link,0,
   (UBYTE *)"KickShell - ©ARTSOFT",
   NULL,NULL,0,0,0,0,
   WBENCHSCREEN
};

UBYTE Befehl[40];
SHORT i,x,y,ac=1;    /* Variable ac=1 : KickShell wird nach Start aktiviert
                                 ac=0 : KickShell wird nicht aktiviert   */

/*---------- MASTER-CONTROL-PROGRAM ----------*/

main(argc,argv)
SHORT argc;
char *argv[];
{
   ULONG class;

   if (*argv[1]=='?')
      exit(puts("Usage: run KickShell [-n <name>][-c <comp>][-l <link>][-xy <x> <y>]"));

   if (argc>2) for(i=0;i<argc-1;i++)
   {
      if (!strcmp(argv[i],"-n")) { sprintf(workBuffer,argv[i+1]); ac=0; }
      if (!strcmp(argv[i],"-c")) sprintf(compBuffer,argv[i+1]);
      if (!strcmp(argv[i],"-l")) sprintf(linkBuffer,argv[i+1]);
      if (!strcmp(argv[i],"-xy"))
      {
         sscanf(argv[i+1],"%d",&x); if (x<0 || x>394) x=0;
         sscanf(argv[i+2],"%d",&y); if (y<0 || y>186) y=0;
         newwin.LeftEdge = x;
         newwin.TopEdge  = y;
      }
   }

   OpenAll();

   FOREVER
   {
      Wait(1L<<win->UserPort->mp_SigBit);    /* Auf IntuiMessage warten */
      if (Nachricht = (struct IntuiMessage *)GetMsg(win->UserPort))
      {
         win->IDCMPFlags = NULL;                   /* Shell desaktivieren */
         class = Nachricht->Class;
         ReplyMsg(Nachricht);
         if (class == CLOSEWINDOW) CloseAll();     /* Shell beenden */
         if (class == GADGETUP) DoGadgets();       /* Befehl ausführen */
         win->IDCMPFlags = CLOSEWINDOW|GADGETUP;   /* Shell reaktivieren */
      }
   }
}

OpenAll()
{
   if (!(IntuitionBase = OpenLibrary("intuition.library",0L))) CloseAll();
   if (ac) newwin.Flags |= ACTIVATE;
   if (!(win = OpenWindow(&newwin))) CloseAll();
   RefreshGadgets(&link,win,NULL);
   if (ac) ActivateGadget(&work,win,NULL);
}

CloseAll()
{
   if (win) CloseWindow(win);
   if (IntuitionBase) CloseLibrary(IntuitionBase);
   exit(0);
}

DoGadgets()
{
   struct Gadget *gad;
   SHORT gadgetnum;

   if (workBuffer[0]=='\0') return();     /* Kein Programm zu bearbeiten */

   gad = (struct Gadget *)Nachricht->IAddress;
   gadgetnum = gad->GadgetID;             /* Gadget-Nummer ermitteln */

   switch(gadgetnum)
   {
      case 1:  sprintf(Befehl,"Ed %s.c",workBuffer);
               Ex(Befehl); /*  ^^ oder eigenen Editor eintragen */
               break;
      case 2:  MakeFile();
               break;
      case 3:  Compile();
               break;
      case 4:  Assemble();
               break;
      case 5:  Link();
               break;
      case 6:  SaveFile();
               break;
      case 7:  Ex(workBuffer);
               break;
   }
   if (gadgetnum>1 && gadgetnum<7) puts("OK.");
}

Compile()
{
   sprintf(Befehl,"cc %s.c %s",workBuffer,compBuffer);
   Ex(Befehl);
}

Assemble()
{
   sprintf(Befehl,"as %s.asm",workBuffer);
   Ex(Befehl);
   sprintf(Befehl,"delete %s.asm",workBuffer);
   Ex(Befehl);
}

Link()
{
   sprintf(Befehl,"ln %s.o %s",workBuffer,linkBuffer);
   Ex(Befehl);
   sprintf(Befehl,"delete %s.o",workBuffer);
   Ex(Befehl);
}

MakeFile()
{
   Compile();
   if(compBuffer[0]=='-' && compBuffer[1]=='a') Assemble();
   Link();
}

SaveFile()
{
   if (!saveBuffer[0]) strcpy(saveBuffer,"df1:\0");
   sprintf(Befehl,"copy %s#? to %s",workBuffer,saveBuffer);
   Ex(Befehl);
}

Ex(cmd)     /* Alternative ohne Diskettenzugriff zu 'Execute()' */
char *cmd;
{
   char *name,*argv[3],*pos1,*pos2;
   char cmdname[40],args[40];

   pos1 = name = &cmdname[0];
   pos2 = argv[1] = &args[0];
   argv[0] = argv[2] = NULL;

   while(*cmd==32) cmd++;
   while(*cmd!=32 && *cmd!=0) *pos1++ = *cmd++;
   *pos1 = 0;

   while(*cmd==32) cmd++;
   while(*pos2++ = *cmd++);
   *pos2 = 0;

   fexecv(name,argv);
}

