/*===========================================================================
  Copyright (C) 1991-2009 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
===========================================================================*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* .IDENT       keyset.c                                       */
/* .AUTHOR      Pascal Ballester,  ESO - Garching                */
/* .KEYWORDS    Session Manager                                  */
/* .PURPOSE     Parse set/.. line and initialize keywords        */

/* .VERSION     1.0    Creation    15-JAN-1991  PB               */

/*  090710		last modif				 */

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

#include <tbldef.h>
#include <midas_def.h>
#include <str.h>

#include <stdio.h>
#include <string.h>


extern int strindex();

int  findkey(), writekey();


int             tid, nrow, colnam, coltyp;

int main()
{

   char            file[61], record[80], keynam[80];
   char            value[135], fullnam[61], *line, linorg[235];
   int             actvals, null, kunit;
   int             found;
   int             ntoken, car, mode, pos, cnt, inter;
   int             fnb; /* First non-blank character */
   char            separ;
   int             ncol, nsort, allcol, allrow;

   SCSPRO("keyset");

   SCKRDI("INPUTI", 1, 1, &actvals, &ntoken, &kunit, &null);
   SCKGETC("IN_A", 1, 60, &actvals, file);

   separ = ' ';

   if (ntoken > 0 ) {

   SCKGETC("LINE", 1,132, &actvals, linorg);

   TCTOPN(file,F_I_MODE,&tid);
   TCIGET(tid, &ncol, &nrow, &nsort, &allcol, &allrow);
   TCCSER(tid,"KEY",&colnam);
   TCCSER(tid,"TYPE",&coltyp);

   /* 0. Counts the real number of tokens */

   ntoken = 0;   /* number of tokens */
   cnt    = 0;
   inter  = 1;   /* 0 = in a token, 1 = between tokens */

   /* Go to the first non-blank character */
   while (linorg[cnt] == ' ' && linorg[cnt] != '\0')   cnt++; 

   line = (char *) (linorg+cnt);
   fnb = cnt  = 0;

   if (cnt < (int)(strlen(line)-1)) {

   while (line[cnt] != '\0') {
          if (line[cnt] != ' ' && inter != 0) {inter=0; ntoken++;}
          if (line[cnt] == ' ' && inter == 0) {inter = 1;}
          cnt++;
	}
 }

   ntoken--;  /* First token is the command itself */

   /* 1. Parse command line to extract all tokens of syntax <name>=<value> */
   /*       The parser is controlled by the variable mode, which value can be:
            mode = 0 : The parser is currently reading a keyword name. All
                       blanks in the keyword name are removed. This
                       mode will be stopped by a separation character (=).
            mode = 1 : A separation character was found and the parser removes
                       all blanks until it finds either a double quote (")
                       or any other character than blank and double quote 
                       and then switches to mode=2
            mode = 2 : The parser is currently reading a value. Depending on
                       the character which started the mode (double quote or
                       any other), the separator will be a double quote or
                       a blank (variable separ). The current mode is stopped at
                       the separator or a character null (\0). The value is 
                       assigned and the parser returns to mode=0.
   */

   mode   = 0;
   pos    = 0;

   for (car=(int)strindex((line+fnb)," ")+1; car<=(int)strlen(line); car++) {  
       switch(mode) {

       case 0 : {
                if (line[car] != ' ') {
                    if (line[car] == '=') 
                         {keynam[pos]='\0'; pos=0; mode=1;}
                    else keynam[pos++] = line[car];
		  }
                break;
		}

       case 1 : {
                if (line[car] != ' ') {
                    mode = 2;
                    if (line[car] == '"') separ='"';
                    else {separ = ' '; value[pos++] = line[car];}
		  }
                break;
		}

       case 2 : {
                if (line[car] == separ || line[car] == '\0') {
                         value[pos] = '\0';
                         pos=0;
                         mode=0;
                         if (findkey(keynam, record, fullnam) == 1)
                                    writekey(fullnam, value);
                         break;
			 }

                value[pos++] = line[car];
                break;
		}

		} /* Matches switch(mode) */

 } /* Matches for (car= ... */

 }  /* Matches if ntoken > 0 ... */

 else {

   SCKGETC("IN_B", 1, 60, &actvals, keynam);
   found = findkey(keynam, record, fullnam);
   if (found == 1)
       SCKWRC("OUT_A", 1, fullnam, 1, 60, &kunit);
   SCKWRI("OUTPUTI",&found,1,1,&kunit);

 }

   SCSEPI();
return 0;
}


