
/*
 * MAIN.C
 *
 * TPLEDIT [project]
 */

#include "defs.h"

Prototype void HandleMenu(IMsg *);
Prototype void BoxComplete();
Prototype void Title(char *);
Prototype void TitleState(void);
Prototype void TitleXY(short, short);
Prototype TplRegion *SetCurRegion(TplRegion *);
Prototype void init_test(void);

Prototype short QuitCheck(void);
Prototype short do_request(char *, char *, UWORD *);

Prototype struct     EasyStruct textreq;
Prototype char       ProjName[256];
Prototype char       ProjSrcName[256];
Prototype char       TmpBuf[256];

Prototype Window     *Win;
Prototype Screen     *Scr;
Prototype NewMenu    Nm[];

Prototype Gadget     *GList;
Prototype Menu       *GMenu;

Prototype List       RegList;
Prototype List       PPList;

Prototype TplRegion  *CurRegion;
Prototype short      CurState;

Prototype uword      copynum;
Prototype uword      exclnum;
Prototype short      savemain;
Prototype short      issaved;

Prototype ProjHeader Ph;

Prototype short      NotDone;
Prototype short      DDebug;
Prototype uword      IdNo;
Prototype short      NewType;
Prototype long       NewFlags;
Prototype struct     VisualInfo *VisInfo;


void   myexit(void);

NewMenu Nm[] =
{
  {NM_TITLE, "Project"},
  {NM_ITEM,  "Save",        NULL, 0, 0, MENU_PROJ_SAVE},
  {NM_ITEM,  "SaveC",       NULL, 0, 0, MENU_PROJ_SAVESRC},
  {NM_SUB,   "Excl Main()", NULL, 0, 0, MENU_PROJ_SAVEMAINNO},
  {NM_SUB,   "Incl Main()", NULL, 0, 0, MENU_PROJ_SAVEMAINYES},
  {NM_ITEM,  "SaveAs",      NULL, 0, 0, MENU_PROJ_SAVEAS},
  {NM_ITEM,  "SaveAsC",     NULL, 0, 0, MENU_PROJ_SAVEASSRC},
  {NM_SUB,   "Excl Main()", NULL, 0, 0, MENU_PROJ_SAVEASMAINNO},
  {NM_SUB,   "Incl Main()", NULL, 0, 0, MENU_PROJ_SAVEASMAINYES},
  {NM_ITEM,  "Load",        NULL, 0, 0, MENU_PROJ_LOAD},
  {NM_ITEM,  "Merge",       NULL, 0, 0, MENU_PROJ_MERGE},
  {NM_ITEM,  "Quit",        NULL, 0, 0, MENU_PROJ_QUIT},


  {NM_TITLE, "Gadgets"},
  {NM_ITEM,  "Invisible", NULL, CHECKIT|CHECKED, GADGET_EXCL - 1, MENU_GADGET},
  {NM_ITEM,  "Button",    NULL, CHECKIT, GADGET_EXCL -     2, MENU_GADGET +  1},
  {NM_ITEM,  "CheckBox",  NULL, CHECKIT, GADGET_EXCL -     4, MENU_GADGET +  2},
  {NM_ITEM,  "Integer",   NULL, CHECKIT, GADGET_EXCL -     8, MENU_GADGET +  3},
  {NM_ITEM,  "ListView",  NULL, CHECKIT, GADGET_EXCL -    16, MENU_GADGET +  4},
  {NM_ITEM,  "MutualeXcl",NULL, CHECKIT, GADGET_EXCL -    32, MENU_GADGET +  5},
  {NM_ITEM,  "Number",    NULL, CHECKIT, GADGET_EXCL -    64, MENU_GADGET +  6},
  {NM_ITEM,  "Cycle",     NULL, CHECKIT, GADGET_EXCL -   128, MENU_GADGET +  7},
  {NM_ITEM,  "Palette",   NULL, CHECKIT, GADGET_EXCL -   256, MENU_GADGET +  8},
  {NM_ITEM,  "Scroller",  NULL, CHECKIT, GADGET_EXCL -   512, MENU_GADGET +  9},
  {NM_ITEM,  "Border",    NULL, CHECKIT, GADGET_EXCL -  1024, MENU_GADGET + 10},
  {NM_ITEM,  "Slider",    NULL, CHECKIT, GADGET_EXCL -  2048, MENU_GADGET + 11},
  {NM_ITEM,  "String",    NULL, CHECKIT, GADGET_EXCL -  4096, MENU_GADGET + 12},
  {NM_ITEM,  "Text",      NULL, CHECKIT, GADGET_EXCL -  8192, MENU_GADGET + 13},

  {NM_TITLE, "Edit"},
  {NM_ITEM,  "LockLinkTo",  NULL, 0, 0, MENU_EDIT_LOCK},
  {NM_ITEM,  "UnLockLink",  NULL, 0, 0, MENU_EDIT_UNLOCK},
  {NM_ITEM,  "SortRegions", NULL, 0, 0, MENU_EDIT_SORT},

  {NM_TITLE, "Snap"},
  {NM_ITEM,   "1",  NULL, CHECKIT|CHECKED, SNAP_EXCL - 1, MENU_SNAP + 1},
  {NM_ITEM,   "2",  NULL, CHECKIT, SNAP_EXCL -    2, MENU_SNAP +  2},
  {NM_ITEM,   "4",  NULL, CHECKIT, SNAP_EXCL -    4, MENU_SNAP +  4},
  {NM_ITEM,   "6",  NULL, CHECKIT, SNAP_EXCL -    8, MENU_SNAP +  6},
  {NM_ITEM,   "8",  NULL, CHECKIT, SNAP_EXCL -   16, MENU_SNAP +  8},
  {NM_ITEM,  "10",  NULL, CHECKIT, SNAP_EXCL -   32, MENU_SNAP + 10},
  {NM_ITEM,  "12",  NULL, CHECKIT, SNAP_EXCL -   64, MENU_SNAP + 12},
  {NM_ITEM,  "14",  NULL, CHECKIT, SNAP_EXCL -  128, MENU_SNAP + 14},
  {NM_ITEM,  "16",  NULL, CHECKIT, SNAP_EXCL -  256, MENU_SNAP + 16},
  {NM_ITEM,  "18",  NULL, CHECKIT, SNAP_EXCL -  512, MENU_SNAP + 18},
  {NM_ITEM,  "20",  NULL, CHECKIT, SNAP_EXCL - 1024, MENU_SNAP + 20},

  {NM_END}
};

