 /*
 * SAVEC.C
 */

#include "defs.h"

Prototype void SaveProjectAsSrc(char *);
Prototype void DeclareHeaders(FILE *);
Prototype void DeclareNG(FILE *, short);
Prototype void DeclareWIN(FILE *);
Prototype void DeclareBOX(FILE *);
Prototype void DeclareRG(FILE *, TplRegion *);
Prototype void DeclareInitGads(FILE *);
Prototype void DeclareFreeGads(FILE *);
Prototype void DeclareDispFunc(FILE *);
Prototype void DeclareSelectGad(FILE *);
Prototype void DeclareDrawBorders(FILE *);
Prototype void DeclareMain(FILE *);

/*****************************************************/

const char *NG_Flags[] = {
  "NULL",
  "PLACETEXT_LEFT",
  "PLACETEXT_RIGHT", "",
  "PLACETEXT_ABOVE", "", "", "",
  "PLACETEXT_BELOW", "", "", "", "", "", "", "",
  "PLACETEXT_IN"
};

static char *RgtKindAry[] = {
  " GENERIC_KIND",      /*  0 invisible */
  "  BUTTON_KIND",      /*  1 */
  "CHECKBOX_KIND",      /*  2 */
  " INTEGER_KIND",      /*  3 */
  "LISTVIEW_KIND",      /*  4 */
  "      MX_KIND",      /*  5 */
  "  NUMBER_KIND",      /*  6 */
  "   CYCLE_KIND",      /*  7 */
  " PALETTE_KIND",      /*  8 */
  "SCROLLER_KIND",      /*  9 */
  "",                   /*  10 reserved = BEVELBOX  */
  "  SLIDER_KIND",      /*  11*/
  "  STRING_KIND",      /*  12*/
  "    TEXT_KIND"       /*  13*/
};

short callback = FALSE;
short exclude  = FALSE;
short border   = FALSE;


/***********************  SaveProjectAsSrc(name)  ********************/
void
SaveProjectAsSrc(name)
  char  *name;
{
  FILE  *fo;
  TplRegion *rg;


  char *defname;
  defname = zalloc(strlen(name) + 8);
  strcpy(defname, name);
  char *d = defname;

  while (*d++ != '.');

  *--d = '\0';

  strcat(defname, "_defs.h");

  char *maindefname = "defs.h";

  if (fo = fopen(name, "r"))
  {
    fclose(fo);
    if (!(do_request( "Sourcefile \"%s\" already exists !",
                      "Replace it|Cancel", name)))
      return;
  }
  if ((fo = fopen(name, "w")) == NULL)
    return;

  fprintf(fo,
          "\n"
          "/*\n"
          " * %s\n"
          " *\n"
          " * MACHINE GENERATED\n"
          " * %s %s\n"
          " */\n\n"
          "#include \"%s\"\n\n"
          "Prototype void    FreeGads(void);\n",
          name, __DATE__, __TIME__, (savemain) ? defname : maindefname);

  if (savemain)
    fputs("Prototype Gadget *InitGads(Screen *);\n", fo);
  else
    fputs("Prototype int     InitGads(void);\n", fo);

  short  numRG = 0;

  for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    switch (rg->rg_Type)
    {
    case RGT_BEVELBOX:
      border = TRUE;

    case RGT_INVISIBLE:
      break;

    case RGT_SLIDER:
      callback = TRUE;

    default:
      if (rg->rg_ExclGroup)
        exclude = TRUE;

      ++numRG;
      break;
    }
  }

  if (exclude)
  {
    fputs("Prototype void    selectgad(Gadget *);\n"
          "Prototype void    DisableExcl(Gadget *);\n"
          "Prototype void    ReleaseExcl(Gadget *);\n", fo);
  }

  if (border)
    fputs("Prototype void    drawborders(void);\n", fo);

  if (callback)
    fputs("Prototype __geta4 long DispFunc(Gadget *, WORD);\n", fo);

  fputs("\n", fo);

  for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    if ((rg->rg_Type != RGT_INVISIBLE) &&
        (rg->rg_Type != RGT_BEVELBOX))
      fprintf(fo, "Prototype Gadget *Gad_%s;\n", rg->rg_Node.ln_Name);
    if (rg->rg_Type == RGT_STRING)
      fprintf(fo, "Prototype char   *Buf_%s;\n", rg->rg_Node.ln_Name);
    if (rg->rg_Type == RGT_LISTVIEW ||
        rg->rg_Type == RGT_CYCLE ||
        rg->rg_Type == RGT_MX )
      fprintf(fo, "Prototype List   List_%s;\n", rg->rg_Node.ln_Name);
  }

  fprintf(fo, "\nPrototype NewGadget NGAry[%d];\n",  numRG);
  fprintf(fo, "Prototype Gadget    *EGList;\n"
              "Prototype Gadget    *Egadlist[%d];\n", numRG);
  fprintf(fo, "Prototype Window    *EWin;\n"
              "Prototype struct    VisualInfo *VisInfo;\n"
              "Gadget    *Egadlist[%d];\n", numRG);

  if (savemain)
    fputs("struct    VisualInfo *VisInfo;\n"
          "Window    *EWin;\n" , fo);


  DeclareNG(fo, numRG);

  for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    if ((rg->rg_Type != RGT_INVISIBLE) &&
        (rg->rg_Type != RGT_BEVELBOX))
      DeclareRG(fo, rg);
  }
  DeclareInitGads(fo);
  if (savemain)
    DeclareMain(fo);

  if (callback)
    DeclareDispFunc(fo);

  if (exclude)
    DeclareSelectGad(fo);

  if (border)
    DeclareDrawBorders(fo);

  DeclareFreeGads(fo);
  fclose(fo);

