/*****************************************************************************
 * 
 * name             : partial.c
 * description      : close & reopen window on workbench close
 * version          : 2.21
 *
 * created          : ?
 * last change      : 09-08-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)
 *
 *****************************************************************************
 */
#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 == 0x200) {
    /* close the window
     */
    if (prj->win) {  
      CloseWindow(prj->win) ;
      prj->win = NULL ;      // in case of error
      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 != 0x100) ;
   
  WBScreen = LockPubScreen("Workbench") ;
  prj->wb = WBScreen ;
  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_PubScreenName, "Workbench", 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
   */
  CloseWindow(prj->win) ;
  prj->wb = LockPubScreen("Workbench") ;
  
  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_PubScreenName, "Workbench", 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 * FindWindow(void) ;

  struct Window * win ;
  win = FindWindow() ;
  if (win)
    MoveWindowInFrontOf(prj->win,win) ;


}


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

  if ((wbscr = LockPubScreen("Workbench")) != 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 ;
      }
    }
    UnlockPubScreen(NULL, wbscr) ;
  }
  return(found) ;
}

