/*****************************************************************************
 * 
 * name             : partial.c
 * description      : close & reopen window on workbench close
 * version          : 2.22
 *
 * created          : ?
 * last change      : 02-09-99
 *
 * version 2.1: bugfixed (sizing and dragging gadget)
 * version 2.1ß2 : now open the window as backdrop (working)
 * version 2.1ß3 : opens in front of wb or do
 * version 2.2   : enforcer hits removed & better in-front-of-WBDO-screen
 * version 2.21  : added a timeout when received a msf from notify
 *                 (avoid deadlocks)
 * version 2.22  : open on the specified screen now
 *
 *****************************************************************************
 */
#include <string.h>
#include "utils.h"
#include "partial.h"
#include "tracewin.h"
#include "obp.h"
#include <proto/intuition.h>
#include <proto/exec.h>
#include <intuition/intuition.h>

extern struct Gadget szgdg,
                     tagdg ;

BOOL partialClose(idWin * prj) {
  /* 
   * handle notify_intuition msg
   * close the window 
   * 
   */
  BOOL ret = FALSE ;
  struct Message * msg ;
  struct IntNotifyMessage * imsg ;
  
  msg = GetMsg(prj->notifyPort) ;
  imsg = (struct IntNotifyMessage*)msg ;

  if (imsg->inm_Code == INRCODE_BEFORE_CLOSEWORKBENCH) {
    /* close the window
     */
    if (prj->win) {  
      int i ;
      for(i=0; i<NUM_COLORS; i++)
        /* first free all pens
         */
        freePen(prj, prj->backWin.cmap[i].reg) ;

      for(i=0; i<NUM_LED_COLORS; i++)
         freePen(prj, prj->backWin.lcmap[i].reg) ;

      CloseWindow(prj->win) ;
      prj->win = NULL ;      // in case of error
      prj->wb  = NULL ;
      ret = TRUE ;
    }
  }
  if (msg) ReplyMsg(msg) ;
  
  return(ret) ;
}


void partialOpen(idWin * prj) {
  /* reopen the window
   */
  struct Screen * WBScreen ;
  struct IntNotifyMessage * imsg ;
  UWORD code ;
  ULONG mask ;
  BOOL stopWait ;

  /* something doesn't work with notify
   */
  code = NULL ;
  WaitIO((struct IORequest*)prj->treq) ;
  AbortIO((struct IORequest*)prj->treq) ;
  WaitIO((struct IORequest*)prj->treq) ;
  runtimer(prj, 10) ;              /* set the timeout for 10 seconds */
  do{
    /* get msg from notifyintuition
     */
    Wait((1<<(prj->notifyPort->mp_SigBit)) |
         (1<<(prj->treq->tr_node.io_Message.mn_ReplyPort->mp_SigBit))) ;
    if ((imsg = (struct IntNotifyMessage*)GetMsg(prj->notifyPort)) != NULL) {
      /* received a msg
       */
      code = imsg->inm_Code ;
      ReplyMsg((struct Message *)imsg) ;
      stopWait = TRUE ;
    }
    if (CheckIO((struct IORequest*)prj->treq)) {
      /* timeout exceede, reopen the window now
       */
      WaitIO((struct IORequest*)prj->treq) ;
      AbortIO((struct IORequest*)prj->treq) ;
      WaitIO((struct IORequest*)prj->treq) ;
      code = 0x100 ;
    }
  }while(code != INRCODE_AFTER_OPENWORKBENCH) ;
   
  if (!(WBScreen = LockPubScreen(prj->backWin.PubScreen)))
    WBScreen = LockPubScreen(NULL) ;
  prj->wb = WBScreen ;
  initColors(prj) ;
  free_bitmap(prj) ;
  init_bitmap(prj) ;
  prj->win = OpenWindowTags(NULL, WA_Left,  prj->backWin.posX,
                        WA_Top,          prj->backWin.posY,
                        WA_Width,        prj->backWin.width,
                        WA_Height,       prj->backWin.height,
                        WA_IDCMP,        IDCMP,
                        WA_MinWidth,     50,
                        WA_MinHeight,    50,
                        WA_MaxHeight,    MAXH,
                        WA_MaxWidth,     MAXH,
                        WA_Flags,        WFLG,
                        WA_ScreenTitle,  TXT_SCRTITLE,
                        WA_NewLookMenus, TRUE,
                        WA_PubScreen,    WBScreen,
                        TAG_DONE) ;
  RemoveGList(prj->win, &szgdg, 2) ;
  /* add the gadgets
   */                      
  szgdg.Width  = prj->win->Width ;
  szgdg.NextGadget = &tagdg ;
  tagdg.LeftEdge  = prj->win->Width - 10 ;
  tagdg.TopEdge   = prj->win->Height - 10 ;
  
  AddGList(prj->win, &szgdg, 0, 2, NULL) ;
   
  RefreshGList(&szgdg, prj->win, NULL, -1) ;                              
  UnlockPubScreen(NULL, WBScreen) ;
  setColors(prj) ;

  GoAhead(prj) ;


}



