/*===========================================================================
  Copyright (C) 1995-2008 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
===========================================================================*/

/*+++++++++++++++++++  Module cgne.c  +++++++++++++++++++++++++++++++++++
.LANGUAGE    C
.IDENTIFICATION  Module cgne.c
.AUTHOR  K. Banse                  ESO - Garching
.KEYWORDS
catalogs, MIDAS frames
.COMMENTS
holds CGN_singleframe, CGN_FRAME, CGN_DSCUPD, CGN_LOGNAM, issub

.VERSION  [1.00] 920325: copied from /midas/`version'/monit/prepl.c
 080131		last modif

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

#include <string.h>
#include <stdlib.h>
#include <fileexts.h>
#include <fsydef.h>

/*

*/

int issub(name)
char  *name;

{
register int nr, mr;

register char cr;



nr = 0;
while (nr > -1)
   {
   cr = name[nr];
   if (cr == '@')
      return (nr);                      /* name@123 */
   else if ((cr == ' ') || (cr == '\0'))
      {
      nr--;
      break;
      }
   nr++;
   }

if (name[nr] == ']')                    /* name[12:34] */
   {
   for (mr=nr; mr>0; mr--)
      {
      if (name[mr] == '[') return(mr);
      }
   }

return(0);
}
/*

*/

int  CGN_singleframe(inname,type,outname)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++

.RETURN
 1 = filename has changed and is stored in outname
 0 = no change, use inname (outname not filled)

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

char    *inname         /* IN: input name */;
int     type		/* IN: type of frame 
			       1=image, 3=table, 4 = fit file */;
char    *outname        /* OUT: new name */;


{
char    catfile[120], cbuf[120];
char    *typeptr;
register char    cc, csav;

int   frmno, status, idx, k, n, mm;
register int   nr, isu, ioff, koff;

float      roff;

double     doff;




typeptr = FSY_DEFPNTR[0];
csav = 'a' - 'A';


/*  check for &a, &A names   */

if (*inname == '&')
   {
   cc = inname[1];
   if ( (cc >= 'A') && (cc <= 'Z') )
      csav += cc;
   else if ( (cc >= 'a') && (cc <= 'z') )
      csav = cc;
   else 				/* must be &123&* or so ... */
      return(0);

   (void) memcpy(outname,"middumm ",(size_t)9);
   idx = 7;
   if (KIWORDS[OFF_AUX+11] == 123)
      {					/* check AUX_MODE(12) */
      mm = OFF_SESS + 10;			/* point to MIDAS unit */
      outname[7] = KCWORDS[mm++];
      outname[8] = KCWORDS[mm];
      idx = 9;
      }
   outname[idx++] = csav;

   ioff = koff = -1;		/* look for subframes abc[...] */
   for (nr=2; ; nr++)
      {
      cc = inname[nr];
      if (cc == '\0')
         break;
      else if (cc == '[')
         {
         if (ioff == (-1)) ioff = nr-2;
         if (koff > (-1)) break;
         }
      else if (cc == FSY_TYPMARK)
         {      			/* if  we are after the '[' already */
         if (ioff > (-1)) break;	/* we leave koff as -1 */
         if (koff == (-1)) koff = nr-2;
         }
      }

   if (koff == (-1))
      {
      if (KIWORDS[OFF_AUX+12] == 1)
         {
         cbuf[0] = '.';				/* so look for default */
         if (type == 1)					/* image type */
            (void) SCKGETC("MID$TYPES",1,8,&k,cbuf+1);
         else if (type == 3)				/* table type */
            (void) SCKGETC("MID$TYPES",9,8,&k,cbuf+1);
         else 					/* should be fit file */
            (void) strcpy(cbuf+1,"fit");
         typeptr = cbuf;

         }
      else
         typeptr = FSY_DEFPNTR[type-1];
      }

   if (ioff < 0)
      {
      (void) strcpy(&outname[idx],&inname[2]);
      if (koff == (-1)) (void) strcat(outname,typeptr);
      }
   else
      {
      if (ioff > 0) (void) memcpy(&outname[idx],&inname[2],(size_t)ioff);
      if (koff == (-1))              /* e.g. &a[2.3:30.3] */
         {
         (void) strcpy(&outname[idx+ioff],typeptr);
         (void) strcat(outname,&inname[2+ioff]);
         }
      else
         (void) strcpy(&outname[idx+ioff],&inname[2+ioff]);
      }

   return (1);
   }


/*  check for #xyz or #xyz_catalog   */

if (*inname == '#')

   {
   n = CGN_INDEXC(inname,'_');
   if (n > 0)
      {
      k = n - 1;
      (void) memcpy(cbuf,&inname[1],(size_t)k);
      cbuf[k] = '\0';
      (void) strcpy(catfile,&inname[n+1]);
      }
   else
      {		/* catalog enabled? If so, copy name from keyw. CATALOG */
      mm = OFF_CATINF + type;
      if (KIWORDS[mm+4] == 0)	/* CATALINF(type+5) = catal_enabled_flag */
         return (0);			/* Not enabled, do nothing */

      n = KIWORDS[mm-1];	/* get offset of this catalog  from CATALINF */
      mm = OFF_CATAL + (n - 1);
      k =  KIWORDS[OFF_CATINF+10];       /* length of catalog file  */
      (void) memcpy(catfile,&KCWORDS[mm],(size_t)k);
      catfile[k] = '\0';
      (void) strcpy(cbuf,&inname[1]);
      }

   isu = issub(cbuf);
   if (isu > 0)
      {
      csav = cbuf[isu];                 /* save that char. */
      cbuf[isu] = '\0';
      }
   if (CGN_CNVT(cbuf,1,1,&frmno,&roff,&doff) <= 0) return (0); 

   status = SCCFND(catfile,frmno,outname);
   if (status != ERR_NORMAL) return (0);;

   if (isu > 0)
      {
      cbuf[isu] = csav;
      (void) strcat(outname,&cbuf[isu]);	/* append subframe sepcs */
      }
   }


/*  check for '*'  */

else if (*inname == '*')
   {
   cc = *(inname+1);
   if ((cc == ' ') || (cc == '\0'))
   (void) SCKGETC("IDIMEMC",1,60,&n,outname);	/* should move to 100 ... */
   }


/* in all other cases use input name */

else                                    /*  nothing to do */
   return (0);

return (1);                     /* Yes, we did replace the file name */
}
/*

*/

