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

.VERSION

 100907		last modif
===========================================================================*/

#include <atype.h>
#include <tbldef.h>
#include <tblsys.h>
#include <tblerr.h>
#include <midas_def.h>
#include <macrogen.h>
#include <proto_tbl.h>

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


#define BUFM 8

extern int nochar,otype,exist,what[BUFM];
extern int strloc(), stucmp(), strcomp();



int stncomp(s1,n1,s2,n2)
    char *s1;  /* IN: address of first string  */
    char *s2;  /* IN: address of 2nd string    */
    int n1,n2; 

{
          register char *p, *q;
	  int i,j;


  for (p=s1, q=s2, i=0, j=0;(*p == *q)&&(i<n1)&&(j<n2); p++, q++, i++, j++)
          {
	  if (!(*p))      break;
          if ((i==n1-1) && (j==n2-1)) return(0);
	  }
  return(*p - *q);
}


int logchar(op,x,cdata,pat,nconst,ibuf,nvar)
int op;
double *x[BUFM] ;
int nconst[BUFM];
char *pat, *cdata[BUFM];
int ibuf[7],nvar;

{
char line[256];
int i, j, ni, nj;
int res,cas,nrow;

nrow = ibuf[2];
if (nvar == 1) {           /*two column comparison */
   ibuf[3] = ibuf[3]-1;
   for (i=0; i<nrow; i++) {
     ni = i * nconst[ibuf[6]-1];
     nj = i * nconst[ibuf[6]];
     res = stncomp(cdata[ibuf[6]-1]+ni,nconst[ibuf[6]-1],
                   cdata[ibuf[6]]+nj,nconst[ibuf[6]]);
     if (op == 4 ) {
        if (res == 0) *(x[ibuf[3]]+i) = 1; else *(x[ibuf[3]]+i) = 0 ;
     }
     else {
        if (res == 0) *(x[ibuf[3]]+i) = 0; else *(x[ibuf[3]]+i) = 1 ;
        }
   }
}
else {
  if (*pat == '~'){
   pat++;
   for (j=0; pat[j]; j++) pat[j] = toupper(pat[j]);
   cas = 1;
   }
  else cas = 0;
  switch (op) {

   case 4:   /*       .EQ.     */
     if (!pat[strloc(pat,'*')] && !pat[strloc(pat,'[')]
	  && !pat[strloc(pat,'?')]) {
     for (i = 0; i<nrow; i++) { 
	 ni = i * nconst[ibuf[6]];
	 for (j=0; j<nconst[ibuf[6]]; j++) 
		line[j] = *(cdata[ibuf[6]] + j + ni);
	 line[j] = '\0';
         if (cas == 1) res = stucmp(pat,line);
         else res =  strcomp(line,pat);
         if (res == 0) *(x[ibuf[3]]+i) = 1; else *(x[ibuf[3]]+i) = 0 ;
         }
     }
     else {
     for (i = 0; i<nrow; i++) { 
	 ni = i * nconst[ibuf[6]];
	 for (j=0; j<nconst[ibuf[6]]; j++) 
		line[j] = *(cdata[ibuf[6]] +j + ni);
	 line[j] = '\0';
         if (cas == 1) for (j=0; line[j]; j++) line[j] = toupper(line[j]);
         res =  amatch(line,pat);
         if (res == 1) *(x[ibuf[3]]+i) = 0; else *(x[ibuf[3]]+i) = 1 ;
         }
     }
     break;
   case 5: /*    .NE.          */
     if (!pat[strloc(pat,'*')] && !pat[strloc(pat,'[')]
	  && !pat[strloc(pat,'?')]) {
     for (i = 0; i<nrow; i++) { 
	 ni = i * nconst[ibuf[6]];
	 for (j=0; j<nconst[ibuf[6]]; j++) 
		line[j] = *(cdata[ibuf[6]] +j + ni);
	 line[j] = '\0';
         if (cas == 1) res = stucmp(pat,line);
         else res =  strcomp(line,pat);
         if (res == 0) *(x[ibuf[3]]+i) = 0; else *(x[ibuf[3]]+i) = 1 ;
         }
     }
     else {
     for (i = 0; i<nrow; i++) { 
	 ni = i * nconst[ibuf[6]];
	 for (j=0; j<nconst[ibuf[6]]; j++) 
		line[j] = *(cdata[ibuf[6]] +j + ni);
	 line[j] = '\0';
         if (cas == 1) for (j=0; line[j]; j++) line[j] = toupper(line[j]);
         res =  amatch(line,pat);
         if (res == 1) *(x[ibuf[3]]+i) = 1; else *(x[ibuf[3]]+i) = 0 ;
         }
     }
 }
}

return 0;
}