char      ProjName[256];
char      ProjSrcName[256];
char      TitleBuf[256];
char      TmpBuf[256];

Window    *Win;
Screen    *Scr;
Gadget    *GList;
Menu      *GMenu;
struct    VisualInfo *VisInfo;

List      RegList;
List      PPList;

TplRegion *CurRegion;
short     CurState = STATE_TEST;
short     ButState;

short     DDebug;

short     CoorSnap = 1;

uword     IdNo;

short     NewType  = 0;
long      NewFlags = 1L << 4;   /* in */

uword     copynum  = 1;
uword     exclnum  = 0;
short     savemain = FALSE;
short     issaved  = TRUE;

long      WinMask;

ProjHeader Ph;

short     NotDone = 1;
Box       TBox;
short     TX, TY;

/***********************  main **********************************/

main(ac, av)
  int   ac;
  char  *av[];
{
  short  i;

  NewList(&RegList);
  NewList(&PPList);

  atexit(myexit);

  for (i = 1; i < ac; ++i)
  {
    char  *ptr = av[i];

    if (*ptr != '-')
    {
      strcpy(ProjName, ptr);
      continue;
    }
    ptr += 2;
    switch (ptr[-1])
    {
    case 'd':
      ++DDebug;
    default:
      break;
    }
  }

  if ((Scr     = LockPubScreen(NULL)) == NULL)
    exit(20);

  if ((VisInfo = GetVisualInfo(Scr, TAG_END)) == NULL)
    exit(22);

  if ((GMenu   = CreateMenus(Nm, GTMN_Menu, 1, TAG_END)) == NULL)
    exit(24);

  if (LayoutMenus(GMenu, VisInfo, TAG_END) == 0)
    exit(25);


  short yoffset =  Scr->Height - 200;


  Ph.ph_WinDim.bo_Xs    =   0;
  Ph.ph_WinDim.bo_Ys    =   (yoffset > 200) ? 200 : yoffset;
  Ph.ph_WinDim.bo_Xe    = 200;
  Ph.ph_WinDim.bo_Ye    = Ph.ph_WinDim.bo_Ys + 200;
  Ph.ph_MinMaxDim.bo_Xs =  32;
  Ph.ph_MinMaxDim.bo_Ys =  32;
  Ph.ph_MinMaxDim.bo_Xe =  -1;
  Ph.ph_MinMaxDim.bo_Ye =  -1;

  if (OpenEditWindow() < 0)
    exit(26);
  if (DDebug)
    puts("done OpenEditWindow");


  if (ProjName[0] == 0)
    strcpy(ProjName, "unnamed");
  else
    LoadProject(ProjName);

  MakeAllGadgets();
  if (DDebug)
    puts("done MakeAllGadgets");

/*
 * Open Window
 */

  Win = OpenWindowTags(NULL,
                       WA_Flags,             WFLG_DRAGBAR |
                                             WFLG_DEPTHGADGET |
                                             WFLG_CLOSEGADGET |
                                             WFLG_SIMPLE_REFRESH |
                                             WFLG_REPORTMOUSE |
                                             WFLG_SIZEGADGET,

                       WA_IDCMP,             IDCMP_NEWSIZE |
                                             IDCMP_MOUSEBUTTONS |
                                             IDCMP_GADGETDOWN |
                                             IDCMP_GADGETUP |
                                             IDCMP_MENUPICK |
                                             IDCMP_VANILLAKEY |
                                             IDCMP_RAWKEY |
                                             IDCMP_CHANGEWINDOW |
                                             IDCMP_CLOSEWINDOW |
                                             IDCMP_REFRESHWINDOW |
                                             IDCMP_MOUSEMOVE |
                                             IDCMP_ACTIVEWINDOW,

                       WA_Left,              Ph.ph_WinDim.bo_Xs,
                       WA_Top,               Ph.ph_WinDim.bo_Ys,
                       WA_Width,             Ph.ph_WinDim.bo_Xe - Ph.ph_WinDim.bo_Xs,
                       WA_Height,            Ph.ph_WinDim.bo_Ye - Ph.ph_WinDim.bo_Ys,
                       WA_Title,             ProjName,
                       WA_MinWidth,          Ph.ph_MinMaxDim.bo_Xs,
                       WA_MinHeight,         Ph.ph_MinMaxDim.bo_Ys,
                       WA_MaxWidth,          Ph.ph_MinMaxDim.bo_Xe,
                       WA_MaxHeight,         Ph.ph_MinMaxDim.bo_Ye,
                       WA_AutoAdjust,        1,
                       WA_PubScreen,         NULL,
                       WA_PubScreenFallBack, 1,
                       WA_Gadgets,           GList,
                       TAG_END);

  if (Win == NULL)
    exit(27);
  if (DDebug)
    puts("done OpenWinWindow");

  WinMask = 1 << Win->UserPort->mp_SigBit;

  SetMenuStrip(Win, GMenu);

  if (DDebug)
    puts("done SetMenuStrip");
  Title("TPLEDIT 1.0 PUBLIC DOMAIN, Matthew Dillon");

/*
 * Main Loop
 */

  EnableGadgets();
  if (DDebug)
    puts("done EnableGadgets");

  GT_RefreshWindow(Win, NULL);

  while (NotDone)
  {
    if (DDebug)
      puts("looping");
    IMsg  *im;
    long   mask;

    mask = Wait(WinMask |
                EWinMask |
                SIGBREAKF_CTRL_C |
                SIGBREAKF_CTRL_E |
                SIGBREAKF_CTRL_F);

    if (mask & SIGBREAKF_CTRL_C)
      NotDone = 0;

    if (Win)
    {
      while (im = GT_GetIMsg(Win->UserPort))
      {
        if (DDebug)
          puts("Win");
        short  saveX = im->MouseX;
        short  saveY = im->MouseY;

        im->MouseX = (saveX + (CoorSnap >> 1)) / CoorSnap * CoorSnap;
        im->MouseY = (saveY + (CoorSnap >> 1)) / CoorSnap * CoorSnap;

        if (DDebug &&
            im->Class != IDCMP_MOUSEMOVE &&
            im->Class != IDCMP_INTUITICKS)
          printf("CLASS %08lx CODE %d IA=%08lx\n",
                  im->Class, im->Code, im->IAddress);

        switch (im->Class)
        {
        case IDCMP_ACTIVEWINDOW:
          ClearMenuStrip(EWin);
          SetMenuStrip(Win, GMenu);
          break;

        case IDCMP_CHANGEWINDOW:
          Ph.ph_WinDim.bo_Xs = Win->LeftEdge;
          Ph.ph_WinDim.bo_Ys = Win->TopEdge;
          Ph.ph_WinDim.bo_Xe = Win->LeftEdge + Win->Width;
          Ph.ph_WinDim.bo_Ye = Win->TopEdge  + Win->Height;
          break;

        case IDCMP_CLOSEWINDOW:
          NotDone = QuitCheck();
          break;

        case IDCMP_REFRESHWINDOW:
          GT_BeginRefresh(Win);

          TplRegion *rg;
          for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node))
          {
            if (rg->rg_Type == RGT_BEVELBOX)
            {
              short leftedge   = rg->rg_Box.bo_Xs;
              short topedge    = rg->rg_Box.bo_Ys;
              short width      = rg->rg_Box.bo_Xe - rg->rg_Box.bo_Xs + 1;
              short height     = rg->rg_Box.bo_Ye - rg->rg_Box.bo_Ys + 1;
              DrawBevelBox(Win->RPort, leftedge, topedge, width, height,
                            GT_VisualInfo, VisInfo,
                            ((rg->rg_SpecFlags & SPEC_RECESSED) ?
                                             GTBB_Recessed : TAG_IGNORE), TRUE,
                            TAG_END);
            }
          }

          GT_EndRefresh(Win, TRUE);
          break;

        case IDCMP_GADGETDOWN:
        case IDCMP_GADGETUP:
          if (SetCurRegion(FindRegionByGad((Gadget *) im->IAddress)))
          {
            UpdateEWinInfo(CurRegion);
            TitleState();
            if (CurState == STATE_TEST)
            {
              if ((CurRegion->rg_ExclGroup) ||
                  (CurRegion->rg_SpecFlags & SPEC_CHECKED))
              {
                Gadget *gad = CurRegion->rg_Gad;
                switch (CurRegion->rg_Type)
                {
                case RGT_BUTTON:
                case RGT_CHECKBOX:
                  selectgad(gad, CurRegion->rg_Type);
                  break;

                case RGT_STRING:
                case RGT_LISTVIEW:
                case RGT_CYCLE:
                case RGT_INTEGER:
                case RGT_SLIDER:
                  DisableExcl(gad);

                default:
                  break;
                }
              }
            }
          }
          break;

        case IDCMP_MENUPICK:
          HandleMenu(im);
          break;

        case IDCMP_MOUSEBUTTONS:
          switch (im->Code)
          {
          case SELECTDOWN:
            switch (CurState)
            {
            case STATE_UNLINKREGION:
              if (CurRegion && (CurRegion->rg_Type == RGT_LISTVIEW))
              {
                UnLink(CurRegion);
                ReMakeEverything();
                Title("UnLink Successful");
                init_test();
              }
              break;

            case STATE_LINKREGION:
              if (CurRegion && (CurRegion->rg_Type == RGT_LISTVIEW))
              {
                TplRegion *tr;

                if (tr = FindRegion(saveX, saveY))
                {
                  if (tr->rg_Type == RGT_STRING)
                  {
                    CurRegion->rg_LockedTo = tr;
                    tr->rg_LockedTo  = CurRegion;

                    tr->rg_Box.bo_Xs = CurRegion->rg_Box.bo_Xs;
                    tr->rg_Box.bo_Xe = CurRegion->rg_Box.bo_Xe;
                    tr->rg_Box.bo_Ys = CurRegion->rg_Box.bo_Ye + 1;
                    tr->rg_Box.bo_Ye = tr->rg_Box.bo_Ys + 15;
                    ReMakeEverything();
                    Title("Link Successful");
                    init_test();
                    break;
                  }
                }
              }
              Title("Link failed !");
              break;

            case STATE_EXCLREGION:
              if (CurRegion && CurRegion->rg_Type)
              {
                TplRegion *tr;

                if (tr = FindRegion(saveX, saveY))
                {
                  if (tr == CurRegion)
                  {
                    tr->rg_ExclGroup = 0;
                  }
                  else
                  {
                    if (!CurRegion->rg_ExclGroup)
                      CurRegion->rg_ExclGroup = 1L << exclnum++;

                    tr->rg_ExclGroup |= CurRegion->rg_ExclGroup;
                  }
                  init_test();
                }
              }
              break;

            case STATE_NEWREGION:
              TBox.bo_Xs = TBox.bo_Xe = im->MouseX;
              TBox.bo_Ys = TBox.bo_Ye = im->MouseY;
              DrawBox(&TBox);
              TitleState();
              ButState |= 4;

            default:
              break;
            }

            if ((CurState != STATE_LINKREGION) &&
                (SetCurRegion(FindRegion(saveX, saveY))))
            {
              switch (CurState)
              {
              case STATE_DELREGION:
                DeleteTplRegion(CurRegion);
                ReMakeEverything();
                Title("Test Gadgets");
                init_test();
                break;

              case STATE_COPYREGION:
                UpdateEWinInfo(CurRegion);
                TitleState();

                TBox = CurRegion->rg_Box;
                sprintf(Buf_region_str, "%s_%d", CurRegion->rg_Node.ln_Name, copynum);
                ++copynum;

                TplRegion *tr = CurRegion;

                BoxComplete();

                SetCurRegion(tr);
                CurState  = STATE_MOVEREGION;
                GT_SetGadgetAttrs(Gad_actions_mx, EWin, NULL,
                                  GTMX_Active, ACT_MOVE,
                                  TAG_END);
                Title("Move Copy to New Place");

              case STATE_SIZEREGION:
              case STATE_MOVEREGION:
                TX = im->MouseX;
                TY = im->MouseY;
                UpdateEWinInfo(CurRegion);

                short ok = FALSE;
                switch(CurRegion->rg_Type)
                {
                case RGT_CHECKBOX:
                  if (CurState == STATE_SIZEREGION)
                    break;
                  CurRegion->rg_Box.bo_Xe = CurRegion->rg_Box.bo_Xs + 25;
                  CurRegion->rg_Box.bo_Ye = CurRegion->rg_Box.bo_Ys + 10;
                  ok = TRUE;
                  break;

                case RGT_MX:
                  if (CurState == STATE_SIZEREGION)
                    break;
                  CurRegion->rg_Box.bo_Xe = CurRegion->rg_Box.bo_Xs + 16;
                  CurRegion->rg_Box.bo_Ye = CurRegion->rg_Box.bo_Ys +  8;
                  ok = TRUE;
                  break;

                case RGT_STRING:
                  if (CurRegion->rg_LockedTo)
                    break;

                default:
                  ok = TRUE;
                  break;
                }
                if (ok)
                {
                  TBox = CurRegion->rg_Box;
                  DrawBox(&TBox);
                  TitleState();
                  ButState |= 4;
                }
                break;

              case STATE_TEST:
                UpdateEWinInfo(CurRegion);
                TitleState();

              default:
                break;
              }
            }

            ButState |= 1;
            break;

          case SELECTUP:
            if (ButState & 4)
            {
              DrawBox(&TBox);
              TitleState();

              switch (CurState)
              {
              case STATE_NEWREGION:
                TBox.bo_Xe = im->MouseX;
                TBox.bo_Ye = im->MouseY;
                break;

              case STATE_MOVEREGION:
                TBox.bo_Xs += im->MouseX - TX;
                TBox.bo_Xe += im->MouseX - TX;
                TBox.bo_Ys += im->MouseY - TY;
                TBox.bo_Ye += im->MouseY - TY;
                break;

              case STATE_SIZEREGION:
                TBox.bo_Xe += im->MouseX - TX;
                TBox.bo_Ye += im->MouseY - TY;
                break;

              case STATE_TEST  :
              default:
                break;
              }
              FixBounds(&TBox);
              BoxComplete();
            }
            ButState &= ~(1 | 4);
            break;

          case MENUDOWN:
            ButState |= 2;
            break;

          case MENUUP:
            ButState &= ~2;
            break;

          default:
            break;

          }
          break;

        case IDCMP_MOUSEMOVE:
          if (ButState & 4)
          {
            DrawBox(&TBox);

            switch (CurState)
            {
            case STATE_NEWREGION:
              TBox.bo_Xe = im->MouseX;
              TBox.bo_Ye = im->MouseY;
              break;

            case STATE_MOVEREGION:
              TBox.bo_Xs += im->MouseX - TX;
              TBox.bo_Xe += im->MouseX - TX;
              TBox.bo_Ys += im->MouseY - TY;
              TBox.bo_Ye += im->MouseY - TY;
              break;

            case STATE_SIZEREGION:
              TBox.bo_Xe += im->MouseX - TX;
              TBox.bo_Ye += im->MouseY - TY;
              break;

            default:
              break;
            }
            TX = im->MouseX;
            TY = im->MouseY;
            DrawBox(&TBox);
            TitleState();
          }
          break;

        default:
          break;

        }
        im->MouseX = saveX;
        im->MouseY = saveY;
        GT_ReplyIMsg(im);
      }
    }
    if (EWin)
    {
      while (im = GT_GetIMsg(EWin->UserPort))
      {
        if (DDebug)
          puts("EWin");
        if (DDebug && im->Class != IDCMP_MOUSEMOVE)
          printf("CLASS %08lx CODE %d IA=%08lx\n",
                  im->Class, im->Code, im->IAddress);

        switch (im->Class)
        {
        case IDCMP_ACTIVEWINDOW:
          if (DDebug)
            puts("IDCMP_ACTIVEWINDOW");
          ClearMenuStrip(Win);
          SetMenuStrip(EWin, GMenu);
          break;

        case IDCMP_CLOSEWINDOW:
          if (DDebug)
            puts("IDCMP_CLOSEWINDOW");
          NotDone = QuitCheck();
          break;

        case IDCMP_REFRESHWINDOW:
          if (DDebug)
            puts("IDCMP_REFRESHWINDOW");
          GT_BeginRefresh(EWin);
          GT_EndRefresh(EWin, TRUE);
          drawborders();
          break;

        case IDCMP_MENUPICK:
          if (DDebug)
            puts("IDCMP_MENUPICK");
          HandleMenu(im);
          break;

        case IDCMP_GADGETDOWN:
        case IDCMP_GADGETUP:
          if (DDebug)
            puts("IDCMP_GADGETUP/DOWN");
          HandleEditGadget(im);
          break;

        case IDCMP_MOUSEMOVE:
          if (DDebug)
            puts("IDCMP_MOUSEMOVE");
          HandleSliders(im);
          break;

        default:
          if (DDebug)
            printf("default:\nCLASS %08lx CODE %d IA=%08lx\n",
                  im->Class, im->Code, im->IAddress);
          break;

        }
        GT_ReplyIMsg(im);
      }
    }
  }
  return (0);
}

