/*-----------------------------------------------------------------
 *	$Id: x2sys_datalist.c,v 1.6 2004/08/19 18:56:00 pwessel Exp $
 *
 *      Copyright (c) 1999-2004 by P. Wessel
 *      See COPYING file for copying and redistribution conditions.
 *
 *      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; version 2 of the License.
 *
 *      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.
 *
 *      Contact info: www.soest.hawaii.edu/pwessel
 *--------------------------------------------------------------------*/
/* x2sys_datalist will read one or several data files and dump their
 * contents to stdout in ascii or binary (double precision) mode.
 * Input data file formats are determined by the definition file
 * given by the -D option.
 *
 * Author:	Paul Wessel
 * Date:	15-JUN-2004
 * Version:	1.1, based on the spirit of the old xsystem code
 *
 */

#include "x2sys.h"

main (int argc, char **argv)
{
	char *sfile, *def = "x2sys", *fflags = CNULL, *TAG = CNULL;

	int i, j, k, n_data_col_out, bad;

	BOOLEAN error = FALSE, suppress = FALSE, t_given, d_given;

	double **data, west, east, south, north, *out;

	struct X2SYS_INFO *s;
	struct X2SYS_FILE_INFO p;		/* File information */
	struct X2SYS_BIX B;

	GMT_begin (argc, argv);
	for (i = strlen(argv[0]); i >= 0 && argv[0][i] != '/'; i--);
	X2SYS_program = &argv[0][i+1];	/* Name without full path */

	sfile = def;
	west = east = south = north = 0.0;
	t_given = d_given = FALSE;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
				/* Common parameters */
			
				case 'H':
				case 'R':
				case 'V':
				case '\0':
					error += GMT_get_common_args (argv[i], &west, &east, &south, &north);
					break;
				
				/* Supplemental parameters */
				
				case 'D':
					sfile = &argv[i][2];
					d_given = TRUE;
					break;
				case 'F':
					fflags = &argv[i][2];
					break;
				case 'M':               /* Multiple line segments */
					GMT_multisegment (&argv[i][2]);
					break;
				case 'S':
					suppress = TRUE;
					break;
				case 'T':
					TAG = &argv[i][2];
					t_given = TRUE;
					break;
				case 'b':
					error += GMT_io_selection (&argv[i][2]);
					break;
				default:
					error = TRUE;
					break;
			}
		}
	}

	if (argc == 1 || error) {
		fprintf (stderr, "x2sys_datalist %s - listing of datafiles to stdout\n\n", X2SYS_VERSION);
		fprintf (stderr, "usage: x2sys_datalist <files> [-D<deffile>] [-F<fields>] [-M[<flag>]] [-R<w/e/s/n>] [-S] [-T<TAG>] [-V] [-b]\n\n");
		fprintf (stderr, "	<files> is one or more datafiles\n");
		fprintf (stderr, "\n\tOPTIONS:\n");
		fprintf (stderr, "	-D definition file for this data set\n");
		fprintf (stderr, "	   [Default is %s%cx2sys.def\n", X2SYS_HOME, DIR_DELIM);
		fprintf (stderr, "	   Alternatively, give the system TAG (-T)\n");
		fprintf (stderr, "	-F is comma-separated list of column names to output [Default are all fields]\n");
		GMT_explain_option ('R');
		fprintf (stderr, "	-S Suppress output records where all data columns are NaN [Output all records]\n");
		fprintf (stderr, "	-T <TAG> is the system tag for the data set.  If not given, please set -D\n");
		GMT_explain_option ('V');
		fprintf (stderr, "	-b gives binary output list (double precision)\n");
		exit (EXIT_FAILURE);
	}
	
	if (t_given && d_given) {
		fprintf (stderr, "%s: ERROR: Only give one of -D and -T\n", GMT_program);
		exit (EXIT_FAILURE);
	}

	if (t_given)
		x2sys_set_system (TAG, &s, &B, &GMT_io);
	else
		s = x2sys_initialize (sfile, &GMT_io);	/* Initialize X2SYS and info structure */
		
	if (fflags) x2sys_pick_fields (fflags, s);

	s->ascii_out = !GMT_io.binary[1];

	if (project_info.region_supplied) {
		/* Supply dummy linear proj */
		project_info.projection = project_info.xyz_projection[0] = project_info.xyz_projection[1] = LINEAR;
		project_info.pars[0] = project_info.pars[1] = 1.0;
		if (west < 0.0 && east < 0.0) {
			west += 360.0;
			east += 360.0;
		}
		GMT_map_setup (west, east, south, north);
	}

	out = (double *) GMT_memory (VNULL, (size_t)s->n_fields, sizeof (double), "x2sys_datalist");

	if (suppress) {	/* Must count output data columns (except t, x, y) */
		for (i = n_data_col_out = 0; i < s->n_out_columns; i++) {
			if (s->out_order[i] == s->t_col) continue;
			if (s->out_order[i] == s->x_col) continue;
			if (s->out_order[i] == s->y_col) continue;
			n_data_col_out++;
		}
	}

	for (i = 1; i < argc; i++) {

		if (argv[i][0] == '-') continue;

		if (gmtdefs.verbose) fprintf (stderr, "x2sys_datalist: Reading file %s\n", argv[i]);

		if (((s->read_file) (argv[i], &data, s, &p, &GMT_io)) < 0) {
			fprintf (stderr, "x2sys_datalist: Error reading file %s\n", argv[i]);
			exit (EXIT_FAILURE);
		}

		if (GMT_io.multi_segments) GMT_write_segmentheader (GMT_stdout, s->n_fields);

		for (j = 0; j < p.n_rows; j++) {
			if (project_info.region_supplied && GMT_map_outside (data[s->x_col][j], data[s->y_col][j])) continue;
			if (suppress) {
				for (i = bad = 0; i < s->n_out_columns; i++) {
					if (s->out_order[i] == s->t_col) continue;
					if (s->out_order[i] == s->x_col) continue;
					if (s->out_order[i] == s->y_col) continue;
					if (GMT_is_dnan (data[s->out_order[i]][j])) bad++;
				}
				if (bad == n_data_col_out) continue;
			}

			for (k = 0; k < s->n_fields; k++) out[k] = data[k][j];
			x2sys_output_record (GMT_stdout, out, s);
		}

		x2sys_free_data (data, s->n_fields);
	}

	x2sys_free_info (s);
	GMT_free ((void *)out);

	GMT_end (argc, argv);
}