/*********************** tpl_defs.h   ******************************************/

  FILE  *fo;
  TplRegion *rg;


  if (fo = fopen(defname, "w"))
  {
    fprintf(fo, "\n"
          "/*\n"
          " * %s\n"
          " *\n"
          " * MACHINE GENERATED\n"
          " * %s %s\n"
          " */\n\n",
          defname, __DATE__, __TIME__);


    if (savemain)
      DeclareHeaders(fo);

    fputs("#define NULPTR    ((void *)0L)\n"
          "#define Prototype extern       /* DICE special */\n", fo);


    fputs("typedef struct Gadget        Gadget;\n"
          "typedef struct Menu          Menu;\n"
          "typedef struct MenuItem      MenuItem;\n"
          "typedef struct Window        Window;\n"
          "typedef struct Screen        Screen;\n"
          "typedef struct NewGadget     NewGadget;\n"
          "typedef struct NewMenu       NewMenu;\n"
          "typedef struct IntuiMessage  IMsg;\n"
          "typedef struct List          MaxList;\n"
          "typedef struct Node          MaxNode;\n"
          "typedef struct TextFont      TextFont;\n"
          "typedef struct TextAttr      TextAttr;\n"
          "typedef struct MsgPort       MsgPort;\n"
          "typedef struct RastPort      RastPort;\n"
          "typedef struct StringInfo    StringInfo;\n"
          "typedef struct FileRequester FileRequester;\n"
          "typedef struct MinList       List;\n"
          "typedef struct MinNode       Node;\n"
          "\n"
          "typedef unsigned char  ubyte;\n"
          "typedef unsigned short uword;\n"
          "typedef unsigned long  ulong;\n\n", fo);

    DeclareWIN(fo);
    DeclareBOX(fo);

    short i = 0;
    for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
    {
      if ((rg->rg_Type != RGT_INVISIBLE) &&
          (rg->rg_Type != RGT_BEVELBOX))
        fprintf(fo, "#define GAD_%s\t%3d\n", rg->rg_Node.ln_Name, i++);

    }
    fprintf(fo, "\n#define ALLGADS\t%3d\n\n", i);

    for (i = 0, rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
    {
      if ((rg->rg_Type != RGT_INVISIBLE) &&
          (rg->rg_Type != RGT_BEVELBOX))
        fprintf(fo, "#define NG_%s\t(NGAry + GAD_%s)\n", rg->rg_Node.ln_Name,
                                                         rg->rg_Node.ln_Name);
    }
    fputs("\n", fo);

    fclose(fo);
  }
}

