/******************  window.c  *******************
 *                                               *
 *                                               *
 *                     hyper                     *
 *                                               *
 *                  © by Koessi                  *
 *                                               *
 *              Sunday, 23 Aug 1992              *
 *                                               *
 *                                               *
 *************************************************/


#include "defs.h"

Prototype int   OpenHlpWindow(void);
Prototype void  DoHlpWindow(void);
Prototype short ResizeWin(void);
Prototype void  ClrWindow(short);
Prototype void  LockWin(void);
Prototype void  UnLockWin(void);

Prototype struct NewWindow      nwin;
Prototype struct Window        *hlp_win;
Prototype struct MsgPort       *app_port;
Prototype struct AppWindow     *appwindow;
Prototype struct AppMenuItem   *appmenuitem;

Prototype __chip UWORD BusyPointerData[];

struct Window        *hlp_win       = NULL;
struct MsgPort       *app_port      = NULL;
struct AppWindow     *appwindow     = NULL;
struct AppMenuItem   *appmenuitem   = NULL;


__chip UWORD BusyPointerData[] =
{
  0x0000,0x0000,
  0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
  0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
  0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
  0x0000,0x0000,
};

struct NewWindow nwin =
{
    0,   0,             /*  WORD  LeftEdge,  TopEdge;   */
  640, 200,             /*  WORD  Width,     Height;    */
    0,   1,             /*  UBYTE DetailPen, BlockPen;  */
  SCROLLERIDCMP       |
  BUTTONIDCMP         |
  IDCMP_MOUSEBUTTONS  |
  IDCMP_CLOSEWINDOW   |
  IDCMP_REFRESHWINDOW |
  IDCMP_CHANGEWINDOW  |
  IDCMP_RAWKEY,         /*  ULONG IDCMPFlags IntuiMessage ; */
  WFLG_DRAGBAR        |
  WFLG_DEPTHGADGET    |
  WFLG_CLOSEGADGET    |
  WFLG_SMART_REFRESH  |
  WFLG_SIZEGADGET     |
  WFLG_SIZEBBOTTOM    |
  WFLG_ACTIVATE,        /*  ULONG  Flags;                 */
  NULL,                 /*  struct Gadget   *FirstGadget; */
  NULL,                 /*  struct Image    *CheckMark;   */
  title,                /*  UBYTE *Title;                 */
  NULL,                 /*  struct Screen   *Screen;      */
  NULL,                 /*  struct BitMap   *BitMap;      */
  640, 200,             /*  WORD   MinWidth, MinHeight;   */
   -1,  -1,             /*  UWORD  MaxWidth, MaxHeight;   */
  WBENCHSCREEN          /*  UWORD  Type;                  */
};


struct Requester fakereq =
{
  NULL,               /*  struct Requester *OlderRequest; */
  -1, -1,             /*  WORD LeftEdge, TopEdge; */
   0,  0,             /*  WORD Width, Height; */
   0,  0,             /*  WORD RelLeft, RelTop; */
  NULL,               /*  struct Gadget *ReqGadget; */
  NULL,               /*  struct Border *ReqBorder; */
  NULL,               /*  struct IntuiText *ReqText;  */
  SIMPLEREQ    |
  NOREQBACKFILL,      /*  UWORD Flags;  */
  0,                  /*  UBYTE BackFill; */
  NULL,               /*  struct Layer *ReqLayer; */
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,    /*  UBYTE ReqPad1[32];  */
  NULL,               /*  struct BitMap *ImageBMap; */
  NULL,               /*  struct Window *RWindow; */
  NULL,               /*  struct Image  *ReqImage;  */
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0     /*  UBYTE ReqPad2[32];  */
};

void
LockWin(void)
{
  struct Window *hwin = hlp_win;
  SetPointer(hwin, BusyPointerData, 16, 16, -6, 0);
  Request(&fakereq, hwin);
}

void
UnLockWin(void)
{
  struct Window *hwin = hlp_win;
  EndRequest(&fakereq, hwin);
  ClearPointer(hwin);
  ActivateWindow(hwin);
}



/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: OpenHlpWindow                    *
 *                                               *
 *                                               *
 *    INPUT:     void                            *
 *                                               *
 *    OUTPUT:   int                              *
 *                                               *
 *    NOTE:                                      *
 *                                               *
 *************************************************/


