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

#include <stdio.h>
#include <stdlib.h>
#include <tbldef.h>
#include <tblsys.h>
#include <tblerr.h>
#include <midas_def.h>
#include <computer.h>
#include <macrogen.h>

#define COLMAX 256

int tbl_readplaneyz( tid, colref, index, items, flag, direction, maxrow,
                     outitem, outrow, rval, null )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE Reads an YZ plane from a 3-D table floating points numbers
         The routine returns an array of floating point values.
         Direction specifies the way the plane is read:
         0: the plane is read column by column (y by y)
         1: the plane is read z by z
         The routine checks the existence of the columns and reads only the
         selected rows.
         flag specifies the way NULL values are treated:
         if flag = 0 tthe program skips null values
         if flag = 1 the program doesn't care about NULL values
.RETURNS status
---------------------------------------------------------------*/
    int  tid;       /* IN : table id              */
    char *colref;   /* IN : column reference      */
    int  index;     /* IN : index number          */ 
    int  items;     /* IN : how many elements     */
    int  flag;      /* IN : flag for NULL values  */
    int  maxrow;    /* IN : max number of rows    */
    int  direction; /* IN : flag for the way the plane has to be read */
    int  *outitem;  /* OUT: actual number of items */
    int  *outrow;   /* OUT: actual number of rows */
    float *rval;    /* OUT: actual values         */
    int  *null;     /* OUT: null flag for each element */ 
{
register int i, j, k, ll, loop;
int  dummy, icol, sel, ritems, bytes, nrow, selrow,uni,nulld,nval;
char selflag[65];

(void) TCCSER(tid,colref,&icol);
if ( icol == -1 ) 
   { SCTPUT("Column not found");
     return -1;
   } 
(void) TCIGET(tid,&dummy,&nrow,&dummy,&dummy,&dummy);
(void) SCDRDI(tid,"TBLCONTR",10,1,&nval,&selrow,&uni,&nulld);
(void) SCDRDC(tid,"TSELTABL",1,1,65,&nval,selflag,&uni,&nulld);
if ( (selrow == -1) || 
     (( strncmp( selflag, "-", 1) == 0)) || 
     (nval == 0 )) selrow = nrow;
(void) TCBGET(tid,icol,&dummy,&ritems,&bytes);

if ( items == 0 ) 
   items = ritems-index+1;
else if ( ritems-index+1 < items) 
   { SCTPUT("Wrong index");
     return -1;
   }
if ( !direction )
   { k = *outitem = 0;
     for ( j=index; j < index+items; j++ )
         { i = ll = 0;
           while ( ll < maxrow && i < nrow )
                 { if (selrow < nrow) (void) TCSGET(tid,i+1,&sel);
                   else sel = 1;
                   if ( sel )
                      { (void) TCARDR(tid,i+1,icol,j,1,rval+k);
                        k++;
                        ll++;
                      }
                   i++;
                 }
           for ( loop = 0; loop < ll; loop++ ) 
               { if (  isNULLF(rval+k-1-loop) ) 
                    { if ( flag ) 
                         *(null+k-1-loop) = 1;
                      else 
                         { k = k-ll;
                           break;
                         }
                    }
                 else if ( flag ) 
                    *(null+k-1-loop) = 0;
               }
           if ( loop == ll ) (*outitem)++;
         }
     *outrow = selrow;
   }
else
   { i = ll = 0;
     while ( ll < maxrow && i < nrow )
           { if (selrow < nrow) (void) TCSGET(tid,i+1,&sel);
             else sel = 1;
             if ( sel )
                { k = ll * items ;
                  (void) TCARDR( tid,i+1,icol,index,items,rval+k );
                  for ( loop = 0; loop < items; loop++)
                      { if (  isNULLF(rval+k+loop) )
                           { if ( flag )
                                *(null+k+loop) = 1;
                             else 
                                break;
                           }
                        else if ( flag ) *(null+k+loop) = 0;
                      }
                  if ( loop == items ) ll++;
                }
             i++; 
           }
     *outrow = ll;
     *outitem = items;
   }
return ERR_NORMAL;
}

int tbl_readplanexy( tid, colref, index, maxrow, flag, direction, 
                     outrow, outcol, rval, null )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE Reads for a given Z an XY plane from a 3-D table floating 
         points numbers
         The routine returns an array of floating point values.
         Direction specifies the way the plane is read:
         0: the plane is read column by column (y by y)
         1: the plane is read row by row (x by x)
         The routine checks the existence of the columns and reads only the
         selected rows.