/***********************  DeclareNG(fo, ******************************/
void
DeclareNG(fo, nrg)
  FILE  *fo;
  short  nrg;
{
  TplRegion *rg;

  fprintf(fo,       "\nNewGadget NGAry[%d] = {\n", nrg);

  short  i;
  for (i = 0, rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    if ((rg->rg_Type != RGT_INVISIBLE) &&
        (rg->rg_Type != RGT_BEVELBOX))
    {
      fprintf(fo,   "  {\n"
                    "    GLEF_%d, GTOP_%d, GWID_%d, GHEI_%d,\n",i,i,i,i);

      if (rg->rg_LabText)
        fprintf(fo, "    \"%s\",", rg->rg_LabText);
      else
        fprintf(fo, "    NULPTR,");

      fputs(        "\t\t/* UBYTE\t*ng_GadgetText\t*/\n", fo);

      fputs(        "    NULPTR,\t\t/* struct TextAttr *ng_TextAttr\t*/\n", fo);

      if (rg->rg_Node.ln_Name)
        fprintf(fo, "    GAD_%s,", rg->rg_Node.ln_Name);
      else
        fprintf(fo, "    NULPTR,");

      fputs(        "\t/* UWORD\tng_GadgetID\t*/\n", fo);

      char *highlabel = (rg->rg_SpecFlags & SPEC_HIGHLABEL) ?
                                          " | NG_HIGHLABEL" : "";

      char *flags = ((NG_Flags[rg->rg_Flags]) ?
                     NG_Flags[rg->rg_Flags]  :
                     NG_Flags[0]);


      fprintf(fo,   "    %s%s,\t/* ULONG\tng_Flags\t*/\n", flags, highlabel);

      fputs(        "    NULPTR,\t\t/* APTR  \tng_VisualInfo\t*/\n", fo);
      fputs(        "    NULPTR,\t\t/* APTR  \tng_UserData\t*/\n", fo);

      fprintf(fo,   "  }%s\n", (GetSucc(&rg->rg_Node) ? "," : ""));
      ++i;
    }
  }
  fputs("};\n", fo);
}