int charfun(fu,cdata,nconst,string,ibuf)
    int fu;
    int ibuf[7];
    int nconst[BUFM];
    char *cdata[BUFM], *string[BUFM] ;
{
int i, j, k, nchar, nchar1, nchar2, items ,act, ni;
int nchar1b;
int imnoc[BUFM];

char name[8],text[80];



nchar1 = nchar2 = nchar = 0;
items = 0;

   if (nconst[ibuf[6]] == 0) {
       sprintf(text,"Operation only allowed on character columns");
       SCTPUT(text);
       SCSEPI();
       }
   switch (fu) {
	 case 19:   /*to  lower */
	   nchar = nconst[ibuf[6]] * ibuf[2];
 	   for (i=0; i<nchar ; i++) 
		if (*(cdata[ibuf[6]]+i) != '\0') 
		    *(cdata[ibuf[6]]+i) = tolower(*(cdata[ibuf[6]]+i));
           break;
         case 20:  /* to upper */
	   nchar = nconst[ibuf[6]] * ibuf[2];
 	   for (i=0; i<nchar ; i++) 
		if (*(cdata[ibuf[6]]+i) != '\0') 
		    *(cdata[ibuf[6]]+i) = toupper(*(cdata[ibuf[6]]+i));
           break;
         case 21: /* concat*/
	   if (ibuf[6] == 0 && ibuf[4] == -1){
               sprintf(text,"Operation only allowed on character columns");
               SCTPUT(text);
               SCSEPI();
             }
	   if (ibuf[6] == 1) { /*concatenation of 2 columns */ 
           if (nconst[ibuf[6]-1] == 0) {
               sprintf(text,"Operation only allowed on character columns");
               SCTPUT(text);
               SCSEPI();
             }
             ibuf[6] = ibuf[6]+1;
             what[ibuf[6]+ibuf[4]+1] = 1;
	     if (!cdata[ibuf[6]]) {
             sprintf(name,"TEMPC%02d",ibuf[6]);
	     nchar1 = nconst[ibuf[6]-2];
	     nchar2 = nconst[ibuf[6]-1];
	     nchar = nchar1+nchar2;
	     nconst[ibuf[6]] = nchar;
	     items = (nconst[ibuf[6]-1] + nconst[ibuf[6]-2]) * ibuf[2];
             SCFCRE(name,D_I1_FORMAT,F_X_MODE,F_IMA_TYPE,items,&imnoc[ibuf[6]]);
             SCFMAP(imnoc[ibuf[6]],F_X_MODE,1,items,&act,&cdata[ibuf[6]]);
	     }
	     for (i=0, k=0; i<items; i+=nchar,k++) {
	         nchar1b = 0;
                 for (j=0; j<nchar1; j++) {
		 if (*(cdata[ibuf[6]-2]+k * nchar1+j) != '\0') { 
		       *(cdata[ibuf[6]]+i+j)  = *(cdata[ibuf[6]-2]+k *
		       nchar1+j);
		       nchar1b = nchar1b+1; 
                       }
		 else break; 
                 } 
		 for (j=0; j <nchar2; j++) 
		    *(cdata[ibuf[6]]+i+j+nchar1b) = *(cdata[ibuf[6]-1]+
		    k * nchar2 +j);
                 
	     }
	     *(cdata[ibuf[6]]+items) = '\0' ;
	   }
	   else { /* concatenation of 1 column and 1 string */
             ibuf[6] = ibuf[6]+1;
             what[ibuf[6]+ibuf[4]+1] = 1;
	     if (!cdata[ibuf[6]]) {
             sprintf(name,"TEMPC%02d",ibuf[6]);
	     nchar1 = strlen(string[ibuf[4]]);
	     nchar2 = nconst[ibuf[6]-1];
	     nchar = nchar1+nchar2;
	     nconst[ibuf[6]] = nchar;
	     items = nchar * ibuf[2];
             SCFCRE(name,D_I1_FORMAT,F_X_MODE,F_IMA_TYPE,items,&imnoc[ibuf[6]]);
             SCFMAP(imnoc[ibuf[6]],F_X_MODE,1,items+1,&act,&cdata[ibuf[6]]);
	     }
	     if (nochar == 0) {
	       for (i=0, k=0; i<items; i+=nchar,k++) {
                 for (j=0; j<nchar1; j++) 
		    *(cdata[ibuf[6]]+i+j)  =  *(string[ibuf[4]]+j);
		 
		 for (j=0; j <nchar2; j++) 
		    *(cdata[ibuf[6]]+i+j+nchar1) = *(cdata[ibuf[6]-1]+
		    k * nchar2 +j);
                 
	      }
	     }
	     else {
		nchar1 = nconst[ibuf[6]-1];
		nchar2 = strlen(string[ibuf[4]]);
	        for (i=0, k=0; i<items; i+=nchar,k++) {
		  nchar1b = 0;
	       	  for (j=0; j<nchar1; j++)
		  if (*(cdata[ibuf[6]-1]+k * nchar1+j) != '\0') { 
		    *(cdata[ibuf[6]]+i+j)  = *(cdata[ibuf[6]-1]+k *
		    nchar1+j);
		    nchar1b = nchar1b+1;
		 }
                  for (j=0; j<nchar2; j++)
		    *(cdata[ibuf[6]]+i+j+nchar1b) = *(string[ibuf[4]]+j);
                 
                }
               }
	     *(cdata[ibuf[6]]+items) = '\0' ;
	   }
	 break;
         case 22: /* collapse */
	   ibuf[6] = ibuf[6]+1;
            what[ibuf[6]+ibuf[4]+1] = 1;
	   if (!cdata[ibuf[6]]) {
	     items = nconst[ibuf[6]-1] * ibuf[2];
	     nchar = nconst[ibuf[6]-1];
	     nconst[ibuf[6]] = nconst[ibuf[6]-1];
             sprintf(name,"TEMPC%02d",ibuf[6]);
             SCFCRE(name,D_I1_FORMAT,F_X_MODE,F_IMA_TYPE,items,&imnoc[ibuf[6]]);
             SCFMAP(imnoc[ibuf[6]],F_X_MODE,1,items,&act,&cdata[ibuf[6]]);
	   }
	   for (i=0; i<ibuf[2]; i++) {
	      k = 0;
	      ni = i * nchar;
	      for (j=0; j<nchar; j++)
	      if (*(cdata[ibuf[6]-1]+j+ni ) != ' ') {
		   *(cdata[ibuf[6]]+k+ni) = *(cdata[ibuf[6]-1]+j+ni);
	           k = k+1;
		}
	      for (j=0; j<k;  j++) 
		  *(cdata[ibuf[6]-1]+ni+j) = *(cdata[ibuf[6]]+ni+j);
	      for (j=k; j<nchar; j++)
	          *(cdata[ibuf[6]-1]+ni+j) = '\0';
	   }
	   SCFUNM(imnoc[ibuf[6]]);
	   SCFCLO(imnoc[ibuf[6]]);
	   cdata[ibuf[6]] = (char *)0;
	   ibuf[6] = ibuf[6]-1;
           break;
        }
return 0;
}



