/*-------------------------------------------------------------------------

                           N E X T R I C S
                           
   NeXus file writing for the four circle diffractometer TRICS at Sinq, PSI.
   
   This object uses the NXDICT-API. A further speciality is that objects
   which are constantly written are kept in  cache. This means, on 
   initialisation pointers to all relevant objects which have to be stored with
   a data frame are searched and kept in the objects data structure.
   
   copyright: see copyright.h
   
   Mark Koennecke, April 1998
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include "fortify.h"
#include "sics.h"
#include "sicsvar.h"
#include "motor.h"
#include "countdriv.h"
#include "counter.h"
#include "HistMem.h"
#include "danu.h"
#include "nxdict.h"
#include "nxutil.h"
#include "hkl.h"
#include "udpquieck.h"
#include "nextrics.h"

#define DET1X 128  /* x -length of detector 1 */ 
#define DET1Y 128  /* y-length of detector 1 */
#define DET1XS 2   /* pixel size in x of detector 1 */
#define DET1YS 2   /* pixel size in y of detector 1 */
#define DET1DESC "Non existent Detector"
#define DETAMAX 128 /* maximum length of pixelsize array */

/*------------------------ the data structure ----------------------------*/
  typedef struct __NexTrics {
                              pObjectDescriptor pDes;
                              char *pCurrentFile;
                              char *pFileRoot;
                              pDataNumber pDanu;
                              NXdict pDict;
                              pHistMem pHistogram;
                              int iFirst;
                            } NexTrics;
                              
/*----------------------------------------------------------------------*/
  pNexTrics CreateNexTrics(pDataNumber pNum, char *pRoot, char *pDict,
                           SicsInterp *pSics)
  {
    pNexTrics pNew = NULL;
    int iRet;
    CommandList *pCom = NULL;
    
    /* allocate memory */
    pNew = (pNexTrics)malloc(sizeof(NexTrics));
    if(!pNew)
    {
      return NULL;
    }
    memset(pNew,0,sizeof(NexTrics));
    
    /* new object descriptor */
    pNew->pDes = CreateDescriptor("NexTrics");
    if(!pNew->pDes)
    {
      free(pNew);
      return NULL;
    }    
    
    /* initialize dictionary */
    iRet = NXDinitfromfile(pDict,&pNew->pDict);
    if(iRet != NX_OK)
    {
       DeleteNexTrics(pNew);
       return NULL;
    }
    pNew->pFileRoot = strdup(pRoot);
    pNew->pDanu = pNum;
    
    /* find things in interpreter */
    pCom = FindCommand(pSics,"banana");
    if(!pCom)
    {
       DeleteNexTrics(pNew);
       return NULL;
    }
    pNew->pHistogram = (pHistMem)pCom->pData;
    pNew->iFirst = 1;
    
    return pNew;
  }                         
/*-------------------------------------------------------------------------*/
  void DeleteNexTrics(void *pData)
  {
     pNexTrics self = NULL;
     
     self = (pNexTrics)pData;
     if(!self)
        return;
        
     if(self->pDes)
        DeleteDescriptor(self->pDes);
        
     if(self->pCurrentFile)
         free(self->pCurrentFile);
         
     if(self->pFileRoot)
         free(self->pFileRoot);
       
     if(self->pDict)
        NXDclose(self->pDict,NULL);
        
     free(self);                 
  }  
/*---------------------- a neXus error handler ---------------------------*/
  static void SNError(void *pData, char *text)
  {
     SConnection *pCon;
     
     assert(pData);
     pCon = (SConnection *)pData;
     SCWrite(pCon,text,eError);
  }
