/* ++++++++++++++++++++++++++++++++++++++++++++++++++++
.COPYRIGHT	(c) 2010-2011 European Southern Observatory
.AUTHOR	K. Banse ESO/SDD
.KEYWODS	image, 3d table, vector columns
.PURPOSE	Copy image(s) into a vector column of a 3d table.
.VERSION
 100826		creation

 111205		last modif
------------------------------------------------------ */

#include	<stdlib.h>
#include	<stdio.h>
#include	"midas_def.h"


#define MAXDIM  2


int main()

{
char	fname[82], tname[82], colref[26];
char	cunit[49], ident[74], format_str[24];
char    *pntr;

int	*kpntr, imno, tno;
int	row_no, upda, naxis, iva, df, n, m;
int	felem, noelem, nr, na, ncol;
int     allrow, allcol, lastrow;
int	npix[MAXDIM], ibuf[5];

double  *dpntr, start[MAXDIM], step[MAXDIM];

float   *fpntr;



/*
COPY/IMT3  image  table  colref,rowno  1st-el,noelem  update/alloc-rows
*/


(void) SCSPRO("BDF3TBL");
(void) SCKGETC("IN_A", 1, 80, &iva, fname);	/* input image */


/* get column ref. and starting row no. */

row_no = 1;					/* the default values */
(void) strcpy(colref,":Values");
(void) SCKGETC("INPUTC", 1, 24, &iva, ident);

if (ident[0] != '*')
   {
   n = CGN_INDEXC(ident,',');
   if (n < 0)
      {					/* input was: colref */
      (void) strcpy(colref,ident);
      }
   else
      {
      ident[n++] = '\0';
      if (n == 1)			/* input was: ,row_no. */
         {
         ;
         }
      else
         {
         (void) strcpy(colref,ident);
         }
      if (ident[n] == '@') n++;		/* @row => row */

      if (ident[n] != '\0') 
         {
         m = -1;
         m = atoi(ident+n); 
         if (m != -1) 
            row_no = m;
         else
            SCETER(6,"invalid row no. entered");
         }
      }
   }

if (row_no < 1) 
   SCETER(6,"invalid row no. entered");


/* read name of output table */

(void) SCKGETC("OUT_A",1,64,&iva,tname);

      
/* all else integer data (I*1, I*2, I*4) are treated as I*4 
   get data type of input image via SCFINF */

(void) SCFINF(fname,4,ibuf);
df = ibuf[1];			/* data format in 2nd element of ibuf */
if ((df == D_R8_FORMAT) || (df == D_R4_FORMAT))
   (void) strcpy(format_str,"F12.5");
else
   {
   (void) strcpy(format_str,"I10");
   df = D_I4_FORMAT;
   }

(void) SCIGET(fname,df,F_I_MODE,F_IMA_TYPE,MAXDIM,
              &naxis,npix,start,step,ident,cunit,&pntr,&imno);


/* determine the no. of rows to write */

if (naxis == 1)
   nr = 1;			/* single line */
else
   nr = npix[1];		/* no of lines in 2dim image */


/* get 1st element and no. of elements to write in array column */

(void) SCKGETC("INPUTC",31, 20, &iva, ident);	/* opt. 1st_element,noelem */

felem = 1;				/* the default values */
noelem = npix[0];
if (ident[0] != '*')
   {
   n = CGN_INDEXC(ident,',');
   if (n < 0)
      {					/* input was: 1st_elem */
      m = -1;
      m = atoi(ident); 
      if (m != -1) 
         felem = m;
      else
         SCETER(7,"invalid 1st element entered");
      }      
   else
      {
      ident[n++] = '\0'; 	/* n is incremented after op... */
      if (n == 1)			/* input was: ,noelem. */
         {
         ;
         }
      else				/* get 1st element. */
         {
         m = -1;
         m = atoi(ident); 
         if (m != -1) 
            felem = m;
         else
            SCETER(7,"invalid 1st element entered");
         }

      if (ident[n] != '\0') 	/* get noelem */
         {
         m = -1;
         m = atoi(ident+n); 
         if (m != -1) 
            noelem = m;
         else
            SCETER(8,"invalid no. of elements entered");
         }
      }
   }

if ((felem < 1) || (felem > npix[0]))
   SCETER(7,"invalid 1st element entered");
if (noelem < 1) 
   SCETER(8,"invalid no. of elements entered");

m = npix[0] - felem + 1;		/* = max. possible no. of elements */
if (noelem > m) noelem = m;


(void) SCKGETC("INPUTC", 26, 1, &iva, ident);	/* update or alloc rows */
upda = 0;
allrow = 1;
if (ident[0] == 'X')
   {				/* allocate more rows for new table */
   int  knull=-1;
   SCKRDI("INPUTI",1,1,&iva,&allrow,&iva,&knull);
   if (allrow < 1) 
      SCETER(9,"invalid no_rows_to_allocate entered");
   }
else if (ident[0] == 'U') 
   upda = 1;			/* table for updating stuff exists */

/*
printf("colref = %s, row no = %d, nr = %d\n",colref,row_no,nr);
printf("upda = %d\n",upda);
*/


/* and create or open this table */

na = 1; 				/* 1 new column */
lastrow = row_no + nr - 1;		/* last row to fill */
if (lastrow < allrow) lastrow = allrow;

if (upda == 0)
   {
   (void) TCTINI(tname, F_TRANS, F_O_MODE, na, lastrow, &tno);
   (void) TCCINI(tno,df,noelem,format_str,"intensity",colref,&ncol);
   }
else
   {
   (void) TCTOPN(tname,F_IO_MODE,&tno);
   (void) TCIGET(tno,&n,&n,&n,&allcol,&allrow);
   if (allrow < lastrow)
      {
      m = sprintf(tname,"last row (%d) to fill exceeds allocated %d rows",
                     lastrow,allrow);
      nr = allrow - row_no + 1;
      if (nr < 1)
         {
         SCTPUT(tname);
         SCETER(33,"no row can be be written");
         }
      else
         {
         (void) sprintf(tname+m,", only %d rows will be written",nr);
         SCTPUT(tname);
         }
      }
   (void) TCCSER(tno,colref,&ncol);
   if (ncol < 1)
      {			/* create new column */
      (void) TCCINI(tno,df,noelem,format_str,"intensity",colref,&ncol);
      }
   else			/* column found - check data type */
      {
      (void) TCFGET(tno,ncol,ident,&n,&iva);
      if (iva != df)		/* column, image data type don't match */
         {
         (void) sprintf(tname,"image and colum type do not match...");
         (void) SCTPUT(tname);
         (void) sprintf(tname,"we reopen image with column data type ");
         (void) SCTPUT(tname);
         df = iva;
         SCFCLO(imno);
         (void) SCIGET(fname,df,F_I_MODE,F_IMA_TYPE,MAXDIM,
                       &naxis,npix,start,step,ident,cunit,&pntr,&imno);
         }
      }
   }

/*
(void) TCFGET(tno,ncol,ident,&n,&iva);
printf("column #%d -> form = %s, len = %d, type = %d\n",ncol,ident,n,iva);
(void) TCBGET(tno,ncol,&iva,&m,&n);
printf("column #%d -> type = %d, items = %d, bytes = %d\n",ncol,iva,m,n);
*/


if (df == D_R4_FORMAT)
   {
   kpntr = (int *) 0;
   fpntr = (float *) pntr;
   dpntr = (double *) 0;
   }
else if (df == D_R8_FORMAT)
   {
   kpntr = (int *) 0;
   fpntr = (float *) 0;
   dpntr = (double *) pntr;
   }
else 				/* only D_I4_FORMAT left */
   {
   kpntr = (int *) pntr;
   fpntr = (float *) 0;
   dpntr = (double *) 0;
   }

m = row_no;			/* starting row no. */
iva = 1;

if (nr == 1)			/* fill only 1 row */
   {
   if (df == D_R4_FORMAT)
      {
      (void) TCAWRR(tno,m,ncol,felem,noelem,fpntr);
      }
   else if (df == D_R8_FORMAT)
      {
      (void) TCAWRD(tno,m,ncol,felem,noelem,dpntr);
      }
   else
      {
      (void) TCAWRI(tno,m,ncol,felem,noelem,kpntr);
      }
   (void) TCSPUT(tno,m,&iva);
   }
else				/* fill nr rows (nr may also be just 1) */
   {
   if (df == D_R4_FORMAT)
      {
      for (n=0; n<nr; n++)
         {
         (void) TCAWRR(tno,m,ncol,felem,noelem,fpntr);
         (void) TCSPUT(tno,m,&iva);
         fpntr += npix[0];
         m++;
         }
      }
   else if (df == D_R8_FORMAT)
      {
      for (n=0; n<nr; n++)
         {
         (void) TCAWRD(tno,m,ncol,felem,noelem,dpntr);
         (void) TCSPUT(tno,m,&iva);
         dpntr += npix[0];
         m++;
         }
      }
   else 
      {
      for (n=0; n<nr; n++)
         {
         (void) TCAWRI(tno,m,ncol,felem,noelem,kpntr);
         (void) TCSPUT(tno,m,&iva);
         kpntr += npix[0];
         m++;
         }
      }
   }


/* append keyword HISTORY to descr. HISTORY of table */

(void) SCKGETC("HISTORY",1, 80, &iva, tname);	
(void) SCDWRC(tno,"HISTORY",1,tname,-1,80,&iva);
TCTCLO(tno);

SCSEPI();
exit(0);
}