int
OpenHlpWindow( void )
{
  struct Window *w = OpenWindow(&nwin);
  if (hlp_win = w)
  {
    LockWin();
    if (app_port)
    {
      if (appmenuitem)
      {
        RemoveAppMenuItem(appmenuitem);
        appmenuitem = NULL;
      }
    }
    else
      app_port = CreateMsgPort();

    if (app_port)
    {
      if (appwindow = (struct AppWindow *)AddAppWindow(1, 0L, w, app_port, NULL))
      {
        if (InitGads(FALSE))
        {
          SetWindowTitles(w, database, title);
          UnLockWin();
          return(TRUE);
        }
      }
    }
  }

  DoRequest(str_erroropenwin, str_resume, NULL);
  cleanup();
  exit(103);
}

/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: ResizeWin                        *
 *                                               *
 *                                               *
 *    INPUT:    void                             *
 *                                               *
 *    OUTPUT:   short                            *
 *                                               *
 *    NOTE:                                      *
 *                                               *
 *************************************************/


short
ResizeWin(void)
{
  RemoveGList(hlp_win, hlp_glist, -1);
  FreeGadgets(hlp_glist);
  hlp_glist = NULL;

  short ret;
  if (ret = InitGads(TRUE))
    DrawText(hlp_node);

  return(ret);
}

/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: DoHlpWindow                      *
 *                                               *
 *                                               *
 *    INPUT:    void                             *
 *                                               *
 *    OUTPUT:   void                             *
 *                                               *
 *    NOTE:                                      *
 *                                               *
 *************************************************/

int oldsecs = 0;
int oldmics = 0;

