/*===========================================================================
  Copyright (C) 1995-2012 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++++ SC interface module SCS +++++++++++++++++++++
.LANGUAGE C
.IDENTIFICATION Module SCS
.AUTHOR         K. Banse  ESO - Garching	870721
.KEYWORDS       standard interfaces.
.ENVIRONMENT    theoretically environment independant.
.COMMENTS       all SC_interfaces related to System + parameter:
                SCSPRO, SCSEPI, SCPSET

.VERSION
 120423		last modif - really!!

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

#include <stdlib.h>

#include <osyparms.h>
#include <fileexts.h>
#include <stlibvars.h>
#include <osparms.h>
#include <osterm.h>

static int NoInt = 1, CntrlC = 0, only = 0, NoStop = 0;

 
/*

*/


/* ARGSUSED */
void interc(s)
int s;

{
if (NoInt == 1)
   CntrlC = 1;			/* just set the CntrlC flag */
else
   MID_ABORT(999,100);		/* exit from the application */
}
 
/*

*/

int myINIT(from)
int  from;		/* = 0, from monitor
			   = 1, from application */

{
register int  nr;


YDSC_PNTR = &YDSCDIR_ENTRY;

MID_INITER();				/*  init error business  */


/* create + clear FCT structure  */

(void) MID_FCTIN(-1);                          /* indicate 1. time  */

/*  FCT_PARM[0,1] holds values for F_XD_PARM
    [0] = initial no. of descriptors
    [1] = initial total space needed for descriptors in bytes
    defaulted to 100 initial descriptors and 6000 bytes descr. space
    => total 3 LDBs  (1 for directory + 2 for descrs)

    [2] = delete flag for extracted subframes, 1- delete, 0 - not 

    [3] = FITS header flag
    0- use all FITS keywords, 1- ignore ESO hierarchical keywords  */

FCT.PARM[0] = 100;
FCT.PARM[1] = 6000;
FCT.PARM[2] = 1;
FCT.PARM[3] = 0;			/* reset */


for (nr=0; nr<CAT_MAXNO; nr++)          /* clear CATALOG structure  */
   CATAL[nr].NAME[0] = ' ';

MID_TINIT();                            /*  some stuff for terminal I/O  */

return 0;
}
/*

*/

int SCSPRO(prog)
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
read keywords data base, initialize File Control Table and open logfile
.ALGORITHM
  straight forward
.RETURNS
return status  ( 0 = o.k )
--------------------------------------------------*/
 
char   *prog;	/* IN : name of calling program 
			if `name' is starting with a minus sign (-),
			this program is running outside the Midas
			environment;
			if `name' = "-no-stop-", SCSEPI() will not
			terminate the process but just return the
			last status */
 
{
int   i, status;
int   tcols, tlines;
 
char  cbuf[8], *outside;


#if vms
#else
 osscatch(SIGINT,interc);
 osscatch(SIGUSR1,SIG_IGN);		/* ignore signal USER1 + USER2 */
 osscatch(SIGUSR2,SIG_IGN);
#endif
 
if (only == 0)
   only = 1;
else
   {
   (void) printf("SCSPRO should only be called once - this call ignored ...\n");
   return ERR_NORMAL;
   }


i = myINIT(1);				/* returned value ignored for now */



/*  check, if this is an "outside" call  */
/*  -----------------------------------  */


cbuf[1] = '\0';


if (unlikely(*prog == '-')) 
   {
   if (strcmp(prog,"-no-stop-") == 0) NoStop = 1;
    
   cbuf[0] = '*';		/* default to use new FORGRdrs.KEY */
   if ((outside = getenv("MIDASDRS")))
      {
      if (*outside == 'y')		/* if yes, reuse existing */
         {				/* FORGRdrs.KEY, if possible */
         cbuf[1] = '*';
         cbuf[2] = '\0';
         }
      }
   }
else if ((outside = getenv("MIDAS_OUTSIDE")))
   {				/* yes, MIDAS_OUTSIDE env.var. is defined */
   cbuf[0] = cbuf[1] = '*';	/* reuse existing FORGRdrs.KEY */
   cbuf[2] = '\0';
   }
else
   {
   cbuf[0] = ' ';
   goto inside_job;
   }


status = MID_MOVKEY("IA",cbuf);		/* use new/old FORGRdrs.KEY */
if (status != ERR_NORMAL)		/* not o.k. - get out of here ... */
   {
   if (NoStop == 1)
      return status;
   else
      ospexit(1);
   }

MID_TTINFO(&tcols,&tlines);		/* get initial terminal size */
KIWORDS[OFF_LOG+9] = tcols;		/* save in log(10,11) */
KIWORDS[OFF_LOG+10] = tlines;

DATA_PATH[0] = '^';
DATA_PATH[320] = '\0';

#if vms				/* enable interrupt routine for CTRL/C */
#else
if (CntrlC == 1)
   MID_ABORT(999,100);	/* exit from the application */
#endif

if (NoStop != 1) status = MID_KEYFILE(prog);
return status;


/* inside Midas session */
/* use FORGR{DAZUNIT(1:2)}.KEY as keyword file */

inside_job:
status = MID_MOVKEY("IA",cbuf);		/*  get current keywords in  */

if (status != ERR_NORMAL) 	/* if not o.k. - get out of here ... */
   {
   (void) printf("Problems getting keywords in for program %s\n",prog);
   ospexit(1);
   }


/* get data path names from keyword DATA_PATH  */

(void) memcpy(DATA_PATH,&KCWORDS[OFF_DPATH],320);
DATA_PATH[320] = '\0';

 
/* open logfile  */
 
KIWORDS[OFF_LOG] = KIWORDS[OFF_LOG+7];			/* reset log flag */
status = MID_LOG('I',&KCWORDS[OFF_SESS+10],2);	   /* point to DAZUNIT  */
if (KIWORDS[OFF_LOG] == 2)
   {					/* if key LOG(1) = 2, init CPU timer */
   float  time;
   time = 0.0;
   status = OSY_TIMER('I',&time);
   if (status != ERR_NORMAL) MID_E1(1,"SCSPRO",status,1);
   }


/* enable interrupt routine for CTRL/C to exit */

#if vms
#else
 if (CntrlC == 1)
    MID_ABORT(999,100);         /* exit from the application */
 else
    NoInt = 0;     
#endif

/* check keyword AUX_MODE(10), if we should use 
   old, VERS_010 or new descriptor format                     */

if (KIWORDS[OFF_MONPAR+11] > 0)
   {					      /* from key MONITPAR(12,13) */
   FCT.PARM[0] = KIWORDS[OFF_MONPAR+11];   /* get initial no. of descr.s */
   FCT.PARM[1] = KIWORDS[OFF_MONPAR+12];   /* and initial descr_data bytes */
   }

if (KIWORDS[OFF_AUX+15] == 1)		/* ESO-DESC_ignore_flag set? */
   {
   i = 1;				/* Yes. Ignore ESO.xyz keywords */
   (void) SCPSET(F_FITS_PARM,&i);	/* in FITS headers */
   }


return status;
}
/*

*/

