#include <clib/exec_protos.h>
#include <exec/memory.h>
#include <clib/dos_protos.h>
#include <signal.h>
#include <clib/locale_protos.h>
#include <clib/icon_protos.h>
#include <workbench/startup.h>

#include "include/Messiecommon.h"
#include "include/Messie.h"

int __nocommandline=1; // libnix special

struct Library *LocaleBase=NULL;
struct DosLibrary *DOSBase=NULL;
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase=NULL;
struct Catalog *catalog=NULL;
struct RxsLib *RexxSysBase=NULL;
struct Library *IconBase=NULL;

extern struct WBStartup *_WBenchMsg;

char thisis[]="Messie V1.01 by Patrick Kursawe 1996-97\0$VER: Messie 1.01 (26.01.97)";

static STRPTR Strings[]= {  // static for internal linkage
 "NULL",
 "problem: couldn't get date string.\n",
 "problem: could neither get lock on directory nor create it.\n",
 "Data%d",
 "Comment%d",
 "Trouble while building filename.\n",
 "#PROGNAME: %s\n#LOCATION: %s\n#DATE: %s\n#TIME: %s\n",
 "Cannot write to file.\n",
 "Can't open misc.resource.\n",
 "Can't allocate IORequest.\n",
 "Could not open window.\n",
 "Setting interval to %ld seconds",
 "Can't allocate a MessagePort.\n",
 "Can't open timer.device.\n",
 "Already active.\n",
 "Subtask seems to have problems.\n",
 "Could not create subtask.\n",
 "Message buffer overflow. Data lost.\n",
 "Channel stopped.",
 "Channel started.",
 "Space for comments, 80 chars.",
 "Channel %ld",
 "Start",
 "Stop",
 "s",
 "Trouble allocating Gadgets.\n",
 "Can't allocate handshake bits. Used by "
};

void PrintString(char *text) {
 PutStr(text);
}

void PrintString(StringID num) {
 PrintString(GetString(num));
}

STRPTR GetString(StringID num) {
 if(LocaleBase != 0) return(GetCatalogStr(catalog,num,Strings[(int)num]));
 return(Strings[num]);
}