/***********************  myexit(void)  ******************************/
void
myexit(void)
{
  if (Win)
  {
    ClearMenuStrip(Win);
    CloseWindow(Win);
  }
  CloseEditWindow();
  if (GList)
    FreeGadgets(GList);
  if (GMenu)
    FreeMenus(GMenu);
  if (VisInfo)
    FreeVisualInfo(VisInfo);
  if (Scr)
    UnlockPubScreen(NULL, Scr);
}

/***********************  BoxComplete(void) **************************/
void
BoxComplete(void)
{
  switch (CurState)
  {
  case STATE_NEWREGION:
    short  dx = TBox.bo_Xe - TBox.bo_Xs;
    short  dy = TBox.bo_Ye - TBox.bo_Ys;

    if ((dx < 5 && dy < 5) || dx < 3 || dy < 3)
      return;
                          /*  fall through */
    if (Buf_region_str[0] == 0)
    {
      if (DDebug)
        puts("no region name");
      return;
    }

  case STATE_COPYREGION:

    DrawBox(&TBox);

    TplRegion *rg = AllocTplRegion();

    UpdateTplRegion(rg);

    switch(rg->rg_Type)
    {
    case RGT_CHECKBOX:
      TBox.bo_Xe = TBox.bo_Xs + 25;
      TBox.bo_Ye = TBox.bo_Ys + 10;
      break;

    case RGT_MX:
      TBox.bo_Xe = TBox.bo_Xs + 16;
      TBox.bo_Ye = TBox.bo_Ys +  8;

    default:
      break;
    }

    rg->rg_Box = TBox;

    rg->rg_MinMax.bo_Xs = rg->rg_MinMax.bo_Xe = TBox.bo_Xe - TBox.bo_Xs;
    rg->rg_MinMax.bo_Ys = rg->rg_MinMax.bo_Ye = TBox.bo_Ye - TBox.bo_Ys;

    SetCurRegion(rg);
    UpdateEWinInfo(CurRegion);
    ReMakeEverything();

    break;

  case STATE_MOVEREGION:
    if (CurRegion)
    {
      CurRegion->rg_Box = TBox;
      ReMakeEverything();
    }
    break;

  case STATE_SIZEREGION:
    if (CurRegion)
    {
      if ((CurRegion->rg_Type != RGT_CHECKBOX) &&
          (CurRegion->rg_Type != RGT_MX))
        CurRegion->rg_Box = TBox;

      ReMakeEverything();
    }
  default:
    break;
  }
}