/*--------------------------------------------------------------------------*/
  int NexTricsFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
                      int argc, char *argv[])
  {
        pNexTrics pNew = NULL;
        pDataNumber pDanu = NULL;
        CommandList *pCom;
        char pBueffel[512];
        int iRet;
        pDummy pDum;
        
        if(argc < 4)
        {
           SCWrite(pCon,
               "ERROR: Insufficient number of arguments to NexTricsFactory",eError);
           return 0;    
        }
        
        /* first item must be the name of a datanumber variable */
        pCom = FindCommand(pSics,argv[1]);
        if(pCom)
        {
          pDanu = (pDataNumber)pCom->pData;
        }
        if( (!pCom) || (!pDanu))
        {
           SCWrite(pCon,"ERROR: DataNumber object NOT found",eError);
           return 0;
        }
        pDum = (pDummy)pDanu;
        if(strcmp(pDum->pDescriptor->name,"DataNumber") != 0)
        {
          sprintf(pBueffel,"ERROR: %s is no DataNumber object",argv[1]);
          SCWrite(pCon,pBueffel,eError);
          return 0;
        }
        
        /* install an error handler */
       NXMSetError((void *)pCon,SNError); 
    
       pNew = CreateNexTrics(pDanu,argv[2],argv[3],pSics);
       if(!pNew)
       {
         SCWrite(pCon,"ERROR: cannot create nexTrics, invalid dictionary file",eError);
         SCWrite(pCon,"ERROR:  or system objects missing.",eError);
         return 0;
       }      
       
       /* create the command */
       iRet = AddCommand(pSics,"nexus",NexTricsAction,DeleteNexTrics,
                         pNew);
       if(!iRet)
       {
          SCWrite(pCon,"ERROR: duplicate command nexus not created",eError);
       }                  
       return iRet;
  }
/*-------------------------------------------------------------------------*/
  static int DumpData(pNexTrics self, SConnection *pCon, NXhandle hfil, 
                      int iFrameNum)
  {
     int iRet;
     char pBueffel[512];
     CounterMode eMode;
     HistInt lData[DET1X*DET1Y], i, lVal;
     int32 iVal;
     float fVal;

     /* write motors */
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "framechi","CHI");     
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "framephi","PHI");     
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "frameomega","OM");     
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "frame2theta","stt");     
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "frametilt","DG1");     

     /* write frame time */
     SNXFormatTime(pBueffel,512);
     iRet = NXDputalias(hfil,self->pDict,"etime",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: cannot write frame time",eError);
     }
     
     /* write counting parameters */
     eMode = GetHistCountMode(self->pHistogram);
     if(eMode == eTimer)
     {
       strcpy(pBueffel,"Timer");
     }
     else
     {
       strcpy(pBueffel,"Monitor");
     }
     NXDputalias(hfil,self->pDict,"framemode",pBueffel);     
     fVal = GetHistPreset(self->pHistogram);
     NXDputalias(hfil,self->pDict,"framepreset",&fVal);
     lVal = GetHistMonitor(self->pHistogram,1,pCon);
     iVal = (int32)lVal;
     NXDputalias(hfil,self->pDict,"framemonitor",&iVal);
     
     /* write detector1 histogram */
     GetHistogram(self->pHistogram,pCon,0,0,DET1X*DET1Y,lData,DET1X*DET1Y*sizeof(HistInt));
     NXDputalias(hfil,self->pDict,"framecounts",lData);

     /* the NXdata links */
     NXDaliaslink(hfil,self->pDict,"frame","detectorx");
     NXDaliaslink(hfil,self->pDict,"frame","detectory");
     NXDaliaslink(hfil,self->pDict,"frame","framecounts");
     
     /* temperature */
     SNXSPutEVVar(hfil,self->pDict,"temperature",
                  pCon,
                  "frametemp",
                  "framestdev");   
     
     /* close and done */
     sprintf(pBueffel,"Frame %d succesfully written",iFrameNum-1);
     SCWrite(pCon,pBueffel,eStatus);
     
     return 1;
 }