int convchar(cdata,data,nconst,ibuf)
char *cdata[BUFM];
char *data[BUFM];
int nconst[BUFM];
int ibuf[7];

{
int items, dummy, nchar, imnoc[BUFM];
int dtype, nbytes, nbytes1;
int i,act;

char form[1+TBL_FORLEN];
char name[60];


ibuf[6] = ibuf[6]+1;
if (exist == -1) otype = D_C_FORMAT;

TCFGET(ibuf[0],ibuf[1],form,&nchar,&dummy);
nconst[ibuf[6]] = nchar;
if (!cdata[ibuf[6]]) 
   {
   sprintf(name,"TMPC%02d",ibuf[6]);
   items = nchar * ibuf[2];
   SCFCRE(name,D_I1_FORMAT,F_X_MODE,F_IMA_TYPE,items,&imnoc[ibuf[6]]);
   SCFMAP(imnoc[ibuf[6]],F_X_MODE,1,items,&act,&cdata[ibuf[6]]);
   }

TBL_TYPCHK(D_R8_FORMAT,1,&dtype);
for (i=0; i<ibuf[2]; i++) 
   {
   nbytes = 8 * i;
   nbytes1 = nchar * i;
   TBL_ed(cdata[ibuf[6]]+nbytes1,form,dtype,data[ibuf[3]]+nbytes);
   }
return 0;
}