/***********************  HandleMenu(im)  ****************************/
void
HandleMenu(im)
  IMsg  *im;
{
  MenuItem *mi;

  if (mi = ItemAddress(GMenu, im->Code))
  {
    switch (GTMENUITEM_USERDATA(mi))
    {
    case MENU_PROJ_SAVEAS:
      strcpy(ProjSrcName, ProjName);
      if (GetSaveFile(ProjSrcName) >= 0)
      {
        SaveProject(ProjSrcName);
        issaved = TRUE;
      }
      break;

    case MENU_PROJ_SAVE:
      SaveProject(ProjName);
      issaved = TRUE;
      break;

    case MENU_PROJ_SAVEMAINNO:
    case MENU_PROJ_SAVEMAINYES:
      sprintf(ProjSrcName, "%s.c", ProjName);
      savemain = (short) GTMENUITEM_USERDATA(mi) - MENU_PROJ_SAVEMAINNO;
      SaveProjectAsSrc(ProjSrcName);
      break;

    case MENU_PROJ_SAVEASMAINNO:
    case MENU_PROJ_SAVEASMAINYES:
      sprintf(ProjSrcName, "%s.c", ProjName);
      savemain = (short) GTMENUITEM_USERDATA(mi) - MENU_PROJ_SAVEASMAINNO;
      if (GetSaveFile(ProjSrcName))
        SaveProjectAsSrc(ProjSrcName);
      break;

    case MENU_EDIT_SORT:
      SortRegions();
      GadDisabled = 0;
      ReMakeEverything();
      break;

    case MENU_EDIT_LOCK:
      if (CurRegion)
      {
        Title("Choose Link Destination String");
        CurState = STATE_LINKREGION;
        DisableGadgets();
      }
      break;

    case MENU_EDIT_UNLOCK:
      if (CurRegion)
      {
        Title("Choose ListView to Unlink");
        CurState = STATE_UNLINKREGION;
        DisableGadgets();
      }
      break;

    case MENU_PROJ_LOAD:
      if (!issaved)
        if (!(do_request( "Load new without saving old ???", "Yes|Cancel", 0)))
          break;

      if (GetSaveFile(ProjName) >= 0)
      {
        TplRegion *rg;

        while (rg = GetHead(&RegList))
          DeleteTplRegion(rg);
        LoadProject(ProjName);
        ReMakeEverything();
        init_test();
      }
      break;

    case MENU_PROJ_MERGE:
      if (GetSaveFile(ProjSrcName) >= 0)
      {
        LoadProject(ProjSrcName);
        ReMakeEverything();
        init_test();
      }
      break;

    case MENU_PROJ_QUIT:
      NotDone = QuitCheck();
      break;

    case MENU_SNAP +  1:
    case MENU_SNAP +  2:
    case MENU_SNAP +  4:
    case MENU_SNAP +  6:
    case MENU_SNAP +  8:
    case MENU_SNAP + 10:
    case MENU_SNAP + 12:
    case MENU_SNAP + 14:
    case MENU_SNAP + 16:
    case MENU_SNAP + 18:
    case MENU_SNAP + 20:
      CoorSnap = (short) GTMENUITEM_USERDATA(mi) - MENU_SNAP;
      break;

    case MENU_GADGET +  0:
    case MENU_GADGET +  1:
    case MENU_GADGET +  2:
    case MENU_GADGET +  3:
    case MENU_GADGET +  4:
    case MENU_GADGET +  5:
    case MENU_GADGET +  6:
    case MENU_GADGET +  7:
    case MENU_GADGET +  8:
    case MENU_GADGET +  9:
    case MENU_GADGET + 10:
    case MENU_GADGET + 11:
    case MENU_GADGET + 12:
    case MENU_GADGET + 13:
      NewType = (short) GTMENUITEM_USERDATA(mi) - MENU_GADGET;
      GT_SetGadgetAttrs(Gad_gadgets_lv, EWin, NULL,
                        GTLV_Selected,  NewType,
                        TAG_END);
    if (CurRegion)
      DisableEGads(CurRegion);
    else
      DisableEGads((void *)0L);

    default:
      break;
    }
  }
}

