//
// The Fusion Library Interface for DOS
// Version 1.02
// Copyright (C) 1990, 1991
// Software Dimensions
//
// Dialog Development System
//

#include "fliwin.h"
#include "colors.h"
#include "dds.h"

#include <stdio.h>
#include <dos.h>
#include <string.h>

// These are defined in DDS.CPP

extern int OverrideBlaze;
extern int OmitComments;

//-------------------------------------------------------------------------
//
// Code Generator
//
//-------------------------------------------------------------------------

void DialogWindow::Generate(char *GenTo)
{
  //-------------------------------------------------------------------------
  //
  // Open the file for output
  //
  //-------------------------------------------------------------------------

  FILE *Output;

  Output=fopen(GenTo,"w+t");

  //-------------------------------------------------------------------------
  //
  // Pump out header lines
  //
  //-------------------------------------------------------------------------

  fputs(
    "// Fusion Library Interface\n"
    "// Dialog Development System Automated Code Generation\n"
    "// Contents Copyright (C) 1991 by Software Dimensions\n"
    "//\n",Output);

  if (!OmitComments)
  {
    fputs(
    "// Usage instructions can be found at the bottom of this file\n",Output);
  }

  fputs(
    "// Includes (elements.h automatically includes fli.h/defines.h)\n\n"
    "#include \"elements.h\"\n",Output);

  if (OverrideBlaze)
    fputs("#include \"colors.h\"\n\n",Output);
  else
    fputs("\n",Output);

  //-------------------------------------------------------------------------
  //
  // Derive a class for our dialog and variables
  //
  //-------------------------------------------------------------------------

  fputs("// Class definition (you can copy this to a header file)\n\n",Output);

  if (DerivedClass[0] && DerivedClass)
  {
    fprintf(Output,"class %s : public DialogClass\n"
      "{\n"
      "  public:\n"
      "    %s();\n"
      "    int EventHandler(int);\n",DerivedClass,DerivedClass);
  }
  else
  {
    fputs("class Generate : public DialogClass\n"
      "{\n"
      "  public:\n"
      "    Generate();\n"
      "    int EventHandler(int);\n",Output);
  }

  //-------------------------------------------------------------------------
  //
  // Stick any defined dialog variables into the class
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut>PieceHandler::__DUMMY__ && Piece.LayOut<PieceHandler::Push)
      {
        if (!TrackIt)
        {
          fputs("\n"
            "    // Variable definitions\n"
            "\n",Output);
          TrackIt++;
        }
        switch(Piece.LayOut)
        {
          case PieceHandler::Character:
            fprintf(Output,"    char %s[%d];\n",Piece.Variable,
              strlen(Piece.Mask)+1);
            break;
          case PieceHandler::Integer:
          case PieceHandler::VRadio:
          case PieceHandler::HRadio:
          case PieceHandler::Check:
            fprintf(Output,"    int %s;\n",Piece.Variable);
            break;
          case PieceHandler::Long:
            fprintf(Output,"    long %s;\n",Piece.Variable);
            break;
          case PieceHandler::Float:
            fprintf(Output,"    float %s;\n",Piece.Variable);
            break;
          case PieceHandler::Double:
            fprintf(Output,"    double %s;\n",Piece.Variable);
            break;
          case PieceHandler::Bcd:
            fprintf(Output,"    bcd %s;\n",Piece.Variable);
            break;
        }
      }
    }
  }

  fputs("};\n\n",Output);

  //-------------------------------------------------------------------------
  //
  // Generate the derived classes
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut>PieceHandler::__DUMMY__ &&
        Piece.LayOut<PieceHandler::__DUMMY2__ &&
        Piece.ToBeDerived)
      {
        if (!TrackIt)
        {
          fputs("// Declare derived classes (you can copy these into a header file)\n\n",Output);
          TrackIt++;
        }

        char ClassName[50];

        switch(Piece.LayOut)
        {
          case PieceHandler::Character:
            strcpy(ClassName,"DiaChar");
            break;

          case PieceHandler::Integer:
            strcpy(ClassName,"DiaInt");
            break;

          case PieceHandler::Long:
            strcpy(ClassName,"DiaLong");
            break;

          case PieceHandler::Float:
            strcpy(ClassName,"DiaFloat");
            break;

          case PieceHandler::Double:
            strcpy(ClassName,"DiaDouble");
            break;

          case PieceHandler::Bcd:
            strcpy(ClassName,"DiaBcd");
            break;

          case PieceHandler::Push:
            strcpy(ClassName,"DiaPushButton");
            break;

          case PieceHandler::Check:
            strcpy(ClassName,"DiaCheckBox");
            break;

          case PieceHandler::VRadio:
            strcpy(ClassName,"DiaVertRadio");
            break;

          case PieceHandler::HRadio:
            strcpy(ClassName,"DiaHorizRadio");
            break;

          case PieceHandler::PickGeneric:
            strcpy(ClassName,"DiaPickGeneric");
            break;
        }

        fprintf(Output,"class %s : public %s\n"
          "{\n"
          "public:\n",Piece.DerivedClass,ClassName);

        switch(Piece.LayOut)
        {
          case PieceHandler::Character:
            fprintf(Output,"  %s(int X,int Y,char *Mask,char *Value,int Visual=0,int MChar=0,\n"
              "      int MWidth=0) :\n"
              "    DiaChar(X,Y,Mask,Value,Visual,MChar,MWidth) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Integer:
            fprintf(Output,"  %s(int X,int Y,char *Mask,int &Value) :\n"
              "    DiaInt(X,Y,Mask,Value) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Long:
            fprintf(Output,"  %s(int X,int Y,char *Mask,long &Value) :\n"
              "    DiaLong(X,Y,Mask,Value) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Float:
            fprintf(Output,"  %s(int X,int Y,char *Mask,float &Value) :\n"
              "    DiaFloat(X,Y,Mask,Value) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Double:
            fprintf(Output,"  %s(int X,int Y,char *Mask,double &Value) :\n"
              "    DiaDouble(X,Y,Mask,Value) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Bcd:
            fprintf(Output,"  %s(int X,int Y,char *Mask,bcd &Value) :\n"
              "    DiaBcd(X,Y,Mask,Value) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Push:
            fprintf(Output,"  %s(int X,int Y,char *Text,int Event,int Key=0) :\n"
              "    DiaPushButton(X,Y,Text,Event,Key) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::Check:
            fprintf(Output,"  %s(int X,int Y,int &Checked,char *Text,int Key=0) :\n"
              "    DiaCheckBox(X,Y,Checked,Text,Key) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::HRadio:
            fprintf(Output,"  %s(int X,int Y,int &Button,int Items,char **Choices) :\n"
              "    DiaHorizRadio(X,Y,Button,Items,Choices) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::VRadio:
            fprintf(Output,"  %s(int X,int Y,int &Button,int Items,char **Choices) :\n"
              "    DiaVertRadio(X,Y,Button,Items,Choices) { };\n",Piece.DerivedClass);
            break;

          case PieceHandler::PickGeneric:
            fprintf(Output,"  int Item;\n"
              "  int ItemCount;\n\n"
              "  %s() :\n"
              "    DiaPickGeneric(%d,%d,%d,%d,Item,ItemCount)\n"
              "  {\n"
              "    // Define other items in this constructor *or*\n"
              "    // set the ITEM or ITEMCOUNT to another location\n"
              "    Item=0;\n"
              "    ItemCount=0;\n"
              "  };\n\n"
              "  // Take the GetItem function and fill it with your own code.\n\n"
              "  char *GetItem(int ItemNumber);\n\n",Piece.DerivedClass,
                Piece.X,Piece.Y,Piece.Width-3,Piece.Height);
            break;
        }
        fputs("  // **Add living functions here\n};\n"
          "\n",Output);
      }
    }
  }

  //-------------------------------------------------------------------------
  //
  // Generate the constants for the push buttons
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut==PieceHandler::Push)
      {
        if (!TrackIt)
        {
          fputs("// Constants (for Push Buttons)\n"
            "\n",Output);
          TrackIt++;
        }
        fprintf(Output,"const %s=%d;\n",Piece.Constant,Piece.HelpId);
      }
    }
    if (TrackIt)
      fputs("\n",Output);
  }

  //-------------------------------------------------------------------------
  //
  // Generate the event handler
  //
  //-------------------------------------------------------------------------

  fputs("// Event handler\n\n",Output);

  fprintf(Output,
    "int %s::EventHandler(int Event)\n"
    "{\n"
    "  switch(Event)\n"
    "  {\n"
    "    case kbEsc:\n"
    "    case kbCr:\n"
    "    case CloseEvent:\n"
    "    case OutsideEvent:\n"
    "      return StopEvent;\n"
    ,(DerivedClass[0])?DerivedClass:"Generate");

  //-------------------------------------------------------------------------
  //
  // If there are push buttons, place the case constants inside
  // the event handler
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut==PieceHandler::Push)
      {
        if (!TrackIt)
        {
          fputs("\n    // Cases (for Push Buttons)\n"
                "    // **Change to suit your needs\n\n",Output);
          TrackIt++;
        }
        fprintf(Output,"    case %s:\n"
          "      return StopEvent;\n",Piece.Constant);
      }
    }
  }

  fputs("  }\n"
    "  return CompleteEvent;\n"
    "}\n\n"
    "// Constructor (defines your dialog)\n\n",Output);

  //-------------------------------------------------------------------------
  //
  // Generate the constructor
  //
  //-------------------------------------------------------------------------

  fprintf(Output,
    "%s::%s() : DialogClass(%d,%d,\"%s\")\n"
    "{\n\n",(DerivedClass[0])?DerivedClass:"Generate",
    (DerivedClass[0])?DerivedClass:"Generate",
    Width,Height,Title);

  //-------------------------------------------------------------------------
  //
  // initialize any defined dialog variables
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut>PieceHandler::__DUMMY__ && Piece.LayOut<PieceHandler::Push)
      {
        if (!TrackIt)
        {
          fputs("  // Initialize Variables\n"
            "\n",Output);
          TrackIt++;
        }
        switch(Piece.LayOut)
        {
          case PieceHandler::Character:
            fprintf(Output,"  %s[0]=0;\n",Piece.Variable);
            break;
          case PieceHandler::Integer:
          case PieceHandler::VRadio:
          case PieceHandler::HRadio:
          case PieceHandler::Check:
          case PieceHandler::Long:
          case PieceHandler::Float:
          case PieceHandler::Double:
          case PieceHandler::Bcd:
            fprintf(Output,"  %s=0;\n",Piece.Variable);
            break;
        }
      }
    }
    if (TrackIt)
    {
      fputs("\n",Output);
    }
  }

  //-------------------------------------------------------------------------
  //
  // Output Blaze Drawing Code (not Text)
  //
  //-------------------------------------------------------------------------

  int MouseHidden=0; // Was mouse hidden

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut<PieceHandler::__DUMMY__)
      {
        if (!TrackIt)
        {
          fputs("  // Display blaze objects\n\n"
            "  MouseHide(); // Hide the mouse\n\n",Output);
          MouseHidden++;
          TrackIt++;
        }
        switch(Piece.LayOut)
        {
          case PieceHandler::Box:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.Box(%d,%d,%d,%d,%d);\n":
              "  Blaze.Box(%d,%d,%d,%d,Colors.DiaInterior);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Height,Piece.Color);
            break;

          case PieceHandler::FilledBox:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.BoxFilled(%d,%d,%d,%d,%d);\n":
              "  Blaze.BoxFilled(%d,%d,%d,%d,Colors.DiaInterior);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Height,Piece.Color);
            break;

          case PieceHandler::HorizontalLine:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.CharacterRepeater(%d,%d,%d,%d,196);\n":
              "  Blaze.CharacterRepeater(%d,%d,%d,Colors.DiaInterior,196);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Color);
            break;

          case PieceHandler::VerticalLine:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.CharacterRepeaterDown(%d,%d,%d,%d,179);\n":
              "  Blaze.CharacterRepeaterDown(%d,%d,%d,Colors.DiaInterior,179);\n",
              Piece.X,Piece.Y,Piece.Height,Piece.Color);
            break;

          case PieceHandler::Shadow:
            fprintf(Output,"  Blaze.Shadow(%d,%d,%d,%d);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Height);
            break;

          case PieceHandler::EraseArea:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.EraseArea(%d,%d,%d,%d,%d);\n":
              "  Blaze.EraseArea(%d,%d,%d,%d,Colors.DiaInterior);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Height,Piece.Color);
            break;

          case PieceHandler::ColorizeArea:
            fprintf(Output,
              (!OverrideBlaze)?
              "  Blaze.BoxAttribute(%d,%d,%d,%d,%d);\n":
              "  Blaze.BoxAttribute(%d,%d,%d,%d,Colors.DiaInterior);\n",
              Piece.X,Piece.Y,Piece.Width,Piece.Height,Piece.Color);
            break;
        }
      }
    }
    if (TrackIt)
    {
      fputs("\n",Output);
    }
  }

  //-------------------------------------------------------------------------
  //
  // Output Optimized Blaze Text Code
  //
  // Although this segment of code is extremely short, it does a lot!
  //
  // The Blaze optimizer is designed to scan the screen and generate the
  // cooresponding Blaze commands.  If two blocks are side by side and
  // are the same color, the optimizer will not reposition the cursor.  If
  // the color is the same for two consecutive blocks, the color will not
  // be reloaded.  Both of these optimizations are designed to reduce the
  // amount of code that is required and also to make the code easy to read.
  //
  //-------------------------------------------------------------------------

  int BlazeOverriden=0; // was blaze overriden?

  #define DumpString \
    if (!TrackIt) \
    { \
      fputs("  // Display blaze text\n\n",Output); \
      if (!MouseHidden) \
      { \
        MouseHidden++; \
        fputs("  MouseHide(); // Hide the mouse\n\n",Output); \
      } \
      TrackIt++; \
    } \
    if (!OverrideBlaze) \
    { \
      if (SideBySide && PreviousColor!=ColorStore) \
        fprintf(Output,"  Blaze << %d << \"%s\";\n",ColorStore,Storage); \
      else if (SideBySide && PreviousColor==ColorStore) \
        fprintf(Output,"  Blaze << \"%s\";\n",Storage); \
      else if (CurrentLocation && PreviousColor!=ColorStore) \
        fprintf(Output,"  Blaze (%d,%d) << %d << \"%s\";\n",XStart,y,ColorStore,Storage); \
      else \
        fprintf(Output,"  Blaze (%d,%d) << \"%s\";\n",XStart,y,Storage); \
      Storage[0]=0; \
    }  \
    else \
    { \
      if (SideBySide && !BlazeOverriden) \
        fprintf(Output,"  Blaze << Colors.DiaInterior << \"%s\";\n",Storage); \
      else if (SideBySide && BlazeOverriden) \
        fprintf(Output,"  Blaze << \"%s\";\n",Storage); \
      else if (CurrentLocation && !BlazeOverriden) \
        fprintf(Output,"  Blaze (%d,%d) << Colors.DiaInterior << \"%s\";\n",XStart,y,Storage); \
      else \
        fprintf(Output,"  Blaze (%d,%d) << \"%s\";\n",XStart,y,Storage); \
      BlazeOverriden++; \
      Storage[0]=0; \
    }

  #define ControlIntercept \
    if (*OutPut<32) \
    { \
      char Intercept[10]; \
      sprintf(Intercept,"\\x%x",*OutPut); \
      strcat(Storage,Intercept); \
      CurrentLocation=strlen(Storage); \
    } \
    else \
    { \
      Storage[CurrentLocation++]=*OutPut; \
      Storage[CurrentLocation]=0; \
    }

  int PreviousColor=0; // previous color
  int ColorStore=0; // current color

  int TrackIt=0;

  for (int y=0;y<Height-2;y++)
  {
    char *OutPut=Interior[y];

    char Storage[300] = "\0";

    int CurrentLocation=0;
    int XStart=0;
    int SideBySide=0;

    for (int x=0;x<Width-2;x++,OutPut+=2)
    {
      if (*OutPut)
      {
        if (CurrentLocation)
        {
          if (*(OutPut+1)!=ColorStore)
          {
            DumpString;
            PreviousColor=ColorStore;
            ColorStore=*(OutPut+1);
            SideBySide=1;
            CurrentLocation=0;
            XStart=x;
          }
          ControlIntercept;
        }
        else
        {
          PreviousColor=ColorStore;
          ColorStore=*(OutPut+1);
          ControlIntercept;
          SideBySide=0;
          XStart=x;
        }
      }
      else
      {
        if (CurrentLocation)
        {
          DumpString;
          CurrentLocation=0;
          SideBySide=0;
        }
      }
    }
    if (CurrentLocation)
    {
      DumpString;
    }
  }

  if (TrackIt)
  {
    fputs("\n",Output);
  }

  if (MouseHidden)
  {
    fputs("  MouseShow(); // Restore the mouse\n\n",Output);
  }

  //-------------------------------------------------------------------------
  //
  // Output Group Headings
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut>PieceHandler::__DUMMY2__)
      {
        if (!TrackIt)
        {
          fputs("  // Declare group headings\n\n",Output);
          TrackIt++;
        }
        fprintf(Output,"  GroupHeading(%d,%d,%d,\"%s\",%s);\n",
          Piece.X,Piece.Y,Piece.GroupCode,Piece.Text,Piece.HotKey);
      }
    }
    if (TrackIt)
    {
      fputs("\n",Output);
    }
  }

  //-------------------------------------------------------------------------
  //
  // Output Dialog Class Code
  //
  //-------------------------------------------------------------------------

  if (NumberPieces)
  {
    for (int i=0,TrackIt=0;i<NumberPieces;i++)
    {
      PieceHandler &Piece=*Pieces[i];
      if (Piece.LayOut>PieceHandler::__DUMMY__ &&
        Piece.LayOut<PieceHandler::__DUMMY2__)
      {
        if (!TrackIt)
        {
          fputs("  // Declare elements, hot keys, help, and groups\n\n",Output);
          TrackIt++;
        }

        char Remember[50];

        if (Piece.GroupCode)
          sprintf(Remember,"GroupElement(%d,",Piece.GroupCode);
        else
          strcpy(Remember,"Element(");

        char ClassName[50];

        if (Piece.ToBeDerived)
          strcpy(ClassName,Piece.DerivedClass);
        else
        {
          switch(Piece.LayOut)
          {
            case PieceHandler::Character:
              strcpy(ClassName,"DiaChar");
              break;

            case PieceHandler::Integer:
              strcpy(ClassName,"DiaInt");
              break;

            case PieceHandler::Long:
              strcpy(ClassName,"DiaLong");
              break;

            case PieceHandler::Float:
              strcpy(ClassName,"DiaFloat");
              break;

            case PieceHandler::Double:
              strcpy(ClassName,"DiaDouble");
              break;

            case PieceHandler::Bcd:
              strcpy(ClassName,"DiaBcd");
              break;

            case PieceHandler::Push:
              strcpy(ClassName,"DiaPushButton");
              break;

            case PieceHandler::Check:
              strcpy(ClassName,"DiaCheckBox");
              break;

            case PieceHandler::VRadio:
              strcpy(ClassName,"DiaVertRadio");
              break;

            case PieceHandler::HRadio:
              strcpy(ClassName,"DiaHorizRadio");
              break;
          }
        }

        switch(Piece.LayOut)
        {
          case PieceHandler::Character:
            if (!Piece.ScrollWidth && !Piece.MaskWidth)
              fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
                Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            else if (Piece.ScrollWidth && !Piece.MaskWidth)
              fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s,%d));\n",Remember,ClassName,
                Piece.X,Piece.Y,Piece.Mask,Piece.Variable,Piece.ScrollWidth);
            else
              fprintf(Output,"  %snew %s(%d,%d,0,%s,%d,'%c',%d));\n",Remember,ClassName,
                Piece.X,Piece.Y,Piece.Variable,Piece.ScrollWidth,
                  (char)Piece.MaskCharacter,Piece.MaskWidth);
            break;

          case PieceHandler::Integer:
            fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            break;

          case PieceHandler::Long:
            fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            break;

          case PieceHandler::Float:
            fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            break;

          case PieceHandler::Double:
            fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            break;

          case PieceHandler::Bcd:
            fprintf(Output,"  %snew %s(%d,%d,\"%s\",%s));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Mask,Piece.Variable);
            break;

          case PieceHandler::Push:
            fprintf(Output,
              (*Piece.HotKey)?"  %snew %s(%d,%d,\"%s\",%s,%s));\n":
              "  %snew %s(%d,%d,\"%s\",%s));\n"
              ,Remember,ClassName,
              Piece.X,Piece.Y,
              Piece.Text,Piece.Constant,Piece.HotKey);
            break;

          case PieceHandler::Check:
            fprintf(Output,
              (*Piece.HotKey)?"  %snew %s(%d,%d,%s,\"%s\",%s));\n":
              "  %snew %s(%d,%d,%s,\"%s\"));\n",Remember,ClassName,
              Piece.X,Piece.Y,Piece.Variable,Piece.Text,Piece.HotKey);
            break;

          case PieceHandler::HRadio:
          case PieceHandler::VRadio:
            fprintf(Output,
              "  %snew %s(%d,%d,%s,0,0));\n"
              ,Remember,ClassName,Piece.X,Piece.Y,Piece.Variable);
            fputs("  *this + ",Output);
            for (int j=0,k=0;j<10;j++)
            {
              if (!*(Piece.Elements[j]+0))
                break;
              if (k)
                fputs("\n        + ",Output);
              k++;
              fprintf(Output,"\"%s\"",Piece.Elements[j]);
            }
            fputs(";\n",Output);
            break;

          case PieceHandler::PickGeneric:
            fprintf(Output,"  %snew %s());\n",Remember,Piece.DerivedClass);
            break;
        }

        if (Piece.Prompter && *Piece.HotKey)
        {
          fprintf(Output,"  HotKey(%d,%d,\"%s\",%s);\n",Piece.PromptX,
            Piece.PromptY,Piece.Prompter,Piece.HotKey);
        }

        if (Piece.HelpId && !Piece.Constant)
        {
          fprintf(Output,"  FusionHelp(%d);\n",Piece.HelpId);
        }

        if (Piece.Help && *Piece.Help)
        {
          fprintf(Output,"  Help(\"%s\");\n",Piece.Help);
        }

        fputs("\n",Output);
      }
    }
  }

  //-------------------------------------------------------------------------
  //
  // Close up the function we created
  //
  //-------------------------------------------------------------------------

  fputs("  // ... End of dialog definition\n"
    "\n"
    "}\n",Output);

  //-------------------------------------------------------------------------
  //
  // Provide instructions about class usage
  //
  //-------------------------------------------------------------------------

  if (!OmitComments)
  {
    fputs("\n/*\n"
      "   DDS CODE USAGE INSTRUCTIONS\n\n"
      "   Here is all you have to do to use this ready made dialog:\n\n"
      "   1. Copy the \"Definition\" section into a header file.\n"
      "      The declaration section is at the VERY TOP of this file.\n\n"
      "   2. Define that header file in any file that will use this\n"
      "      dialog.  Use code similar to this:\n\n"
      "      #include \"mydialog.h\" // <- This header will declare the class\n\n"
      "      void myFunc()\n"
      "      {\n\n"
      "        ...\n\n",Output);
    fprintf(Output,
      "        %s &PowerUp = *new %s();\n"
      "        int ReturnedCode = PowerUp.UseDialog();\n\n"
      "        // Evaluate ReturnedCode here ...\n"
      "        // Mess with variables in the PowerUp class now ...\n\n"
      "        delete &PowerUp;\n\n"
      "        ...\n\n"
      "      }\n"
      "*/\n",DerivedClass,DerivedClass);
  }

  fputs("\n// Thank you for using DDS!",Output);

  fclose(Output);
}