/*--------------------------------------------------------------------------*/
  static int  WriteFirstFrame(pNexTrics self, SConnection *pCon)
  {
     char pBueffel[1024];
     NXhandle hfil;
     int iRet, iYear, i;
     pSicsVariable pVar;
     char *pText;
     CommandList *pCom = NULL;
     pHKL pCryst = NULL;
     float fVal, fPix[DETAMAX];
     
     iRet = NXopen(self->pCurrentFile,NXACC_RDWR,&hfil);
     if(iRet != NX_OK)
     {
       sprintf(pBueffel,"ERROR: cannot open %s",self->pCurrentFile);
       SCWrite(pCon,pBueffel,eError);
       return 0;
     }       
  
     /* make sure: first frame */
     NXDupdate(self->pDict,"framename","frame0000");
  
     /* title */
     pVar = NULL;
     pVar = FindVariable(pServ->pSics,"title");
     if(pVar)
     {
        pText = pVar->text;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable title not found ",eError);
        pText = pBueffel;
     }
     iRet = NXDputalias(hfil,self->pDict,"etitle",pText);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write title",eError);
     }
     
     /* start time */
     SNXFormatTime(pBueffel,1023);
     iRet = NXDputalias(hfil,self->pDict,"etime",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write start time",eError);
     }
     
     /* source info */
     strcpy(pBueffel,"SINQ at Paul Scherrer Institut, Villigen");
     iRet = NXDputalias(hfil,self->pDict,"sname",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write source name",eError);
     }
     strcpy(pBueffel,"Continous flux spallation source");
     iRet = NXDputalias(hfil,self->pDict,"stype",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write source type",eError);
     }
     
     /* instrument name */
     strcpy(pBueffel,"TRICS at SINQ, Paul Scherrer Institut, Switzerland"); 
     iRet = NXDputalias(hfil,self->pDict,"iname0",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write instrument name",eError);
     }
     
     
     /* Monochromator */
     pVar = NULL;
     strcpy(pBueffel,"UNKNOWN");
     pVar = FindVariable(pServ->pSics,"monodescription");
     if(pVar)
     {
        pText = pVar->text;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable monodescription not found ",eError);
        pText = pBueffel;
     }
     iRet = NXDputalias(hfil,self->pDict,"monodes",pText);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write monodescription",eError);
     }

     /* lambda */
     pCom = FindCommand(pServ->pSics,"HKL");
     if(pCom)
     {
       pCryst = (pHKL)pCom->pData;
     }
     if(!pCryst)
     {
        SCWrite(pCon,"ERROR: HKL not found, cannot write lambda",eError);
     }
     else
     {
        GetLambda(pCryst,&fVal);
        iRet = NXDputalias(hfil,self->pDict,"monolambda",&fVal);
        if(iRet != NX_OK)
        {
             SCWrite(pCon,"ERROR: failed to write lambda",eError);
        }
     }
     
     /* two theta */
     pVar = NULL;
     strcpy(pBueffel,"UNKNOWN");
     pVar = FindVariable(pServ->pSics,"mono2theta");
     if(pVar)
     {
        fVal = pVar->fVal;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable mono2theta not found ",eError);
        fVal = -2188.99;
     }
     iRet = NXDputalias(hfil,self->pDict,"mono2theta",&fVal);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write monochromator 2 Theta",eError);
     }
     /* theta, needs work when lift operational */
     SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict,
                  "monotheta","MUCA");     
     
     
     /* detector data */
     /* first set detector variables in dictionary */
     strcpy(pBueffel,"detector1");
     NXDupdate(self->pDict,"dnumber",pBueffel);
     sprintf(pBueffel,"%d",DET1X);
     NXDupdate(self->pDict,"framedim1",pBueffel);
     sprintf(pBueffel,"%d",DET1Y);
     NXDupdate(self->pDict,"framedim2",pBueffel);
     strcpy(pBueffel,DET1DESC);
     iRet = NXDputalias(hfil,self->pDict,"ddescription",pBueffel);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detector1 description",eError);
     }
     for(i = 0; i < DET1X; i++)
     {
       fPix[i] = i * DET1XS;
     }
     iRet = NXDputalias(hfil,self->pDict,"detectorx",fPix);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detector1 x-axis description",eError);
     }
     for(i = 0; i < DET1Y; i++)
     {
       fPix[i] = i * DET1YS;
     }
     iRet = NXDputalias(hfil,self->pDict,"detectory",fPix);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detector1 y-axis description",eError);
     }
     pVar = NULL;
     pVar = FindVariable(pServ->pSics,"det1zerox");
     if(pVar)
     {
        fVal = pVar->fVal;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable detector x zero point not found ",eError);
        fVal = -2188.99;
     }
     iRet = NXDputalias(hfil,self->pDict,"detzerox",&fVal);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detecor x zero point",eError);
     }
     pVar = NULL;
     pVar = FindVariable(pServ->pSics,"det1zeroy");
     if(pVar)
     {
        fVal = pVar->fVal;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable detector y zero point not found ",eError);
        fVal = -2188.99;
     }
     iRet = NXDputalias(hfil,self->pDict,"detzeroy",&fVal);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError);
     }
     pVar = NULL;
     pVar = FindVariable(pServ->pSics,"det1dist");
     if(pVar)
     {
        fVal = pVar->fVal;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable detector distance not found ",eError);
        fVal = -2188.99;
     }
     iRet = NXDputalias(hfil,self->pDict,"detdist",&fVal);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError);
     }
     iRet = 1;
     iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write frame validity",eError);
     }
     
     
     /* do sample information */
     strcpy(pBueffel,"UNKNOWN");
     pVar = FindVariable(pServ->pSics,"sample");
     if(pVar)
     {
        pText = pVar->text;
     }
     else
     {
        SCWrite(pCon,"ERROR: Variable sample not found ",eError);
        pText = pBueffel;
     }
     iRet = NXDputalias(hfil,self->pDict,"samplename",pText);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write sample name",eError);
     }
   
     /* put the frame number */
     iRet = 0;
     iRet = NXDputalias(hfil,self->pDict,"fnum",&iRet);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write initial frame number",eError);
     }

     /* write actual data */
     iRet = DumpData(self,pCon,hfil,1);

     /* put the frame number */
     iRet = 1;
     iRet = NXDputalias(hfil,self->pDict,"fnum",&iRet);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write initial frame number",eError);
     }
     
     self->iFirst = 0;
     
     /* close the file and go */
     NXclose(&hfil);
     SendQuieck(QUIECK,self->pCurrentFile);
     return iRet;
  }  