int findkey (keynam, record, fullnam)

/* Associates the name of the keyword (keynam) to its complete */
/* definition (stored in file) */

char     *keynam, *record, *fullnam;

{

   int    found, matched;
   int    reclen, index, knull;
   char   line[80], match[80], type[20];

 
   found  = 0;
   matched = 0;

   for (reclen=1; reclen<=nrow; reclen++) {

       TCERDC(tid, reclen, colnam, line, &knull);
       strcat(line,"/");
       TCERDC(tid, reclen, coltyp, type, &knull);
       strcat(line,type);

       if (stuindex(line,keynam) == 0) { /* Case unsensitive comparison */
           found++;
           strcpy(record,line);
           index = strindex(record,"/");
           if (strlen(keynam) == index) {
               matched = 1;
               strcpy(match,line);
	     }
/*   printf("found %d matched %d keynam %s line %s index %d\n",found,  */
/*   matched,keynam,line,index);   */
	 }

     }

   switch (found) {

   case(0) :  {
      printf("Could not find keyword  %s. Ignored.\n",keynam);
      break;
    }

   case(1) : {
         strcpy(fullnam,record);
         index = strindex(fullnam,"/");
         fullnam[index] = '\0';
         matched = 1;
         break;
    }

   default : {

      switch (matched) {

      case(1) : {
         strcpy(record,match);
         strcpy(fullnam,record);
         index = strindex(fullnam,"/");
         fullnam[index] = '\0';
         break;
       }

      default : {
         printf("Ambiguous : %s. Ignored. \n",keynam);
         break;
        }
      } /* Matches switch(matched) */

    break;
    } /* Matches default: */

 }  /* Matches switch(found) */
   return(matched);
}



int writekey (fullnam, value)

char     *value, *fullnam;

{
     int       pos, str, valid[50], errflag;
     char      ctype, eos, c, string[80];
     int       noelm, ncoma, bytelem;
     int       kunit;
     double    buffer[50], buffd;
     int       buffi, elm;
     float     buffr;

     SCKFND(fullnam, &ctype, &noelm, &bytelem);
     ctype = toupper(ctype);

     if (ctype != 'C') {

        /* Counts number of comas in string value: ncoma is nb. of comas+1 */
        ncoma = 1;
        pos   = 0;
        while (value[pos] != '\0')
              if (value[pos++] == ',')   ncoma++;

        /* noelm becomes the minimum of noelm and ncoma */
        noelm = (noelm < ncoma) ? noelm : ncoma;

        /* Copy noelm  elements in a double array */
        pos = 0;
        for (elm=0; elm<noelm; elm++) {

            if (elm == (noelm-1))  eos = '\0';  /* End Of String */
            else                   eos = ',';
            str = 0;
            while (value[pos] != eos) {
              c = value[pos++];
              errflag = 1;
              /* Only accepted signs are 0-9 and +/- and . and e and E */
              if (c >= '0' && c <= '9') errflag = 0;
              if (c == '+' || c == '-') errflag = 0;
              if (c == 'e' || c == 'E') errflag = 0;
              if (c == '.' )            errflag = 0;
              if (errflag == 0) 
                   string[str++] = c;
	    }
               string[str] = '\0';
               pos++;
            if (str != 0) {
               sscanf(string, "%lf", &buffer[elm]);
               valid[elm] = 1;
	     }
            else
               valid[elm] = 0;
	  } /* Matches for (elm=0 ... */
      } /* Matches if (ctype != 'C') .. */

     switch (ctype) {

       case('C') : {
           SCKWRC(fullnam, bytelem, value, 1, noelm, &kunit);
           break;
	 }

       case('I') : {
           for (elm=1; elm<=noelm; elm++) {
               if (valid[elm-1] != 0) {
                  buffi = (int) buffer[elm-1];
                  SCKWRI(fullnam, &buffi, elm, 1, &kunit);
		}
	     }
           break;
	 }

       case('R') : {
           for (elm=1; elm<=noelm; elm++) {
               if (valid[elm-1] != 0) {
                 buffr = (float) buffer[elm-1];
                 SCKWRR(fullnam, &buffr, elm, 1, &kunit);
	       }
	     }
           break;
	 }

       case('D') : {
           for (elm=1; elm<=noelm; elm++) {
               if (valid[elm-1] != 0) {
                 buffd = buffer[elm-1];
                 SCKWRD(fullnam, &buffd, elm, 1, &kunit);
	       }
	     }
           break;
	 }
     } /* Matches switch(ctype)  */

     return(noelm);
}