int CGN_FRAME(inname,type,outname,optio)

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.ALGORITHM
 use CGN_singleframe
 if not replaced, copy input name over to output name
.RETURNS
 1 if replacement, 0 if same frame returned

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

char  *inname		/* IN: input name */;
int   type		/* IN: type of frame,
			       1 = image, 3 = table, 4 = FIT file */;
char  *outname		/* OUT: new name */;
int   optio		/* IN: = 0, single frame; = 1, whole string */;
 
{
int   klen, kk, mm, iav, status;
register int nj, nr;

char  twork[256], tframe[80], xframe[80];
register char cr;
static char  limc[] = {'+','-','/','*','(',')','.',',','\0'};




if (optio != 1)
   {
   cr = *inname;
   if ((cr == 'm') || (cr == 'M'))
      {						/* check for "middumm..." */
      (void) CGN_UPCOPY(twork,inname+1,8);
      if (strncmp(twork,"IDDUMM",6) == 0)
         {
         cr = twork[6];
         if ((cr != '\0') && (cr != '.')  && (cr != ' '))
            {
            twork[0] = '&';			/* we're sure of replacement */
            (void) strcpy(twork+1,inname+7);
            status = CGN_singleframe(twork,type,outname);
            if (status == 0) (void) strcpy(outname,inname);
            return(status);
            }
         }
      }

   status = CGN_singleframe(inname,type,outname);
   if (status == 0) (void) strcpy(outname,inname);
   return(status);
   }

 
/* we have to handle a whole string */

mm = CGN_INDEXC(inname,'#');
if (mm >= 0)
   {
   klen = CGN_COPY(twork,inname);
   kk = mm;

   while (klen > 0)				/* always true ... */
      {
      tframe[0] = '#';
      iav = 1;
      for (nr=mm+1; nr<klen; nr++)
         {
         for (nj=0; nj<9; nj++)
            {
            if (inname[nr] == limc[nj])
               {
               tframe[iav] = '\0';
               goto clean_it;
               }
            }
         tframe[iav++] = inname[nr];
         }

     clean_it:				/* due to `#abc' => xframe is set */ 
      (void) CGN_singleframe(tframe,type,xframe);
      (void) strcpy(&twork[kk],xframe);
      iav = (int) strlen(twork);
      (void) strcpy(&twork[iav],&inname[nr]);

      mm = CGN_INDEXC(&inname[nr],'#');
      if (mm < 0) 
         {
         (void) strcpy(outname,twork);
         return(1);		/* all done */
         }

      mm += nr;
      kk = CGN_INDEXC(twork,'#');       /* '#' must also be in `twork' */
      }
   return (1);
   }

else
   {
   (void) strcpy(outname,inname);
   return (0);
   }
}
/*

*/