/***********************  DeclareInitGads(fo) ************************/
void
DeclareInitGads(fo)
  FILE  *fo;
{
  TplRegion *rg;

  fputs("\n\nGadget *EGList;\n\n"
        "/* ***** InitGads ***** */\n" , fo);

  if (savemain)
    fputs(
        "Gadget *\n"
        "InitGads(Scr)\n"
        "  Screen *Scr;\n", fo);
  else
    fputs(
        "int\n"
        "InitGads(void)\n", fo);

  fputs("{\n"
        "  Gadget *gad;\n"
        "  short i;\n\n"
        "  EGList = NULPTR;\n", fo);

/*
 * Step 1, allocate VisInfo
 */
  if (savemain)
  fputs("  if ((VisInfo = GetVisualInfo(Scr, TAG_END)) == NULL)\n"
        "    return(NULPTR);\n", fo);

/*
 * Step 2, apply to NGAry ng_VisualInfo & ng_TextAttr (from screen)
 */

  fputs("\n  NewGadget *ng;\n"
        "  for (i = 0, ng = NGAry;\n"
        "       i < sizeof(NGAry)/sizeof(NGAry[0]);\n"
        "       ++i, ++ng)\n"
        "  {\n"
        "    ng->ng_VisualInfo = VisInfo;\n"
        "    ng->ng_TextAttr   = Scr->Font;\n"
        "  }\n", fo);

/*
 * Step 3, allocate EGList
 */

  fputs("  if ((gad = CreateContext(&EGList)) == NULL)\n", fo);
  if (savemain)
    fputs(
        "    return(NULPTR);\n\n", fo);
  else
    fputs(
        "    return(NULL);\n\n", fo);

/*
 * Step 4, allocate gadgets
 *
 * Allocation is a two pass process.  The first pass deals with those gadgets
 * that do not depend on other gadgets.  The second pass deals with those
 * gadgets that DO depend on other gadgets.
 */

  short  i = 0;

  for (short j = 0; j < 2; ++j)
  {
    for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
    {
      if ((rg->rg_Type != RGT_INVISIBLE) &&
          (rg->rg_Type != RGT_BEVELBOX))
      {
        if (j == 0)
        {
          if (rg->rg_LockedTo && (rg->rg_Type == RGT_LISTVIEW))
            continue;
        }
        else
        {
          if (!(rg->rg_LockedTo && (rg->rg_Type == RGT_LISTVIEW)))
            continue;
        }

        char *name  = rg->rg_Node.ln_Name;

        fprintf(fo,     "  Gad_%s\t= gad = Egadlist[GAD_%s] =\n"
                        "\tCreateGadget(%s, gad, NG_%s,\n",
                          name, name, RgtKindAry[rg->rg_Type], name);

        switch (rg->rg_Type)
        {
        case RGT_STRING:
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          fprintf(fo,   "\tGTST_MaxChars,     %d,\n",     rg->rg_BufSpace);
          if (rg->rg_DefText[0])
            fprintf(fo, "\tGTST_String,       \"%s\",\n", rg->rg_DefText);
          break;

        case RGT_INTEGER:
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          fprintf(fo,   "\tGTIN_MaxChars,     %d,\n",     rg->rg_BufSpace);
          fprintf(fo,   "\tGTIN_Number,       %d,\n",     rg->rg_DefVal);
          break;

        case RGT_SLIDER:
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          fprintf(fo,   "\tGTSL_Max,          %d,\n",     rg->rg_MaxVal);
          fprintf(fo,   "\tGTSL_Level,        %d,\n",     rg->rg_DefVal);
          fprintf(fo,   "\tGTSL_MaxLevelLen,  %d,\n",    (rg->rg_BufSpace) ?
                                                          rg->rg_BufSpace  : 4);
          fprintf(fo,   "\tGTSL_LevelFormat,  \"%s\",\n",(rg->rg_LabText)   ?
                                                          rg->rg_LabText    : "%4ld");
          fprintf(fo,   "\tGTSL_LevelPlace,   %s,\n",     NG_Flags[rg->rg_Flags]);
          fprintf(fo,   "\tGTSL_DispFunc,     DispFunc,\n");
          fprintf(fo,   "\tPGA_Freedom,       %s,\n",    (rg->rg_SpecFlags  &
                                                          SPEC_VERTICAL)    ?
                                                         "LORIENT_VERT"     :
                                                         "LORIENT_HORIZ");
          break;

        case RGT_SCROLLER:
          Box box = rg->rg_Box;
          short x = box.bo_Xe - box.bo_Xs;
          short y = box.bo_Ye - box.bo_Ys;
          x = (x >  7) ?  8 : x;
          y = (y > 15) ? 16 : y;

          fprintf(fo,   "\tGTSC_Total,        %d,\n",     rg->rg_MaxVal);
          fprintf(fo,   "\tGTSC_Top,          %d,\n",     rg->rg_DefVal);
          fprintf(fo,   "\tGTSC_Visible,      %d,\n",     rg->rg_BufSpace);
          fprintf(fo,   "\tGTSC_Arrows,       %d,\n",    (rg->rg_SpecFlags   &
                                                          SPEC_VERTICAL) ? y : x);
          fprintf(fo,   "\tPGA_Freedom,       %s,\n",    (rg->rg_SpecFlags   &
                                                          SPEC_VERTICAL)     ?
                                                         "LORIENT_VERT"      :
                                                         "LORIENT_HORIZ");
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          break;

        case RGT_LISTVIEW:
          fprintf(fo,   "\tGTLV_Labels,       &List_%s,\n", name);
          fprintf(fo,   "\tGTLV_Selected,     %d,\n",     rg->rg_DefVal);
          if (rg->rg_LockedTo)
            fprintf(fo, "\tGTLV_ShowSelected, Gad_%s,\n",
                                           rg->rg_LockedTo->rg_Node.ln_Name);
          else
            if (rg->rg_SpecFlags & SPEC_READONLY)
              fputs(    "\tGTLV_ShowSelected, NULL,\n",   fo);

          fprintf(fo,   "\tLAYOUTA_Spacing,   %d,\n",     rg->rg_BufSpace);
          break;

        case RGT_CYCLE:
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          fprintf(fo,   "\tGTCY_Labels,       Ary_%s,\n",   name);
          fprintf(fo,   "\tGTCY_Active,       %d,\n",     rg->rg_DefVal);
          break;

        case RGT_MX:
          fprintf(fo,   "\tGTMX_Spacing,      %d,\n",     rg->rg_BufSpace);
          fprintf(fo,   "\tGTMX_Labels,       Ary_%s,\n", name);
          fprintf(fo,   "\tGTMX_Active,       %d,\n",     rg->rg_DefVal);
          break;

        case RGT_CHECKBOX:
          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",   fo);
          fprintf(fo,   "\tGTCB_Checked,      %d,\n",    (rg->rg_SpecFlags &
                                                          SPEC_CHECKED));
          break;


        case RGT_NUMBER:
          fprintf(fo,   "\tGTNM_Number,       %d,\n",     rg->rg_DefVal);
          fprintf(fo,   "\tGTNM_Border,       %d,\n",    (rg->rg_SpecFlags &
                                                          SPEC_BORDER));
          break;

        case RGT_TEXT:
          if (rg->rg_DefText[0])
          {
            fprintf(fo, "\tGTTX_Text,         \"%s\",\n"
                        "\tGTTX_CopyText,     1,\n",      rg->rg_DefText);
          }
          fprintf(fo,   "\tGTTX_Border,       %d,\n",    (rg->rg_SpecFlags &
                                                          SPEC_BORDER));
          break;

        case RGT_PALETTE:
          Box box = rg->rg_Box;
          short x = box.bo_Xe - box.bo_Xs;
          short y = box.bo_Ye - box.bo_Ys;
          x = (x >> 1) - 4;
          if ((y + 4) < x)
            x = y + 4;

          short val = (rg->rg_MaxVal > 15) ? 5 :
                      (rg->rg_MaxVal >  7) ? 4 :
                      (rg->rg_MaxVal >  3) ? 3 :
                      (rg->rg_MaxVal >  1) ? 2 : 1;

          if (rg->rg_SpecFlags & SPEC_DISABLED)
            fputs(      "\tGA_Disabled,       TRUE,\n",     fo);
          fprintf(fo,   "\tGTPA_Depth,          %d,\n",     val);
          fprintf(fo,   "\tGTPA_Color,          %d,\n",     rg->rg_DefVal);
          fprintf(fo,   "\tGTPA_ColorOffset,    %d,\n",     rg->rg_BufSpace);
          fprintf(fo,   "\tGTPA_IndicatorWidth, %d,\n",     x);
          fprintf(fo,   "\tGTPA_IndicatorHeight,%d,\n",     y);

        default:
          break;

        }
        fputs(          "\tTAG_END);\n\n"
                        "  if (gad == NULL)\n", fo);
        if (savemain)
          fputs(        "    return(NULPTR);\n\n", fo);
        else
          fputs(        "    return(NULL);\n\n", fo);

        switch (rg->rg_Type)
        {
        case RGT_BUTTON:
          if (rg->rg_SpecFlags & SPEC_CHECKED)
            fputs(      "  gad->Flags |= GFLG_SELECTED;\n", fo);
          break;

        case RGT_STRING:
          fprintf(fo,   "  Buf_%s\t= ((StringInfo *)gad->SpecialInfo)->Buffer;\n",
                                                            name);
        default:
          break;
        }

        fprintf(fo,     "  (long)gad->UserData = %s;\n",    RgtKindAry[rg->rg_Type]);
        if (rg->rg_ExclGroup)
          fprintf(fo,   "  gad->MutualExclude  = 0x%X;\n",  rg->rg_ExclGroup);

        fputs(          "\n", fo);
        ++i;
      }
    }
  }

/*
 * return EGList
 */

  fputs(                "  return(EGList);\n}\n", fo);
}