/*-------------------------------------------------------------------------*/
  static int ContinueFile(pNexTrics self, SConnection *pCon)
  {
     int iFrameNum, iRet;
     char pBueffel[1024];
     float fVal;
     NXhandle hfil;
     
     assert(self);
     assert(pCon);
     assert(self->iFirst == 0);
     
     /* let's start by opening the file*/
     iRet = NXopen(self->pCurrentFile,NXACC_RDWR,&hfil); 
     if(iRet != NX_OK)
     {
       sprintf(pBueffel,"ERROR: cannot reopen %s, NO data written",
               self->pCurrentFile);
       SCWrite(pCon,pBueffel,eError);  
       return 0;      
     }
     
     /* read the frame number, set the framename for further reading, 
        increment and write back again
     */
     iRet = NXDgetalias(hfil,self->pDict,"fnum",&iFrameNum);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"EERROR: cannot read old framenumber, NO data written",eError);
       return 0;
     }
     sprintf(pBueffel,"frame%4.4d", iFrameNum);
     NXDupdate(self->pDict,"framename",pBueffel);
     iFrameNum++;
     iRet = NXDputalias(hfil,self->pDict,"fnum",&iFrameNum);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"EERROR: cannot write new framenumber, NO data written",eError);
       return 0;
     }

     /* put in links to duplicates: entry */
     iRet = NXDaliaslink(hfil,self->pDict,"entry","etitle0");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against title",eWarning);
     }
     
     /* links to instrument */
     iRet = NXDaliaslink(hfil,self->pDict,"inst0","iname0");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against instrument name",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"inst0","source0");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against source group",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"inst0","mono0");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against monochromator group",eWarning);
     }
     
     /* links in detector group */
     iRet = NXDaliaslink(hfil,self->pDict,"det1","ddescription");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector description",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"det1","detectorx");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector x-axis",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"det1","detectory");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector y-axis",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"det1","detzerox");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector x zero ",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"det1","detzeroy");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector y zero",eWarning);
     }
     iRet = NXDaliaslink(hfil,self->pDict,"det1","detdist");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against detector distance",eWarning);
     }
     iRet = 1;
     iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"ERROR: failed to write frame validity",eError);
     }
     
     
     /* links in sample group */
     iRet = NXDaliaslink(hfil,self->pDict,"samplev","samplename");  
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: cannot link against sample name",eWarning);
     }
     
     /* write actual data */
     iRet = DumpData(self,pCon,hfil,iFrameNum);

     /* close the file and go */
     NXclose(&hfil);
     SendQuieck(QUIECK,self->pCurrentFile);
     return iRet;
  
  }
