/*-------------------------------------------------------------------------
                      N X U T I L
                      
   NeXus data file writing utilities for SICS.
   
   
   Mark Koennecke, April 1998
   
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include "fortify.h"
#include "sics.h"
#include "motor.h"
#include "sicsvar.h"
#include "evcontroller.h"
#include "nxdict.h"
#include "nxutil.h"
/*-----------------------------------------------------------------------*/
  int SNXSPutMotor(SicsInterp *pSics, SConnection *pCon,
                      NXhandle hFil, NXdict pDict,
                      char *pAlias, char *pName)
  {
      pMotor pMot = NULL;
      float fVal;
      char pBueffel[512];
      int iRet;
      
      /* Find the motor */
      strtolower(pName);
      pMot = FindMotor(pSics,pName);
      if(!pMot)
      {
        sprintf(pBueffel,"WARNING: cannot find motor %s",pName);
        SCWrite(pCon,pBueffel,eWarning);
        return 0;
      }  
      
      /* get the position */
      iRet = MotorGetSoftPosition(pMot,pCon,&fVal);
      if(!iRet) /* should have been reported */
      {
        return 0;
      }
      
      /* write it */
      return NXDputalias(hFil,pDict,pAlias,&fVal);
  }                    
/*-----------------------------------------------------------------------*/
  int SNXSPutMotorNull(SicsInterp *pSics, SConnection *pCon,
                      NXhandle hFil, NXdict pDict,
                      char *pAlias, char *pName)
  {
      pMotor pMot = NULL;
      float fVal;
      char pBueffel[512];
      int iRet;
      
      /* Find the motor */
      strtolower(pName);
      pMot = FindMotor(pSics,pName);
      if(!pMot)
      {
        sprintf(pBueffel,"WARNING: cannot find motor %s",pName);
        SCWrite(pCon,pBueffel,eWarning);
        return 0;
      }  
      
      /* get the null point  */
      iRet = MotorGetPar(pMot,"softzero",&fVal);
      if(!iRet) /* should have been reported */
      {
        sprintf(pBueffel,
            "WARNING: failed to find zero point for motor %s",
            pName);
        SCWrite(pCon,pBueffel,eWarning);
        return 0;
      }
      
      /* write it */
      return NXDputalias(hFil,pDict,pAlias,&fVal);
  }                    
/*-------------------------------------------------------------------------*/
  int SNXSPutVariable(SicsInterp *pSics,SConnection *pCon,
                             NXhandle hFil, NXdict pDict,
                             char *pAlias, char *pName)
  {
     pSicsVariable pVar = NULL;
     int iRet;
     float fVal;
     int   iVal;
     char pBueffel[512];
     VarType eType;
     char *pText = NULL;
     
     /* find it */
     strtolower(pName);
     pVar = FindVariable(pSics,pName);
     if(!pVar)
     {
        sprintf(pBueffel,"WARNING: cannot find variable %s",pName);
        SCWrite(pCon,pBueffel,eWarning);
        return 0;
     }  

     /* write it, depending on type */
     eType = GetVarType(pVar);
     switch(eType)
     {
       case veText:
            VarGetText(pVar,&pText);
            if(pText != NULL)
            {
              iRet = NXDputalias(hFil,pDict,pAlias,pText);
              free(pText);
              return iRet;
            }
            break;
       case veInt:
            VarGetInt(pVar,&iVal);
            return NXDputalias(hFil,pDict,pAlias,&iVal);
            break;     
       case veFloat:
            VarGetFloat(pVar,&fVal);
            return NXDputalias(hFil,pDict,pAlias,&fVal);
            break;     
       default:
            assert(0); /* should not happen */
          
     }
     return 1;     
  }                           
/*------------------------------------------------------------------------*/
  void SNXFormatTime(char *pBuffer, int iBufLen)
  {
     time_t iDate;
     struct tm *psTime;

     /* make time string */
     iDate = time(NULL);
     psTime = localtime(&iDate);
     memset(pBuffer,0,iBufLen);         
     strftime(pBuffer,iBufLen,"%Y-%m-%d %H:%M:%S",psTime);
  } 
