#include <intuition/intuisup.h>
#include "patch.h"

#ifndef DEBUG
#include <proto/all.h>
#endif

extern struct ListSupport  *DList;
extern struct HiddenWindow HList;
extern struct MsgPort      *IDCMPReplyPort;


VOID
HideWindow(window)
register struct   Window   *window;
{
   register struct   Screen      *screen = window->WScreen;
   register struct   Layer       *layer;
   register struct   Layer_Info  *linfo;

   Forbid();
   layer = window->RPort->Layer;
   linfo = layer->LayerInfo;

   SizeLayer(linfo, layer, 1-window->Width, 1-window->Height);
   MoveLayer(linfo, layer,
             screen->Width  - window->LeftEdge - 1,
             screen->Height - window->TopEdge  - 1);
   ShowTitle(screen, TRUE);
   MakeScreen(screen);
   Permit();
}

VOID
RevealWindow(window)
register struct   Window   *window;
{
   register struct   Screen       *screen = window->WScreen;
   register struct   Layer        *layer;
   register struct   Layer_Info   *linfo;
   register struct   IntuiMessage *msg = New(struct IntuiMessage, 1);

   Forbid();
   layer = window->RPort->Layer;
   linfo = layer->LayerInfo;

   MoveLayer(linfo, layer,
             window->LeftEdge - screen->Width  + 1,
             window->TopEdge  - screen->Height + 1);
   SizeLayer(linfo, layer, window->Width-1, window->Height-1);
   WindowToFront(window);
   Permit();

   /* Send the window a fake IDCMP message to tell it to refresh itself.   */
   /* Try both REFRESH and NEWSIZE, for most programs will refresh only    */
   /* on when they get the last.                                           */
   if (msg)
      {
      if (window->IDCMPFlags & REFRESHWINDOW) msg->Class = REFRESHWINDOW;
      else if (window->IDCMPFlags & NEWSIZE)  msg->Class = NEWSIZE;
      if (msg->Class)
         {
         msg->ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
         msg->ExecMessage.mn_ReplyPort    = IDCMPReplyPort;
         msg->IAddress = msg->IDCMPWindow = window;
         PutMsg(window->UserPort, msg);
         WaitPort(IDCMPReplyPort);
         while (GetMsg(IDCMPReplyPort));
         Delete(msg, 1);
         }
      }
}

VOID
FixDisplay(reset)
BOOL reset;
{
   /* Reset the display list   */
   DList->Header = (LONG)HList.Next;
   DList->Next   = (LONG)&HList.Next->Next;
   DList->Text   = (LONG)&HList.Next->Title;
   if (reset) ls_WarmStartFileIO(DList);
}

VOID Iconify(window, refresh)
register struct Window *window;
BOOL     refresh;
{
   register struct HiddenWindow  *hidden = New(struct HiddenWindow, 1);
   if (hidden)
      {
      /* Link it to our main list */
      hidden->Next = HList.Next;
      HList.Next   = hidden;

      /* Fill the structure data  */
      hidden->Window = window;
      hidden->Title  = window->Title;

      HideWindow(window);

      if (refresh) FixDisplay(TRUE);
      }
}

VOID UnIconify(hidden, refresh)
register struct HiddenWindow *hidden;
BOOL     refresh;
{
   struct   HiddenWindow  *h = HList.Next, *previous = NULL;

#ifdef DEBUG
printf("uniconifying [%s]\n", hidden->Title);
#endif

   RevealWindow(hidden->Window);

   while(h != hidden) { previous = h; h = h->Next; }

   if (previous) previous->Next = hidden->Next;
   else HList.Next = hidden->Next;
   CheckDelete(hidden, 1);

   if (refresh) FixDisplay(TRUE);
}