.RETURNS status
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    int  tid;       /* IN : table id              */
    char *colref;   /* IN : column reference      */
    int  index;     /* IN : index number          */ 
    int  maxrow;    /* IN : max number of rows    */
    int  flag;      /* IN : flag for NULL values  */
    int  direction; /* IN : flag for the way the plane has to be read */
    int  *outrow;   /* OUT: actual number of rows */
    int  *outcol;   /* OUT: actual number of columns */
    float *rval;    /* OUT: actual values         */
    int  *null;     /* OUT: null flag for each element */ 
{
register int i, j, k, ll, loop;
int  nrow, narow, ncol, dummy, selrow;
int  icol[COLMAX], sflag[COLMAX];
int  ritems[COLMAX], bytes, sel,uni,nulld,nval;
char selflag[65];

(void) TCIGET(tid,&dummy,&nrow,&dummy,&dummy,&narow);
(void) SCDRDI(tid,"TBLCONTR",10,1,&nval,&selrow,&uni,&nulld);
(void) SCDRDC(tid,"TSELTABL",1,1,65,&nval,selflag,&uni,&nulld);
if ( (selrow == -1) || (nval == 0 ) ||
     (( strncmp( selflag, "-", 1) == 0))) selrow = nrow;
(void) TCCSEL(tid,colref,COLMAX,icol,sflag,&ncol);

for ( i = 0; i < ncol; i++ ) 
    { (void) TCBGET(tid,icol[i],&dummy,&ritems[i],&bytes);
      if ( index > ritems[i] )
         { SCTPUT("Wrong index");
           return -1;
         }
    }

if ( ! direction )
   { ll = k = *outcol = 0;
     for ( j = 0; j < ncol; j++ )
         { i = ll = 0;
           while ( i < nrow && ll < maxrow )
                 { if (selrow < nrow) (void) TCSGET(tid,i+1,&sel);
                   else sel = 1;
                   if ( sel )
                      { (void) TCARDR(tid,i+1,icol[j],index,1,rval+k);
                        k++;
                        ll++;
                      }
                   i++;
                 }
           for ( loop = 0; loop < ll; loop++ )
               { if (  isNULLF(rval+k-1-loop) )
                    { if ( flag ) 
                         *(null+k-1-loop) = 1;
                      else
                         { k = k - ll;   
                           break;
                         }
                    }
                 else if (flag) 
                    *(null+k-1-loop) = 0;
               }
           if ( loop == ll ) (*outcol)++;
         }   
     *outrow = ll;
   }
else 
   { i = ll = k = *outrow = 0;
     while ( i < nrow && ll < maxrow )
           { if (selrow < nrow) (void) TCSGET(tid,i+1,&sel);
             else sel = 1;
             if ( sel )
                { for ( j = 0; j < ncol;j++ )
                      { (void) TCARDR(tid,i+1,icol[j],index,1,rval+k);
                        k++;
                      }       
                  for ( loop = 0; loop < ncol; loop++ )
                      { if (  isNULLF(rval+k-1-loop) )
                           { if ( flag ) 
                                *(null+k-1-loop) = 1;
                             else
                                { k = k - ncol;
                                  break;
                                }
                           }
                        else if ( flag )
                           *(null+k-1-loop) = 0;
                      }
                  if ( loop == ncol ) ll++;
                }
             i++; 
           }
     *outrow = ll;
     *outcol = ncol;
   }
return ERR_NORMAL;
}

int tbl_readplanexz( tid, colref, row, index, items, flag, direction,
                     outcol, outitem, rval, null )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE Reads for a given Y a  XZ plane from a 3-D table floating 
         points numbers
         The routine returns an array of floating point values.
         Direction specifies the way the plane is read:
         0: the plane is read z by z
         1: the plane is read x by x
         The routine checks the existence of the columns  .