int SCSEPI()
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
write keywords back + clean up everything
.ALGORITHM
if everything goes o.k. and we are running inside Midas, we also exit
.RETURNS
return status only if something went wrong or we are outside Midas!!
-------------------------------------------------------------*/
 
{
int  mm, status, fp;
register int i;
 
char  cbuf[8];
 
struct FCT_STRUCT  *fctpntr;




only = 0;		/* reset one_time flag */


/* if key LOG(1) = 2  we get the CPU time + log it  */

if (KIWORDS[OFF_LOG] == 2)
   {
   float  time, r;
   char   record[80];
 
   status = OSY_TIMER('G',&time);
   if (status != ERR_NORMAL) MID_E1(2,"SCFCLO",status,1);
 
   KIWORDS[OFF_AUX+1] = (int) time;
   r = time * 0.01 ;				/* obtain seconds */
   i = OFF_APPLIC + 2;
   mm = snprintf(record,(size_t)80,"%.50s: CPU time = %g seconds\n",
              &KCWORDS[i],r);		/* obtain program name */
   (void) MID_LOG('G',record,mm);
   }

fp = KIWORDS[OFF_OUTFLG+2];
if (fp > 0) 
   {
   if (fp < 999) osaclose(fp);	/* fp = 999 means "Nullo" output */
   KIWORDS[OFF_OUTFLG+2] = -2;
   }
 
 
/*  close all files still open + add to current catalog   */
 
fctpntr = FCT.ENTRIES;
for (i=0; i<FCT.MAXENT; i++)
   {
   if (fctpntr->NAME[0] != ' ')
      {
      if (fctpntr->ACCESS == 'X')		/* virtual memory only */
         fctpntr->NAME[0] = ' ';
      else
         {
         if (fctpntr->CATALOG[0] == 'T')
            status = TCTCLO(i);           
         else
            status = SCFCLO(i);
         }
      }
   fctpntr ++;
   }
 

KCWORDS[OFF_APPLIC] = 't';		/* indicate that normal termination */
KIWORDS[OFF_PRSTAT] = 0;

NoInt = 1; 		/* disable exiting in CntrlC interrupt handler */


/* close logfile + write keywords back  */
 
KIWORDS[OFF_LOG+8] = 0;		/* clear print flag  */
(void) MID_LOG('O',cbuf,2);	/* length of cbuf not used */
cbuf[0] = ' ';
status = MID_MOVKEY("O",cbuf);

if (NoStop == 0) 
   {
   if (status != ERR_NORMAL) MID_E1(2,"...",status,1);
   ospexit(0);				/* always stop the process */
   }

return status;	/* if we get here, just return last status */
}
 
/*

*/

int SCPSET(para,pval)
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
set values for a parameter
.ALGORITHM
para is the parameter no. and pval[] the array of values for that parameter
.RETURNS
return status  ( 0 = o.k )
--------------------------------------------------*/

int  para;	/* IN: parameter no. given as a symbol */
int  *pval;	/* IN: array with values (may be just one) */

{
int  i;


switch (para)
  {
  case F_XD_PARM:		/* specify no. of descrs + initial space */
   if (*pval<1) 		/* pval[0] - no. of inital descriptors  */
      return ERR_INPINV;
   i = *(pval+1);
   if (i<1) 			/* pval[1] - initial descr. space in bytes */
      return ERR_INPINV;

   FCT.PARM[0] = *pval;		
   FCT.PARM[1] = i;		
   return ERR_NORMAL;


  case F_DEL_PARM:		/* delete (or not) extracted frames */
   i = *pval;
   if (i != 1) i = 0;
   FCT.PARM[2] = i;		/* 1 = YES - delete, 0 = NO */
   return ERR_NORMAL;


  case F_FITS_PARM:		/* handling of FITS headers */
   FCT.PARM[3] = *pval;
   if (KIWORDS[OFF_AUX+13] == 1)
      FCT.PARM[3] = 0;		/* FITS files are updated! */
/*
printf
("FCT.PARM = %d, %d, %d, %d\n",FCT.PARM[0],FCT.PARM[1],FCT.PARM[2],FCT.PARM[3]);
*/
   return ERR_NORMAL;

 
  default:
   return ERR_INPINV;
  }

}
 