/*--------------------------------------------------------------------------*/
  int StartFile(pNexTrics self, SConnection *pCon)
  {
     char pBueffel[1024];
     NXhandle hfil;
     int iRet, iYear, i;
     pSicsVariable pVar;
     char *pText;
     CommandList *pCom = NULL;
     pHKL pCryst = NULL;
     float fVal, fPix[DETAMAX];
     
     /* make a filename and open it */
     if(self->pCurrentFile)
        free(self->pCurrentFile);
     iRet  = IncrementDataNumber(self->pDanu,&iYear);
     sprintf(pBueffel,"%s/trics%4.4d%4.4d.hdf",self->pFileRoot,iRet, iYear);
     self->pCurrentFile = strdup(pBueffel);   
     iRet = NXopen(self->pCurrentFile,NXACC_CREATE,&hfil);
     if(iRet != NX_OK)
     {
       sprintf(pBueffel,"ERROR: cannot open %s",self->pCurrentFile);
       SCWrite(pCon,pBueffel,eError);
       return 0;
     }       
  
     /* tell user what we are doing */
     sprintf(pBueffel,"Initialising file %s ......", self->pCurrentFile);
     SCWrite(pCon,pBueffel,eWarning);
     
     
     /* Write header data */
     SNXSPutGlobals(hfil,self->pCurrentFile,
                    "TRICS at SinQ, Paul Scherrer Institut, Switzerland",
                    pCon);

     self->iFirst = 1;
     
     /* close the file and go */
     NXclose(&hfil);
     return 1;
  }  
/*-------------------------------------------------------------------------*/
  int ReopenFile(pNexTrics self, char *filename)
  {
     char pBueffel[1024];
     NXhandle hfil;
     int iRet, iFrameNum;
     
     assert(self);
     
     /* concat with data root and check for existence */
     sprintf(pBueffel,"%s/%s",self->pFileRoot,filename);
     iRet = NXopen(pBueffel,NXACC_RDWR,&hfil);
     NXclose(&hfil);
     if(iRet != NX_OK)
     {
       return 0;
     }
     else
     {
       if(self->pCurrentFile)
            free(self->pCurrentFile);
       self->pCurrentFile = strdup(pBueffel);     
     }

     /* check the framenumber, if already data written */
     iRet = NXDgetalias(hfil,self->pDict,"fnum",&iFrameNum);
     if(iRet != NX_OK)
     {
       self->iFirst = 1;
     }
     else
     {
       self->iFirst = 0;
     }
     return 1;
  }
/*--------------------------------------------------------------------------*/
  int DumpFrame(pNexTrics self, SConnection *pCon)
  {
     int iRet;
     
     assert(self);
     assert(pCon);
     
     if(self->iFirst == 1)
     {
        iRet = WriteFirstFrame(self,pCon);
     }
     else
     {
       iRet = ContinueFile(self,pCon);
     }     

     return iRet;     
  }  
/*---------------------------------------------------------------------------*/
  int NexTricsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
                     int argc, char *argv[])
  {
      pNexTrics self;
      char pBueffel[1024];
      int iRet;
      
      self = (pNexTrics)pData;
      assert(self);
      assert(pCon);
      
      /* check for subcommands */
      if(argc < 2)
      {
        sprintf(pBueffel,"ERROR: no subcommand found for %s",argv[0]);
        SCWrite(pCon,pBueffel,eError);
        return 0;
      }

       /* install an error handler */
       NXMSetError((void *)pCon,SNError); 
      
      strtolower(argv[1]);
      if(strcmp(argv[1],"start") == 0)
      {
         if(!SCMatchRights(pCon,usUser))
         {
           return 0;
         }
         iRet = StartFile(self,pCon);
         if(iRet)
         {
           SCSendOK(pCon);
         }
         return iRet;
      }
      else if(strcmp(argv[1],"file") == 0)
      {
        sprintf(pBueffel,"Currently writing to: %s",self->pCurrentFile);
        SCWrite(pCon,pBueffel,eValue);
        return 1; 
      }
      else if(strcmp(argv[1],"dumpframe") == 0)
      {
         if(!SCMatchRights(pCon,usUser))
         {
           return 0;
         }
         iRet = DumpFrame(self,pCon);
         if(iRet)
         {
           SCSendOK(pCon);
         }
         return iRet;
      }
      else if(strcmp(argv[1],"reopen") == 0)
      {
         if(!SCMatchRights(pCon,usUser))
         {
           return 0;
         }
         if(argc < 3)
         {
           SCWrite(pCon,"ERROR: expected filename as parameter for reopen",eError);
           return 0;
         }
         iRet = ReopenFile(self,argv[2]);
         if(iRet)
         {
           SCSendOK(pCon);
         }
         return iRet;
      }
      sprintf(pBueffel,"ERROR: subcommand %s not recognized",argv[1]);
      SCWrite(pCon,pBueffel,eError);
      return 0;
  }                                                                   