/***********************  DeclareDrawBorders(FILE **********************/
void
DeclareDrawBorders(FILE *fo)
{
  TplRegion *rg;

  fputs("\n/* ***** Do BevelBorders ***** */\n"
        "void\n"
        "drawborders(void)\n"
        "{\n", fo);

  short i = 0;
  for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    if (rg->rg_Type == RGT_BEVELBOX)
    {
      fprintf(fo, "/* *** %s *** */\n",  rg->rg_Node.ln_Name);
      fprintf(fo, "  DrawBevelBox(EWin->RPort, "
                  "BLEF_%d, BTOP_%d, BWID_%d, BHEI_%d,\n", i,i,i,i);

      fputs(    "\tGT_VisualInfo, VisInfo,\n", fo);
      if (rg->rg_SpecFlags & SPEC_RECESSED)
        fputs(  "\tGTBB_Recessed, TRUE,\n", fo);
      fputs(    "\tTAG_END);\n", fo);
      ++i;
    }
  }
  fputs("}\n", fo);
}


/***********************  DeclareRG(fo, ******************************/
void
DeclareRG(fo, rg)
  FILE  *fo;
  TplRegion *rg;
{
  char *name = rg->rg_Node.ln_Name;

  fprintf(fo,           "\nGadget *Gad_%s;\n", name);

  switch (rg->rg_Type)
  {
  case RGT_STRING:
    fprintf(  fo,       "char   *Buf_%s;\n", name);
    break;

  case RGT_LISTVIEW:
    {
      MaxNode *mn;
      short  i;
      short  cnt;

      for (cnt = 0, mn = GetHead(&rg->rg_ListSet); mn; ++cnt, mn = GetSucc(mn)) ;

      if (cnt)
      {
        fprintf(fo,     "struct Node NodeAry_%s[%d] = {\n", name, cnt);

        for (i = 0, mn = GetHead(&rg->rg_ListSet); mn; ++i, mn = GetSucc(mn))
        {
          fprintf(fo,   "  {\n");

          if (GetSucc(mn))
            fprintf(fo, "    NodeAry_%s + %d,\n", name, i + 1);
          else
            fprintf(fo, "    (struct Node *)&List_%s.mlh_Tail,\n", name);

          if (GetPred(mn))
            fprintf(fo, "    NodeAry_%s + %d,\n", name, i - 1);
          else
            fprintf(fo, "    (struct Node *)&List_%s.mlh_Head,\n", name);

          fprintf(fo,   "    0, 0,\n"
                        "    \"%s\"\n"
                        "  }%s\n", mn->ln_Name, (i == cnt - 1) ? "" : ",");
        }

        fprintf(fo,     "};\n\n");
      }

      fprintf(fo,       "List List_%s = {\n", name);

      if (cnt)
        fprintf(fo,     "  &NodeAry_%s[0],\n", name);
      else
        fprintf(fo,     "  (struct MinNode *)&List_%s.mlh_Tail,\n", name);

      fprintf(fo,       "  NULPTR,\n");

      if (cnt)
        fprintf(fo,     "  &NodeAry_%s[%d]\n", name, cnt - 1);
      else
        fprintf(fo,     "  (struct MinNode *)&List_%s.mlh_Head\n", name);

      fputs(            "};\n", fo);
    }
    break;

  case RGT_CYCLE:
  case RGT_MX:
    short  i = 0;

    fprintf(fo,         "char   *StatAry_%s[] = {", name);
    if (rg->rg_CycleAry)
    {
      char  *ptr;

      for (; ptr = rg->rg_CycleAry[i]; ++i)
        fprintf(fo,     "\n  \"%s\",", ptr);
    }
    fprintf(fo,         "\n  NULPTR\n};\n");
    fprintf(fo,         "char **Ary_%s\t= StatAry_%s;\n", name, name);

    break;

  default:
    break;
  }
}