.RETURNS status
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    int  tid;       /* IN : table id              */
    char *colref;   /* IN : column reference      */
    int  index;     /* IN : index number          */ 
    int  items;     /* IN : number of items       */
    int  row;       /* IN : row number            */
    int  flag;      /* IN : flag for NULL values  */
    int  direction; /* IN : flag for the way the plane has to be read */
    int  *outitem;  /* OUT: actual number of items */
    int  *outcol;   /* OUT: actual number of columns */
    float *rval;    /* OUT: actual values         */
    int  *null;     /* OUT: null flag for each element */ 
{
register int i, j, k, loop;
int  nrow, narow, ncol, dummy;
int  icol[COLMAX], sflag[COLMAX];
int  ritems[COLMAX], bytes;

(void) TCIGET(tid,&dummy,&nrow,&dummy,&dummy,&narow);
(void) TCCSEL(tid,colref,COLMAX,icol,sflag,&ncol);

for ( i = 0; i < ncol; i++ )
    { (void) TCBGET(tid,icol[i],&dummy,&ritems[i],&bytes);
      if ( items-index+1 > ritems[i] )
         { SCTPUT("Wrong index");
           return -1;
         }
    }
if ( items == 0 )
   { items = ritems[0]-index+1;
     for ( i = 1; i < ncol; i++ ) items = MIN( items, ritems[i]-index+1 );
   }

if ( !direction )
   { *outitem = *outcol = i = 0;
     while ( i < ncol )
           { j = *outcol * items; 
             (void) TCARDR( tid, row, icol[i], index, items, rval+j );
             i++;
             for ( loop = 0; loop < items; loop++ )
                 { if (  isNULLF(rval+j+loop) )
                      { if ( ! flag ) break;
                        *(null+j+loop) = 1;
                      }
                   else if ( flag )
                      *(null+j+loop) = 0;
                 } 
             if ( loop == items ) (*outcol)++;
           }
     *outitem = items;
   } 
else
   { *outitem =  k = 0;  
     for ( j = index; j < index+items; j++ )
         { for ( i = 0;i < ncol; i++,k++ ) 
               (void) TCARDR(tid,row,icol[i],j,1,rval+k);
           for ( loop = 0; loop < ncol; loop++ )
               { if (  isNULLF(rval+k-1-loop) )
                    { if ( flag )
                         *(null+k-1-loop) = 1;
                      else
                         { k = k - ncol;
                           break;
                         }
                    }
                 else if ( flag )
                    *(null+k-1-loop) = 0;
               }
           if ( loop == ncol ) (*outitem)++; 
         }
     *outcol = ncol;
   } 
return ERR_NORMAL;
}
/*

*/

int tbl_readyzplane( tid, colref, index, items, flag, direction, maxrow,
                     outitem, outrow, rval, null, sele )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE Reads an YZ plane from a 3-D table floating points numbers
         The routine returns an array of floating point values.
         Direction specifies the way the plane is read:
         0: the plane is read column by column (y by y)
         1: the plane is read z by z
         The routine checks the Existence of the columns and reads 
	 ALL rows and fills the selection output array accordingly
         flag specifies the way NULL values are treated:
         if flag = 0 tthe program skips null values
         if flag = 1 the program doesn't care about NULL values
.RETURNS status

.VERSION
 070806		creation

---------------------------------------------------------------*/
    int  tid;       /* IN : table id              */
    char *colref;   /* IN : column reference      */
    int  index;     /* IN : index number          */ 
    int  items;     /* IN : how many elements     */
    int  flag;      /* IN : flag for NULL values  */
    int  maxrow;    /* IN : max number of rows    */
    int  direction; /* IN : flag for the way the plane has to be read */
    int  *outitem;  /* OUT: actual number of items */
    int  *outrow;   /* OUT: actual number of rows */
    float *rval;    /* OUT: actual values         */
    int  *null;     /* OUT: null flag for each element */ 
    int  *sele;     /* OUT: sel flag for each element */ 
{
register int i, j, k, ll, loop;
int  dummy, icol, sel, ritems, bytes, nrow;

(void) TCCSER(tid,colref,&icol);
if ( icol == -1 ) 
   { SCTPUT("Column not found");
     return -1;
   } 
(void) TCIGET(tid,&dummy,&nrow,&dummy,&dummy,&dummy);
(void) TCBGET(tid,icol,&dummy,&ritems,&bytes);

if ( items == 0 ) 
   items = ritems-index+1;
else if ( ritems-index+1 < items) 
   { SCTPUT("Wrong index");
     return -1;
   }
if ( !direction )
   { k = *outitem = 0;
     for ( j=index; j < index+items; j++ )
         { i = ll = 0;
           while ( ll < maxrow && i < nrow )
                 { 
                 (void) TCSGET(tid,i+1,&sel);
                 (void) TCARDR(tid,i+1,icol,j,1,rval+k);
                 if (sel) 
                   *(sele+k) = 1;
                 else
                   *(sele+k) = 0;
                 k++; ll++;
                 i++;
                 }
           for ( loop = 0; loop < ll; loop++ ) 
               { if (  isNULLF(rval+k-1-loop) ) 
                    { if ( flag ) 
                         *(null+k-1-loop) = 1;
                      else 
                         { k = k-ll;
                           break;
                         }
                    }
                 else if ( flag ) 
                    *(null+k-1-loop) = 0;
               }
           if ( loop == ll ) (*outitem)++;
         }
     *outrow = nrow;
   return ERR_NORMAL;
   }


return ERR_INPINV;
}