/* ++++++++++++++++++++++++++++++++++++++++++++++++++

.LANGUAGE: C

.AUTHOR: K.Banse

.IDENTIFICATION
  function CGN_DSCUPD  			version 1.00	880127
  K. Banse    				ESO - Garching
  1.10	    901107	1.20	910617		2.00	920225

.KEYWORDS
  descriptors, copy

.PURPOSE
  a) copy all non-standard descriptors from one frame to another
  b) append line(2) to descr. HISTORY
     if parameter HISTRY != ' '  we use HISTRY
     else we read key HISTORY + append all Pi (MIDAS parameters)

.ALGORITHM
  a) use STDCOP with option 4 or 5 to do the job
  b) if HISTORY_UPDATE == 1, we do not write HISTORY line(s)
 
.INPUT
  use as  stat = CGN_DSCUPD(inno,outno,history)

  inno:  	I*4	 	input frame no.
  outno:  	I*4	 	result frame no.
  history: 	char. exp. 	current addition for descr. HISTORY
    				if blank, get HISTORY from keyword HISTORY
					  and keys P1, P2, ...
  outpt par:
.RETURNS
  always status = 0 for backward compatibility reasons

.VERSIONS
  1.00  	adapted from DSCUPDX (version 1.30)
  1.10  	get contents of Pi explicitely
  2.00  	converted to C
  --------------------------------------------------------------------  */

int CGN_DSCUPD(inno,outno,history)

int   inno,outno;

char       *history;

{
int   flag, iav, ec, el, ed, lzero, lone, nl;
int   unit, stat, n, klen, mm;
int   bytelm, noelm; 
register int  nr;

char   cbuf[100], work[164];
static char  *par[] = {"P1","P2","P3","P4","P5","P6","P7","P8"};

  
n = 0;
 

/*  if frames not equal, we copy first all or just HISTORY descr.  */

if (inno != outno) 
   {
   stat = SCKRDI("AUX_MODE",4,1,&iav,&flag,&unit,&nl);
   MID_DRESET();
   if (flag == 1) 
      stat = SCDCOP(inno,outno,5," ");
   else
      stat = SCDCOP(inno,outno,4,"HISTORY");
   MID_DRESET();
   }


/*   if descriptor "HISTORY_UPDA" exists and is = 0,
     leave descr. HISTORY untouched                       */
  
SCECNT("GET",&ec,&el,&ed);
lone = 1; lzero = 0;
SCECNT("PUT",&lone,&lzero,&lzero);
stat = SCDRDI(outno,"HISTORY_UPDA",1,1,&iav,&flag,&unit,&nl);
SCECNT("PUT",&ec,&el,&ed);

if ((stat == ERR_NORMAL) && (flag == 0)) return (0);

/* o.k. we want to update the HISTORY descr:
   look for existing descr. HISTORY, and check if multiple of 80 chars.  */

(void) SCDFND(outno,"HISTORY",work,&noelm,&bytelm);
if (work[0] == 'C')
   {
   n = noelm*bytelm;				/* curent size */
   mm = n / 80;
   iav = mm * 80;
   if (iav < n)				/* force multiple of 80 chars. */
      {
      klen = ((mm+1) * 80) - n;
      memset((void *)work,32,(size_t)klen);
      (void) SCDWRC(outno,"HISTORY",1,work,-1,klen,&unit);
      }
   }

  
/*  history str. is either given as parameter (history != ' ')
    or taken from keyword HISTORY and Pi                         */

if (*history != ' ') 
   {
   klen = (int) strlen(history);
   if (klen > 160) klen = 160;			/* max. 160 chars. */
   (void) strncpy(work,history,klen);
   }
else
   {
   (void) SCKGETC("HISTORY",1,80,&klen,work);
   (void) SCKRDI("PCOUNT",1,1,&iav,&mm,&unit,&nl);
   for (nr=0; nr<mm; nr++)			    /* append all parameters */
      {
      (void) SCKGETC(par[nr],1,80,&iav,cbuf);
      work[klen++] = ' ';
      n = klen;				/* `n' follows `klen' */
      klen += iav;
      if (klen < 160) 
         (void) strcpy(&work[n],cbuf);
      else
         {
         klen -= iav;
         break;
         }
      }
   }
 
if (klen < 1)
   return klen;				/* tell that there is a problem... */
else if (klen <= 80)
   n = 80 - klen;
else if (klen <= 160)
   n = 160 - klen;
if (n > 0)
   {
   memset(&work[klen],32,(size_t)n);
   klen += n;				/*   -> 80 or 160   */
   }

work[klen] = '\0';
(void) SCDWRC(outno,"HISTORY",1,work,-1,klen,&unit);

return (0);
}
/*

*/