void setWindow(idWin * prj) {
  /* the window did moved
   */
  int i ;
  for(i=0; i<NUM_COLORS; i++)
    /* first free all pens
     */
    freePen(prj, prj->backWin.cmap[i].reg) ;

  for(i=0; i<NUM_LED_COLORS; i++)
    freePen(prj, prj->backWin.lcmap[i].reg) ;

  CloseWindow(prj->win) ;
  if (!(prj->wb = LockPubScreen(prj->backWin.PubScreen)))
    prj->wb = LockPubScreen(NULL) ;
  
  initColors(prj) ;

  free_bitmap(prj) ;
  init_bitmap(prj) ;
  
  prj->win = OpenWindowTags(NULL, WA_Left,  prj->backWin.posX,
                        WA_Top,          prj->backWin.posY,
                        WA_Width,        prj->backWin.width,
                        WA_Height,       prj->backWin.height,
                        WA_IDCMP,        IDCMP,
                        WA_MinWidth,     50,
                        WA_MinHeight,    50,
                        WA_MaxHeight,    MAXH,
                        WA_MaxWidth,     MAXH,
                        WA_Flags,        WFLG,
                        WA_ScreenTitle,  TXT_SCRTITLE,
                        WA_NewLookMenus, TRUE,
                        WA_PubScreen,    prj->wb, TAG_DONE) ;

  /*RemoveGList(prj->win, &szgdg, 2) ;
   */
  szgdg.Width  = prj->win->Width ;
  szgdg.NextGadget = &tagdg ;
  tagdg.LeftEdge  = prj->win->Width /2 ;
  tagdg.TopEdge   = prj->win->Height - 20 ;
  tagdg.Width     = prj->win->Width /2 ;
  
/*  AddGList(prj->win, &szgdg, 0, 2, NULL) ;
   
  RefreshGList(&szgdg, prj->win, NULL, -1) ;
  */
  UnlockPubScreen(NULL, prj->wb) ; 
  reinit_win(prj) ;
}

void GoAhead(idWin * prj) {
  /* go in front of wb or do main window
   */
  struct Window * win ;
  win = FindWindow(prj->wb) ;
  if (win)
    MoveWindowInFrontOf(prj->win,win) ;


}


struct Window * FindWindow(struct Screen * wbscr) {
  /* find the WB or DO main window
   */
  struct Window * wbwin ;
  struct Window * found = NULL ;
  ULONG mx, my ;

  if (wbscr != NULL) {
    /* workbench found !
     */
    wbwin = wbscr->FirstWindow ;
    while(wbwin) {
      /* search the main window (named "Directory Opus" || "Workbench"
       */
      if(wbwin->Title) {
        /* avoid enforcer hits
         */
        if (strcmp(wbwin->Title, "Directory Opus") == 0)
          found = wbwin ;
        if (strcmp(wbwin->Title, "Workbench") == 0)
          found = wbwin ;
      }
      wbwin = wbwin->NextWindow ;
    }
    if (!found) {
      /* still not found
       * maybe a backdrop widow
       */
      wbwin = wbscr->FirstWindow ;
      mx = wbwin -> Width ;
      my = wbwin -> Height ;
      while(wbwin) {
        /* search the main window (larger & backdrop)
         */

        if (wbwin->Flags & WFLG_BACKDROP) {
          /* a backdrop window
           */
          if ((wbwin->Width > mx) && (wbwin->Height > my))
            /* big window
             */
            found = wbwin ;
        }
        wbwin = wbwin->NextWindow ;
      }
    }
  }
  return(found) ;
}