/*--------------------------------------------------------------------------*/
  int SNXSPutGlobals(NXhandle hfil,char *pFilename, 
                    char *pInst, SConnection *pCon)
  {
    pSicsVariable pVar = NULL;
    char pBueffel[1024];
    char *pUser,*pemail,*pPhone,*pFax, *pAddress;
    int iRet;
    
     /* write global attributes */
     strcpy(pBueffel,"UNKNOWN");
     pVar = FindVariable(pServ->pSics,"user");
     if(pVar)
     {
        pUser = pVar->text;
     }
     else
     {
        SCWrite(pCon,"WARNING: Variable user not found ",eWarning);
        pUser = pBueffel;
     }
     pVar = FindVariable(pServ->pSics,"phone");
     if(pVar)
     {
        pPhone = pVar->text;
     }
     else
     {
        SCWrite(pCon,"WARNING: Variable phone not found ",eWarning);
        pPhone = pBueffel;
     }
     pVar = FindVariable(pServ->pSics,"email");
     if(pVar)
     {
        pemail = pVar->text;
     }
     else
     {
        SCWrite(pCon,"WARNING: Variable email not found ",eWarning);
        pemail = pBueffel;
     }
     pVar = FindVariable(pServ->pSics,"adress");
     if(pVar)
     {
        pAddress = pVar->text;
     }
     else
     {
        SCWrite(pCon,"WARNING: Variable adress not found ",eWarning);
        pAddress = pBueffel;
     }
     pVar = FindVariable(pServ->pSics,"fax");
     if(pVar)
     {
        pFax = pVar->text;
     }
     else
     {
        SCWrite(pCon,"WARNING: Variable phone not found ",eWarning);
        pFax = pBueffel;
     }
     iRet = NXUwriteglobals(hfil,
                            pFilename,
                            pUser,
                            pAddress,
                            pPhone,
                            pemail,
                            pFax,
                            pInst);
     if(iRet != NX_OK)
     {
       SCWrite(pCon,"WARNING: failed writing global attributes to file",eWarning);
     } 

     return 1;
  }                      
/*---------------------------------------------------------------------------*/
   int SNXSPutEVVar(NXhandle hfil, NXdict pDict,
                       char *pName, SConnection *pCon,
                       char *pValAlias, char *pStdDevAlias)
   {
     CommandList *pCom  = NULL;
     pIDrivable  pDriv = NULL;  
     float fMean, fStdDev;
     pVarLog pLog = NULL;
     int iRet;
     char pBueffel[512];
     pSicsVariable pVar = NULL;

     pCom = NULL;
     fMean = -111.;
     fStdDev = -111.;
     pCom = FindCommand(pServ->pSics,pName);
     if(pCom)
     {
        pDriv = GetDrivableInterface(pCom->pData);
        if(pDriv) /* it is a controller */
        {
          pLog = EVCGetVarLog((pEVControl)pCom->pData);
          iRet = VarlogGetMean(pLog,&fMean, &fStdDev);
          if(!iRet)
          { /* the data was not logged, get the value */
            iRet = EVCGetPos((pEVControl)pCom->pData,pCon,&fMean);
          }
        }
        else
        {
          /* it can still be a simple variable */
          pVar = (pSicsVariable)pCom->pData;
          fMean = pVar->fVal;
        }
     }
     
     if(fMean < -110)
     {
       sprintf(pBueffel,"WARNING: %s invalid",pName);
       SCWrite(pCon,pBueffel,eWarning);
     }
     if(pStdDevAlias)
     {
       if(fStdDev < -110)
       {
          sprintf(pBueffel,"WARNING: %s standard deviation invalid",pName);
          SCWrite(pCon,pBueffel,eWarning);
       }
     } 
     /* whatever it was, write it, even if it is shit */
     iRet = NXDputalias(hfil,pDict,pValAlias,&fMean);
     if(iRet != NX_OK)
     {
         sprintf(pBueffel,"WARNING: failed to write %s",pName);
         SCWrite(pCon,pBueffel,eWarning);
     }
     if(pStdDevAlias)
     {
        iRet = NXDputalias(hfil,pDict,pStdDevAlias,&fStdDev);
        if(iRet != NX_OK)
        {
            sprintf(pBueffel,"WARNING: failed to write %s standard deviation",pName);
            SCWrite(pCon,pBueffel,eWarning);
        }
     }   
     return 1;
   }  
/*---------------------------------------------------------------------------*/
   int SNXSPutDrivable(SicsInterp *pSics, SConnection *pCon,
                       NXhandle hfil, NXdict pDict,
                       char *pName, 
                       char *pAlias)
   {
     CommandList *pCom  = NULL;
     pIDrivable  pDriv = NULL;  
     float fVal =- -777.77;
     int iRet;
     char pBueffel[512];

     pCom = NULL;
     pCom = FindCommand(pSics,pName);
     if(pCom)
     {
        pDriv = GetDrivableInterface(pCom->pData);
        if(pDriv) /* it is drivable */
        {
           fVal = pDriv->GetValue(pCom->pData,pCon);  
        }
        else
        {
          sprintf(pBueffel,"ERROR: %s is not driveable, not written",pName);
          SCWrite(pCon,pBueffel,eError);
          return 0;
        }
     }
     
     /* whatever it was, write it, even if it is shit */
     iRet = NXDputalias(hfil,pDict,pAlias,&fVal);
     if(iRet != NX_OK)
     {
         sprintf(pBueffel,"WARNING: failed to write %s",pName);
         SCWrite(pCon,pBueffel,eWarning);
         return 0;
     }
     return 1;
   }  