void CGN_LOGNAM(infile,outfile,maxout)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
 this function translates a filename of the form LOGNAM:file
 to the physical name
.RETURN nothing
------------------------------------------------------------ */

char  *infile;		/* IN: input file name       */
char  *outfile;		/* OUT: result file name     */
int   maxout;		/* IN: max length of outfile */


{
int  m, k, jcolo;
register int  nr;

char tempa[128];
register char  cc;




/* we're looking for something like:	"SYMBOL:name" */

jcolo = -1;
for (nr=0; ; nr++)
   {
   cc = infile[nr];
   if ((cc == ' ') || (cc == '\0'))	/* also cut off trailing blanks */
      break;
   else if (cc == ':')		/* the ":" is fixed char. for all systems...*/
      {
      jcolo = nr + 1;
      if (nr > 127)			/* we screwed up buf `tempa'!!! */
         {
         outfile[0] = '\0';		/* caller will find out soon ... */
         return;
         }
      tempa[nr] = '\0';
      goto symbol_found;	/* SYMBOL:  -> max 60 chars */
      }

   tempa[nr] = cc;		/* already copy to work buffer */
   }


/* no "SYMBOL:" found */

if (nr >= maxout) nr= maxout - 1;   		/* avoid buffer overflow */
(void) memcpy(outfile,infile,(size_t)nr);
outfile[nr] = '\0';
return;
   

symbol_found:
m = OSY_TRANSLA(tempa,outfile,maxout);
if (m >= maxout)				/* new name too long */
   {
   m = maxout - 1;				/* so keep orig name */
   (void) memcpy(outfile,infile,(size_t)m);
   outfile[m] = '\0';
   return;
   }


if (m < 1) 				/* No translation. */
   {
   maxout --;
   for (nr=0; nr <maxout ; nr++)
      {					/* Copy input file including `:' */
      cc = infile[nr];
      if ((cc == ' ') || (cc == '\0'))
         {				/* cut off trailing blanks */
         outfile[nr] = '\0';
         return;
         }
      outfile[nr] = cc;
      }
   outfile[maxout] = '\0';
   return;                              /* we're already done... */
   }


/* OK, we have a translated symbol and m < maxout, so paste all together */

#if vms
if (outfile[m-1] != FSY_DISKEND)
   {
   if (outfile[m-1] != FSY_DIREND) outfile[m++] = FSY_DIREND;
   }
#else

if (outfile[m-1] != FSY_DIREND) outfile[m++] = FSY_DIREND;
#endif


for (nr=jcolo; ; nr++)
   {
   cc = infile[nr];
   if ((cc == ' ') || (cc == '\0')) break;
   }

k = nr - jcolo + 1;
nr = maxout - m;
if (k > nr)				/* final result doesn't fit! */
   {
   nr --;
   (void) memcpy(&outfile[m],&infile[jcolo],(size_t)nr);
   outfile[maxout-1] = '\0';
   }
else                            /* no blanks before end of string  */
   (void) memcpy(&outfile[m],&infile[jcolo],(size_t)k);

}