/***********************  Title(tit)  ********************************/
void
Title(tit)
  char  *tit;
{
  if (Win)
  {
    SetWindowTitles(Win, NULL, NULL);
    sprintf(TitleBuf, "%s  %s  %s",
            ProjName,
            (CurRegion) ? CurRegion->rg_Node.ln_Name : "<none>",
            tit);
    SetWindowTitles(Win, TitleBuf, NULL);
  }
}

/***********************  TitleState(void)  **************************/
void
TitleState(void)
{
  switch (CurState)
  {
  case STATE_NEWREGION:
  case STATE_SIZEREGION:
    TitleXY(TBox.bo_Xe - TBox.bo_Xs, TBox.bo_Ye - TBox.bo_Ys);
    break;

  case STATE_MOVEREGION:
    TitleXY(TBox.bo_Xs, TBox.bo_Ys);

    default:
    break;
  }
}

/***********************  TitleXY(x, y)  ********************************/
void
TitleXY(x, y)
  short  x, y;
{
  if (x < 0)
    x = -x;
  if (y < 0)
    y = -y;
  sprintf(TmpBuf, "X:%d Y:%d", x, y);
  Title(TmpBuf);
}

/***********************  SetCurRegion(rg)  **************************/
TplRegion *
SetCurRegion(rg)
  TplRegion *rg;
{
  CurRegion = rg;
  Title("selected");
  return (rg);
}

/***********************  do_request() ************************/

struct EasyStruct textreq =
{
  sizeof(struct EasyStruct),            /* ULONG es_StructSize      */
  0L,                                   /* ULONG es_Flags           */
  " TplEdit ",                          /* UBYTE *es_Title          */
  NULL,                                 /* UBYTE *es_TextFormat     */
  NULL                                  /* UBYTE *es_GadgetFormat   */
};

short
do_request(char *text, char *gads, UWORD *args)
{
  textreq.es_TextFormat   = text;
  textreq.es_GadgetFormat = gads;

  return (EasyRequestArgs(Win, &textreq, NULL, &args));
}

/***********************  init_test() ********************************/
void
init_test()
{
  CurState = STATE_TEST;
  GT_SetGadgetAttrs(Gad_actions_mx, EWin, NULL,
                    GTMX_Active, ACT_TEST,
                    TAG_END);
  EnableGadgets();
}

/***********************  QuitCheck();  ******************************/
short
QuitCheck()
{
  if (!issaved)
    return (!(do_request( "Quit without saving ???", "Yes|Cancel", 0)));

  return (!(do_request( "Really quit now ???", "Yes|Cancel", 0)));
}