void
DoHlpWindow(void)
{
  short  keepopen = TRUE;
  MSGP  *uport    = hlp_win->UserPort;
  int    ibit     = 1 << uport->mp_SigBit;
  int    abit     = 1 << app_port->mp_SigBit;
  int    rbit     = 1 << rexx_port->mp_SigBit;
  int    sigbit;

  while (keepopen | backmode)
  {
    while (backmode)
    {
      sigbit = Wait(abit | rbit);
      if (sigbit == rbit)
      {
        if (GetRxMsg() != NEWNODE_OK)   /*  no doc/node/win ? */
          return;
      }
      else
      {
        AMSG *amsg;
        if (amsg = (AMSG *)GetMsg(app_port))
          ReplyMsg(amsg);
        backmode = FALSE;
        if (NewNode(nodename) != NEWNODE_OK)   /*  no doc/node/win ? */
          return;
      }
      oldsecs  = 0;
      oldmics  = 0;
      keepopen = TRUE;
      uport    = hlp_win->UserPort;
      ibit     = 1 << uport->mp_SigBit;
    }

    sigbit = Wait(ibit | abit | rbit);

    if (sigbit == ibit)
    {
      IMSG  *imsg;
      if (imsg = (IMSG *)GT_GetIMsg(uport))
      {
        long  class = imsg->Class;
        short code  = imsg->Code;
        short id    = ((struct Gadget *)imsg->IAddress)->GadgetID;

        switch (class)
        {
        case IDCMP_MOUSEBUTTONS:
          if (code == SELECTDOWN)
          {
            if (DoubleClick(oldsecs, oldmics, imsg->Seconds, imsg->Micros))
            {
              short mx = imsg->MouseX;
              short my = imsg->MouseY;
              GT_ReplyIMsg(imsg);
              DoLinkGad(mx, my);
            }
            else
            {
              oldsecs = imsg->Seconds;
              oldmics = imsg->Micros;
              GT_ReplyIMsg(imsg);
            }
          }
          break;

        case IDCMP_CHANGEWINDOW:
          GT_ReplyIMsg(imsg);
          struct Window    *w  = hlp_win;
          struct NewWindow *nw = &nwin;
          short  hw = w->Width;
          short  hh = w->Height;
          if (!(nw->Width == hw && nw->Height == hh))
          {
            nw->Width  = hw;
            nw->Height = hh;
            keepopen   = ResizeWin();
          }
          while (imsg = (MSG *)GetMsg(uport))
            ReplyMsg(imsg);
          break;

        case IDCMP_REFRESHWINDOW:
          GT_BeginRefresh(hlp_win);
          GT_EndRefresh(hlp_win, TRUE);
          GT_ReplyIMsg(imsg);
          break;

        case IDCMP_CLOSEWINDOW:
          code = GD_Gad_return;

        case IDCMP_RAWKEY:
          switch (code)
          {
          case 0x001F:  /*  kp3(PgDn) */
          case 0x002F:  /*  kp6(right)*/
          case 0x0040:  /*  spacebar  */
          case 0x004E:  /*  right     */
            id = GD_Gad_nextpage;
            break;

          case 0x002D:  /*  kp4(left) */
          case 0x003F:  /*  kp9(PgUp) */
          case 0x0041:  /*  backspace */
          case 0x004F:  /*  left      */
            id = GD_Gad_prevpage;
            break;

          case 0x0043:  /*  enter     */
          case 0x0044:  /*  return    */
          case 0x0045:  /*  escape    */
            id = GD_Gad_return;
            break;

          case 0x003E:  /*  kp8(up)   */
          case 0x004C:  /*  up        */
            id = GD_cursor;
            short pos;
            code = (pos = scrollpos) ? pos - 1 : 0;
            break;

          case 0x001E:  /*  kp2(down) */
          case 0x004D:  /*  down      */
            id = GD_cursor;
            short pos;
            code = ((pos = scrollpos) < (scrollmax - scrollvis)) ?
                    (pos + 1) : pos;
            break;

          case 0x003D:  /*  kp7(home)   */
          case 0x005F:  /*  help        */
            id = GD_Gad_firstpage;
            break;

          default:
            id = code;
            break;
          }

        case IDCMP_GADGETDOWN:
        case IDCMP_MOUSEMOVE:
        case IDCMP_GADGETUP:
          GT_ReplyIMsg(imsg);
          if (keepopen = HandleHlpGads(id, code))
          {
            while (imsg = (MSG *)GetMsg(uport))
              ReplyMsg(imsg);
          }
          break;

        default:
          GT_ReplyIMsg(imsg);
          break;
        }
      }
    }
    else
    {
      if (sigbit == abit)
      {
        AMSG *amsg;
        if (amsg = (AMSG *)GetMsg(app_port))
        {
          char *doc = charbuffer;
          if (NameFromLock(amsg->am_ArgList->wa_Lock, doc, 64))
          {
            AddPart(doc, amsg->am_ArgList->wa_Name, 64);
            AddPart(doc, str_main,                  64);
            NewNode(doc);
          }
          ReplyMsg(amsg);
        }
      }
      else
      {
       if (sigbit == rbit)
         keepopen = (GetRxMsg() < NEWNODE_WINNOTOPENED);   /*  no win ? */
      }
    }
  }
}

/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: ClrWindow                        *
 *                                               *
 *                                               *
 *    INPUT:    short                            *
 *                                               *
 *    OUTPUT:   void                             *
 *                                               *
 *    NOTE:                                      *
 *                                               *
 *************************************************/


void
ClrWindow(short all)
{
  register void *p1;
  if (p1 = app_port)
  {
    register void *p2;
    if (p2 = appwindow)
      RemoveAppWindow(p2);

    while (p2 = GetMsg(p1))
      ReplyMsg(p2);
    if (all)
    {
      if (p2 = appmenuitem)
        RemoveAppMenuItem(p2);

      DeleteMsgPort(p1);
    }
  }

  register struct Window *w;
  if (w = hlp_win)
  {
    p1 = &nwin;
    ((struct NewWindow *)p1)->LeftEdge = w->LeftEdge;
    ((struct NewWindow *)p1)->TopEdge  = w->TopEdge;
    ((struct NewWindow *)p1)->Width    = w->Width;
    ((struct NewWindow *)p1)->Height   = w->Height;

    while (p1 = GetMsg(w->UserPort))
      ReplyMsg(p1);

    if (p1 = hlp_glist)
    {
      RemoveGList(w, p1, -1);

      if (all)
      {
        FreeGadgets(p1);
        if (p1 = VisInfo)
        {
          FreeVisualInfo(p1);
          VisInfo = 0;
        }
        if (Scr)
          UnlockPubScreen(NULL, Scr);
      }
    }
    CloseWindow(w);
    hlp_win = NULL;
  }
  ClrMap(&hlp_map);
}