/***********************  DeclareFreeGads(fo) ************************/
void
DeclareFreeGads(fo)
  FILE  *fo;
{
  fputs("\n/* ***** Free the Gadlist and return ***** */\n"
        "void\n"
        "FreeGads(void)\n"
        "{\n"
        "  FreeGadgets(EGList);\n", fo);

  if (savemain)
    fputs(
        "  if (VisInfo)\n"
        "    FreeVisualInfo(VisInfo);\n"
        "  VisInfo = NULL;\n", fo);

  fputs("  EGList  = NULL;\n"
        "}\n", fo);
}


/***********************  DeclareHeaders(fo)  ************************/
void
DeclareHeaders(fo)
  FILE  *fo;
{
  fputs("#include <exec/types.h>\n"
        "#include <exec/lists.h>\n"
        "#include <intuition/intuition.h>\n"
        "#include <intuition/screens.h>\n"
        "#include <intuition/gadgetclass.h>\n"
        "#include <libraries/gadtools.h>\n"
        "#include <clib/gadtools_protos.h>\n"
        "\n", fo);
}


/***********************  DeclareBOX(fo)  ****************************/
void
DeclareBOX(fo)
  FILE  *fo;
{
  short bboxes = FALSE;
  TplRegion *rg;
  short  i;

  for (i = 0, rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
  {
    if (rg->rg_Type == RGT_BEVELBOX)
    {
      bboxes = TRUE;
      continue;
    }

    if (rg->rg_Type != RGT_INVISIBLE)
    {
      fprintf(fo, "/* *** Gadget %s *** */\n", rg->rg_Node.ln_Name);
      fprintf(fo, "#define GLEF_%d\t%3d\n",   i,rg->rg_Box.bo_Xs);
      fprintf(fo, "#define GTOP_%d\t%3d\n",   i,rg->rg_Box.bo_Ys);
      fprintf(fo, "#define GWID_%d\t%3d\n",   i,rg->rg_Box.bo_Xe -
                                               rg->rg_Box.bo_Xs + 1);
      fprintf(fo, "#define GHEI_%d\t%3d\n\n", i,rg->rg_Box.bo_Ye -
                                               rg->rg_Box.bo_Ys + 1);
      ++i;
    }
  }
  fputs("\n", fo);

  if (bboxes)
  {
    for (i = 0, rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
    {
      if (rg->rg_Type == RGT_BEVELBOX)
      {
        fprintf(fo, "/* *** BevelBox %s *** */\n",  rg->rg_Node.ln_Name);
        fprintf(fo, "#define BLEF_%d\t%3d\n",   i,rg->rg_Box.bo_Xs);
        fprintf(fo, "#define BTOP_%d\t%3d\n",   i,rg->rg_Box.bo_Ys);
        fprintf(fo, "#define BWID_%d\t%3d\n",   i,rg->rg_Box.bo_Xe -
                                                  rg->rg_Box.bo_Xs + 1);
        fprintf(fo, "#define BHEI_%d\t%3d\n\n", i,rg->rg_Box.bo_Ye -
                                                  rg->rg_Box.bo_Ys + 1);
        ++i;
      }
    }
    fputs("\n", fo);
  }
}

/***********************  DeclareWIN(fo)  ****************************/
void
DeclareWIN(fo)
  FILE  *fo;
{
  fprintf(fo, "/* *** Window pos & size *** */\n");
  fprintf(fo, "#define WLEF\t%3d\n", Ph.ph_WinDim.bo_Xs);
  fprintf(fo, "#define WTOP\t%3d\n", Ph.ph_WinDim.bo_Ys);
  fprintf(fo, "#define WWID\t%3d\n", Ph.ph_WinDim.bo_Xe - Ph.ph_WinDim.bo_Xs);
  fprintf(fo, "#define WHEI\t%3d\n", Ph.ph_WinDim.bo_Ye - Ph.ph_WinDim.bo_Ys);
  fprintf(fo, "\n");
}

/***********************  DeclareMain(fo) ****************************/
void
DeclareMain(fo)
  FILE  *fo;
{
  fputs("/*  main function to test gadgets  */\n"
        "int\n"
        "main()\n"
        "{\n"
        "  Screen *Scr;\n"
        "  Gadget *gadgets;\n"
        "\n"
        "  if (Scr = (Screen *)LockPubScreen(NULL))\n"
        "  {\n"
        "    if (gadgets = InitGads(Scr))\n"
        "    {\n"
        "      EWin = (Window *)OpenWindowTags(NULL,\n"
        "             WA_Flags,     WFLG_DRAGBAR|\n"
        "                           WFLG_DEPTHGADGET|\n"
        "                           WFLG_CLOSEGADGET|\n"
        "                           WFLG_SIZEGADGET|\n"
        "                           WFLG_SMART_REFRESH|\n"
        "                           WFLG_REPORTMOUSE|\n"
        "                           WFLG_ACTIVATE,\n"
        "\n"
        "             WA_IDCMP,     LISTVIEWIDCMP|\n"
        "                           IDCMP_NEWSIZE|\n"
        "                           IDCMP_MENUPICK|\n"
        "                           IDCMP_VANILLAKEY|\n"
        "                           IDCMP_RAWKEY|\n"
        "                           IDCMP_CHANGEWINDOW|\n"
        "                           IDCMP_CLOSEWINDOW|\n"
        "                           IDCMP_REFRESHWINDOW,\n"
        "\n"
        "             WA_Left,      WLEF,\n"
        "             WA_Top,       WTOP,\n"
        "             WA_Width,     WWID,\n"
        "             WA_Height,    WHEI,\n"
        "             WA_Title,     \"TPLTEST\",\n"
        "             WA_MinWidth,  32,\n"
        "             WA_MinHeight, 32,\n"
        "             WA_MaxWidth,  -1,\n"
        "             WA_MaxHeight, -1,\n"
        "             WA_AutoAdjust, 1,\n"
        "             WA_PubScreen, NULL,\n"
        "             WA_PubScreenFallBack, 1,\n"
        "             WA_Gadgets,   gadgets,\n"
        "             TAG_END );\n"
        "\n"
        "\n"
        "      if (EWin)\n"
        "      {\n", fo);

  if (border)
  fputs("        drawborders();\n", fo);

  fputs("        IMsg *im;\n"
        "        short notDone = 1;\n"
        "\n"
        "        GT_RefreshWindow(EWin, NULL);\n"
        "        while (notDone)\n"
        "        {\n"
        "          WaitPort(EWin->UserPort);\n"
        "          while (im = GT_GetIMsg(EWin->UserPort))\n"
        "          {\n"
        "            switch (im->Class)\n"
        "            {\n"
        "            case IDCMP_CLOSEWINDOW:\n"
        "              notDone = 0;\n"
        "              break;\n"
        "            case IDCMP_REFRESHWINDOW:\n"
        "              GT_BeginRefresh(EWin);\n"
        "              GT_EndRefresh(EWin, TRUE);\n"
        "              break;\n", fo);

  if (exclude)
  fputs("            case IDCMP_GADGETDOWN:\n"
        "            case IDCMP_GADGETUP:\n"
        "              Gadget *gad = im->IAddress;\n"
        "              if (gad->MutualExclude)\n"
        "              {\n"
        "                switch((long)gad->UserData)\n"
        "                {\n"
        "                case  CHECKBOX_KIND:\n"
        "                  if (gad->Flags & GFLG_SELECTED)\n"
        "                    DisableExcl(gad);\n"
        "                  break;\n"
        "                case  BUTTON_KIND:\n"
        "                  selectgad(gad);\n"
        "                  break;\n"
        "                default:\n"
        "                  DisableExcl(gad);\n"
        "                  break;\n"
        "                }\n"
        "              }\n", fo);

  fputs("            default:\n"
        "              break;\n"
        "            }\n"
        "            GT_ReplyIMsg(im);\n"
        "          }\n"
        "        }\n"
        "        CloseWindow(EWin);\n"
        "      }\n"
        "    }\n"
        "    FreeGads();\n"
        "  }\n"
        "  return (0);\n"
        "}\n"
        "\n", fo);

}
/***********************  DeclareDispFunc(FILE  **********************/
void
DeclareDispFunc(FILE *fo)
{
  fputs("\n/* CallBack function to Sliders & Scrollers */\n"
        "__geta4 long\n"
        "DispFunc(Gadget *gad, WORD Level)\n"
        "{\n  return((long)Level);\n}\n", fo);
}

/***********************  DeclareSelectGad(FILE **********************/
void
DeclareSelectGad(FILE *fo)
{
  fputs("\n/* Mutual Exclusion for Buttons & Boxes */\n"
        "void\n"
        "ReleaseExcl(Gadget *gadget)\n"
        "{\n"
        "  for (short i = 0; i < ALLGADS; ++i)\n"
        "  {\n"
        "    Gadget *gad  = Egadlist[i];\n"
        "    if (gad != gadget)\n"
        "    {\n"
        "      if (gadget->MutualExclude & gad->MutualExclude)\n"
        "        GT_SetGadgetAttrs(gad, EWin, NULL,\n"
        "                          GA_Disabled, 0,\n"
        "                          TAG_END);\n"
        "    }\n"
        "  }\n"
        "}\n"
        "\n"
        "\n"
        "void\n"
        "DisableExcl(Gadget *gadget)\n"
        "{\n"
        "  for (short i = 0; i < ALLGADS; ++i)\n"
        "  {\n"
        "    Gadget *gad  = Egadlist[i];\n"
        "    if (gad == gadget)\n"
        "      continue;\n"
        "    if (gadget->MutualExclude & gad->MutualExclude)\n"
        "    {\n"
        "      switch((long)gad->UserData)\n"
        "      {\n"
        "      case BUTTON_KIND:\n"
        "      case CHECKBOX_KIND:\n"
        "        if (gad->Flags & GFLG_SELECTED)\n"
        "        {\n"
        "          short gad_pos;\n"
        "          gad_pos     = RemoveGadget(EWin, gad);\n"
        "          gad->Flags -= GFLG_SELECTED;\n"
        "          AddGadget(EWin, gad, gad_pos);\n"
        "          RefreshGList(gad, EWin, NULL, 1);\n"
        "        }\n"
        "        break;\n"
        "\n"
        "      default:\n"
        "        GT_SetGadgetAttrs(gad, EWin, NULL,\n"
        "                          GA_Disabled, 1,\n"
        "                          TAG_END);\n"
        "        break;\n"
        "      }\n"
        "    }\n"
        "  }\n"
        "}\n"
        "\n"
        "\n"
        "void\n"
        "selectgad(Gadget *gadget)\n"
        "{\n"
        "  short release = FALSE;\n"
        "  short gad_pos = RemoveGadget(EWin, gadget);\n"
        "  if (gadget->Flags & GFLG_SELECTED)\n"
        "  {\n"
        "    gadget->Flags -= GFLG_SELECTED;\n"
        "    release = TRUE;\n"
        "  }\n"
        "  else\n"
        "    gadget->Flags |= GFLG_SELECTED;\n"
        "\n"
        "  AddGadget(EWin, gadget, gad_pos);\n"
        "  RefreshGList(gadget, EWin, NULL, 1);\n"
        "\n"
        "  if (gadget->MutualExclude)\n"
        "  {\n"
        "    if (release)\n"
        "      ReleaseExcl(gadget);\n"
        "    else\n"
        "      DisableExcl(gadget);\n"
        "  }\n"
        "}\n\n\n", fo);
}