int main(void) {

 int ret=20;
 signal(SIGINT,SIG_IGN); // schaltet das GCC/libnix-eigene CTRL_C handling ab
 UBYTE dosname[]="dos.library";

 if((DOSBase=(struct DosLibrary*)OpenLibrary(dosname,37L)) != 0) {
  struct Process *pr=(struct Process *)FindTask(NULL);
  BPTR win=NULL;
  BPTR lock=NULL;
  BPTR workdirlock=NULL;
  BPTR progdirlock=NULL;
  char prognamebuf[31];
  char *windescr=NULL;
  char *progname=NULL;
        
  IconBase=OpenLibrary((UBYTE *)"icon.library",37L);

  struct DiskObject *dobj=NULL;
      

  if(_WBenchMsg) {                                      
   windescr=_WBenchMsg->sm_ToolWindow;
   lock=CurrentDir(_WBenchMsg->sm_ArgList[0].wa_Lock);
   progname=(char *)_WBenchMsg->sm_ArgList[0].wa_Name;
  } else if(GetProgramName(prognamebuf,31)) 
  progname=prognamebuf;
  
    
  if(progname && IconBase) dobj=GetDiskObject((UBYTE *)progname);

  char *location=NULL;

  if(dobj) {
   if(dobj->do_ToolTypes) {
    STRPTR value=NULL;  
    value=(char *)FindToolType((UBYTE **)dobj->do_ToolTypes,(UBYTE *)"WINDOW");
    windescr=value;
    value=(char *)FindToolType((UBYTE **)dobj->do_ToolTypes,(UBYTE *)"LOCATION");
    if(value!=0) {
     location=(char *)MEMALLOC(strlen(value)+1);
     if(location) strcpy(location,value);
    }
    value=(char *)FindToolType((UBYTE **)dobj->do_ToolTypes,(UBYTE *)"WORKDIR");
    if(value!=0) {
     workdirlock=Lock(value,ACCESS_READ);
     if(workdirlock) progdirlock=CurrentDir(workdirlock);
    }
   }
  }

  LONG rdargarr[]={NULL,NULL};
     
  struct RDArgs *Args=ReadArgs((STRPTR)"WORKDIR,LOCATION",rdargarr,NULL);
     
  if(rdargarr[0]) {
   if(workdirlock) {            
    CurrentDir(progdirlock);
    UnLock(workdirlock);
   }
   workdirlock=Lock((char *)rdargarr[0],ACCESS_READ);
   if(workdirlock) progdirlock=CurrentDir(workdirlock);
  }
  if(rdargarr[1]) {
   if(location) FREEMEM(location);
   location=(char *)MEMALLOC(strlen((char *)rdargarr[1])+1);
   if(location) strcpy(location,(char *)rdargarr[1]);
  }
     
  if(!(windescr)) windescr="CON:0/10/400/50/Messie-Error/auto/close/wait";
 
  if(pr->pr_COS==NULL) {
   win=Open(windescr,MODE_READWRITE);
   pr->pr_COS=win;
   if(pr->pr_CIS==NULL) pr->pr_CIS=win;
  }
      
  FreeArgs(Args);
  if(dobj) FreeDiskObject(dobj); 

  if((GfxBase=(struct GfxBase*)OpenLibrary((UBYTE*)"graphics.library",37L)) !=0) {
   if((GadToolsBase=OpenLibrary((UBYTE*)"gadtools.library",37L)) !=0) {
    if((IntuitionBase=(struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library",37L)) !=0) {
     RexxSysBase=(struct RxsLib *)OpenLibrary((UBYTE *)"rexxsyslib.library",36L);
     LocaleBase=OpenLibrary((UBYTE *)"locale.library",38L);
     if((LocaleBase)) catalog=OpenCatalogA(NULL,"Messie.catalog",NULL);

     //******************************************
     // Everything ok now, let's go for the data.
     //******************************************

     ULONG mask=0,signals;
     class Messie modul(location ? location : "--- not set ---");

     if(!(modul.error)) {
      ret=0;
      mask = modul.GetSignalMask()|SIGBREAKF_CTRL_C;
      struct Mess_Param Params;

      for(;;) {
       signals=Wait(mask);
       if(signals & SIGBREAKF_CTRL_C) break;

       modul.CheckPort();
       while(modul.GetData(Params)) {
        modul.PlotData(Params);
        modul.SaveData(Params);
       }
      }
     }
          
     //******************************************
     // That was it.
     //******************************************
          
     if((LocaleBase)) {
      CloseCatalog(catalog);
      CloseLibrary(LocaleBase);
     }

     if((RexxSysBase)) CloseLibrary((struct Library *)RexxSysBase);
     CloseLibrary((struct Library *)IntuitionBase);
    } else PrintString("Can't open intuition.library V37.\n");
    CloseLibrary(GadToolsBase);
   } else PrintString("Can't open gadtools.library V37.\n");
   CloseLibrary((struct Library*)GfxBase);
  } else PrintString("Can't open graphics.library V37.\n");

  if(win!=NULL) {
   if(pr->pr_CIS==win) pr->pr_CIS=NULL;
   pr->pr_COS=NULL;
   Close(win);
  }

  if(location) FREEMEM(location);     

  if(workdirlock) {
   CurrentDir(progdirlock);
   UnLock(workdirlock);
  }

  if(_WBenchMsg) CurrentDir(lock);
  if((IconBase)) CloseLibrary(IconBase);
    
  CloseLibrary((struct Library*)DOSBase);
 } else if((DOSBase=(struct DosLibrary*)OpenLibrary(dosname,0L))) {
  BPTR handle;
  UBYTE cantopendos[]="Can't open dos.library V37.\n";
  if((handle=Output()) !=0) Write(handle,cantopendos,sizeof(cantopendos));
  CloseLibrary((struct Library*)DOSBase);
 }
 return ret;
}

