/*****************************************************************************
 * 
 * Nom				: utils.c
 * desc				: utilitaires projet
 *
 * version			: $VER: utils.c 1.2 (08.02.98)
 *
 *****************************************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <exec/exec.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <dos/datetime.h>
#include <dos/dosextens.h>
#include <workbench/workbench.h>
#include <libraries/notifyintuition.h>

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/icon.h>
#include "utils.h"
#include "timer.h"
#include "tracewin.h"
#include "notify.h"
#include "partial.h"

struct Library * NotifyIntuitionBase ;

idWin * init(WBArg * appName) {
  struct DiskObject * dobj ;
  char ** toolarray ;
  struct Process * mytask = NULL ;
  struct Screen  * WBScreen = NULL ;
  idWin * prjWin = NULL ;
  LONG  args[10] ;
  
  if ((prjWin = AllocVec(sizeof(idWin), MEMF_PUBLIC|MEMF_CLEAR)) != NULL) {
    if ((prjWin->date = AllocVec(sizeof(struct DateStamp), MEMF_PUBLIC)) != NULL) {
      if ((prjWin->Notify = AllocVec(sizeof(struct IntNotifyRequest), MEMF_PUBLIC|MEMF_CLEAR)) != NULL) {
        if ((NotifyIntuitionBase = OpenLibrary(NOTIFYINTUITIONNAME, NOTIFYINTUITION_VMIN)) != NULL) {
          mytask = (struct Process *)FindTask(NULL) ;
        
          if (mytask->pr_CLI){
            //lance du cli
            // lecture des args
            if ((prjWin->args = ReadArgs("X=POSX/N/A,Y=POSY/N/A,W=WIDTH/N/A,H=HEIGHT/N/A,BACK/N/A", args, NULL)))
              setArgs(prjWin, (LONG*)args) ;
            else {
              prjWin->backWin.back   = 3 ;
              prjWin->backWin.posX   = 0 ;
              prjWin->backWin.posY   = 0 ;
              prjWin->backWin.width  = 100 ;
              prjWin->backWin.height = 100 ;
            }
          } else {
            //lance du wb
            // lecture des tooltypes
            CurrentDir(appName->wa_Lock) ;
            if ((dobj=GetDiskObject(appName->wa_Name)) != NULL) {
              toolarray = (char **)dobj->do_ToolTypes;
              prjWin->backWin.posX   = readToolValue(toolarray, "POSX", 0) ;
              prjWin->backWin.posY   = readToolValue(toolarray, "POSY", 0) ;
              prjWin->backWin.back   = readToolValue(toolarray, "BACK", 3) ;
              prjWin->backWin.width  = readToolValue(toolarray, "WIDTH", 50) ;
              prjWin->backWin.height = readToolValue(toolarray, "HEIGHT", 50) ;
              FreeDiskObject(dobj) ;
            }
          }
          WBScreen = LockPubScreen("Workbench") ;
          prjWin->win = OpenWindowTags(NULL, WA_Left,	prjWin->backWin.posX,
      												WA_Top,		prjWin->backWin.posY,
      												WA_Width,	prjWin->backWin.width,
      												WA_Height,	prjWin->backWin.height,
      												WA_IDCMP,	IDCMP_CHANGEWINDOW|IDCMP_REFRESHWINDOW,
      												WA_Flags,	WFLG_BORDERLESS,
      												WA_ScreenTitle, "BackClock", 
      												WA_NewLookMenus, TRUE,
      												WA_PubScreenName, "Workbench", TAG_DONE) ;
          WindowToBack(prjWin->win) ;
          UnlockPubScreen(NULL, WBScreen) ;
          initwin(prjWin) ;
          initTimer(prjWin) ;
          startNotify(prjWin) ;
      												
          // initialisation ...  (fenetre...)
        }else {
          FreeVec(prjWin->Notify) ;
          FreeVec(prjWin->date) ;
          FreeVec(prjWin) ;
          prjWin = NULL ;
        }
      }else {
        // error memoire notify
        FreeVec(prjWin->date) ;
        FreeVec(prjWin) ;
        prjWin = NULL ;
      }
    }else {
      // plus de memoire pour datestamp
      // liberation du projet
      FreeVec(prjWin) ;
      prjWin = NULL ;
    }
    
  } // prjWin = 0 si erreur memoire 
  return prjWin ;
}
void setArgs(idWin * prj, LONG * args) {
  prj->backWin.posX   = *(ULONG*)args[0] ;
  prj->backWin.posY   = *(ULONG*)args[1] ;
  prj->backWin.width  = *(ULONG*)args[2] ;
  prj->backWin.height = *(ULONG*)args[3] ;
  prj->backWin.back   = *(ULONG*)args[4] ;
}
void close(idWin * prj) {
  if (prj) {                              // struct prj existe (<>0) 
    endNotify(prj) ;
    if (prj->win) CloseWindow(prj->win) ; // ferme la fenetre 
    if (prj->date) FreeVec(prj->date) ;   // libere datestamp 
    if (prj->Notify) FreeVec(prj->Notify) ; // libere struct IntNotify
    closeTimer(prj) ;
    if (prj->args) FreeArgs(prj->args) ;  // libere les args
    FreeVec(prj) ;                        // libere la memoire 
    if (NotifyIntuitionBase) CloseLibrary(NotifyIntuitionBase) ;
  }
}
void getDate(idWin * prj) {
  // remplit la structure (projet) avec la date
  
  char * ptrTime = NULL ;
  struct DateTime * dt = NULL ;
  
  
  DateStamp(prj->date) ;

  ptrTime = AllocVec(LEN_DATSTRING, MEMF_PUBLIC|MEMF_CLEAR) ;
  
  if (ptrTime) {
    if ((dt = AllocVec(sizeof(struct DateTime), MEMF_PUBLIC)) != NULL) {
      CopyMem(prj->date, &(dt->dat_Stamp), sizeof(struct DateStamp)) ;
      dt->dat_Format = FORMAT_DOS ;
      dt->dat_Flags = NULL ;
      dt->dat_StrDay  = NULL ;
      dt->dat_StrDate = NULL ;
      dt->dat_StrTime = ptrTime ;
      DateToStr(dt) ;
      strcpy(prj->datestr, ptrTime) ;
      prj->oldH = prj->heu ;
      prj->oldM = prj->min ;
      prj->oldS = prj->sec ;
      DateToByte(ptrTime, prj) ;
      FreeVec(dt) ;
    }
  } 
  if (ptrTime) FreeVec(ptrTime) ;
}

void processwin(idWin* prj) {
  /* variables
   */
  ULONG signals = NULL,										 /* masque des signaux a attendre */
        mask,															/* masque des signaux recus */
        sigtimer ;
        
  BOOL  stop    = FALSE ;												  		 /* vrai si ctrl c */
  struct IntuiMessage * msg = NULL ;	                 /* ptr sur message intuition */
  struct MsgPort      * stopPort = NULL ;
  struct Message      * stopmsg = NULL ;
  
  stopPort = CreateMsgPort() ;
  stopPort->mp_Node.ln_Name = AllocVec(10, MEMF_PUBLIC) ;
  strcpy(stopPort->mp_Node.ln_Name, "backclock") ;
  AddPort(stopPort) ;
  
  sigtimer =  (1<<(prj->treq->tr_node.io_Message.mn_ReplyPort->mp_SigBit)) ; 
  /* signaux d'attentes
   */
  signals = SIGBREAKF_CTRL_C | 
            (1<<(prj->notifyPort->mp_SigBit)) | 
            (1<<(prj->win->UserPort->mp_SigBit)) | sigtimer|
            (1<<(stopPort->mp_SigBit)) ;
  
  runtimer(prj) ;
  getDate(prj) ;
  retracer(prj) ;
  while(!stop) {
    mask = Wait(signals) ;
    if (mask & SIGBREAKF_CTRL_C) {
      /* recu le signal CTRL C
       */
      stop=TRUE;
    }
    if (mask & (1<<(stopPort->mp_SigBit))) {
      // recu stop
      stopmsg = GetMsg(stopPort) ;
      if (stopmsg) ReplyMsg(stopmsg) ;
      stop=TRUE
    }
    if (mask & (1<<(prj->notifyPort->mp_SigBit))) {
      // attention fermeture du WB
      partialClose(prj) ;
      partialOpen(prj) ;
    }
    if (mask & 1<<(prj->win->UserPort->mp_SigBit)) {
      /* recu message d'intuition
       */
      while((msg = GT_GetIMsg(prj->win->UserPort)) != NULL) {
        if ((msg->Class) == IDCMP_REFRESHWINDOW) {
          /* rafraichissement (prob ?)
           */
          initwin(prj) ;
          getDate(prj) ;
          effacer(prj) ;
          retracer(prj) ;
        }
        if ((msg->Class) == IDCMP_CHANGEWINDOW) 
          WindowToBack(prj->win) ;
        /* retourne le message
         */
        if (msg) ReplyMsg((struct Message *)msg) ; 
      }
    }
    if (CheckIO((struct IORequest*)prj->treq)) {
      WaitIO((struct IORequest*)prj->treq) ;
      AbortIO((struct IORequest*)prj->treq) ;
      WaitIO((struct IORequest*)prj->treq) ;
      runtimer(prj) ;
      getDate(prj) ;
      effacer(prj) ;
      retracer(prj) ;
      WindowToBack(prj->win) ;
    }  
 
  }
  AbortIO((struct IORequest*)prj->treq) ;
  WaitIO((struct IORequest*)prj->treq) ;
  RemPort(stopPort) ;
  FreeVec(stopPort->mp_Node.ln_Name) ;
  DeleteMsgPort(stopPort) ;
     
}

int readToolValue(char ** toolarr, char * argtype, int argdef) {
  int retVal = NULL ;
  char * s ;

  if ((s = (char *) FindToolType((UBYTE **)toolarr, argtype)) != NULL) {
    retVal = atoi(s) ;
  } else retVal = argdef ;
  return retVal ;
}

