/*--------------------------------------------------------------------
 *	$Id: gmtconvert.c,v 1.2.4.2 2002/02/27 17:58:55 pwessel Exp $
 *
 *	Copyright (c) 1991-2002 by P. Wessel and W. H. F. Smith
 *	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: gmt.soest.hawaii.edu
 *--------------------------------------------------------------------*/
/*
 * gmtconvert.c
 * reads a GMT table and writes it out in a different format.
  
   Author: 	P. Wessel
   Date:	13-JUL-2000.
   version:	3.4.1

*/

#include "gmt.h"


main (int argc, char **argv)
{	
	int	i, n_total_read = 0, n_files = 0, n_outputs = 0, fno, n_args, n_fields, n_expected_fields, error = 0, n_cols = 0;

	double	*in;
	
	BOOLEAN nofile = TRUE, done = FALSE;

	char record_str[BUFSIZ];
	
	FILE *fp = NULL;
	
	argc = GMT_begin (argc, argv);

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
			
		
				/* Common parameters */
			
				case 'H':
				case 'V':
				case '\0':
					error += GMT_get_common_args (argv[i], 0, 0, 0, 0);
					break;
				
				/* Supplemental parameters */
				
				case 'b':
					error += GMT_io_selection (&argv[i][2]);
					break;
				case 'M':
					GMT_multisegment (&argv[i][2]);
					break;
				default:
					error = TRUE;
					GMT_default_error (argv[i][1]);
					break;
			}
		}
		else
			n_files++;
	}
	
	if (argc == 1 || GMT_quick) {
		fprintf (stderr, "gmtconvert %s - gmtconvert table data from one format to another\n\n", GMT_VERSION);
		fprintf(stderr,"usage:	gmtconvert [files] [-H[<nrec>]] [-M[<flag>]] [-V] [-:] [-bi[s]<n>] [-bo[s][<n>]]\n\n");
		
		if (GMT_quick) exit (EXIT_FAILURE);

		fprintf(stderr,"\tgmtconvert will read GMT_stdin or files, and writes to GMT_stdout\n");
		fprintf (stderr, "\n\tOPTIONS:\n");
		GMT_explain_option ('H');
		GMT_explain_option ('M');
		GMT_explain_option ('V');
		GMT_explain_option ('i');
		GMT_explain_option ('n');
		GMT_explain_option ('o');
		exit (EXIT_FAILURE);
	}
	
	if (GMT_io.binary[0] && GMT_io.ncol[0] == 0) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR.  Must specify number of columns in binary input data (-bi)\n", GMT_program);
		error++;
	}
	if (!GMT_io.binary[0] && GMT_io.multi_segments && GMT_io.binary[1] && GMT_io.ncol[1] == 0) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR.  With -M, must specify number of columns in binary output data (-bo)\n", GMT_program);
		error++;
	}
	if (error) exit (EXIT_FAILURE);

	GMT_put_history (argc, argv);	/* Update .gmtcommands */


	if (GMT_io.binary[0] && gmtdefs.verbose) {
		char *type[2] = {"double", "single"};
		fprintf (stderr, "%s: Expects %d-column %s-precision binary data\n", GMT_program, GMT_io.ncol[0], type[GMT_io.single_precision[0]]);
	}

#ifdef SET_IO_MODE
	GMT_setmode (1);
#endif

	if (!GMT_io.binary[0] && GMT_io.multi_segments && GMT_io.binary[1]) n_cols = GMT_io.ncol[1];

	/*  Now we are ready to work  */

	if (n_files > 0)
		nofile = FALSE;
	else
		n_files = 1;

	n_args = (argc > 1) ? argc : 2;

	for (fno = 1; !done && fno < n_args; fno++) {	/* Loop over input files, if any */
		if (!nofile && argv[fno][0] == '-') continue;
		
		if (nofile) {	/* Just read standard input */
			fp = GMT_stdin;
			done = TRUE;
#ifdef SET_IO_MODE
			GMT_setmode (0);
#endif
		}
		else if ((fp = GMT_fopen (argv[fno], GMT_io.r_mode)) == NULL) {
			fprintf (stderr, "%s: Cannot open file %s\n", GMT_program, argv[fno]);
			continue;
		}

		if (!nofile && gmtdefs.verbose) fprintf (stderr, "%s: Working on file %s\n", GMT_program, argv[fno]);
		
		if (!GMT_io.binary[0] && gmtdefs.io_header) {
			for (i = 0; i < gmtdefs.n_header_recs; i++) {
				GMT_fgets (record_str, BUFSIZ, fp);
				n_total_read ++;
				if (!GMT_io.binary[1]) fputs (record_str, GMT_stdout);
			}
		}
	
		n_expected_fields = (GMT_io.ncol[0]) ? GMT_io.ncol[0] : BUFSIZ; /* BUFSIZ -> Ascii table, must first find the number of fields */
		n_fields = GMT_input (fp, &n_expected_fields, &in);

		while (! (GMT_io.status & GMT_IO_EOF)) {	/* Not yet EOF */
			
			while (GMT_io.status & GMT_IO_SEGMENT_HEADER && !(GMT_io.status & GMT_IO_EOF)) {
				GMT_write_segmentheader (GMT_stdout, n_cols);
				n_fields = GMT_input (fp,  &n_expected_fields, &in);
				n_total_read ++;
			}

			while (! (GMT_io.status & (GMT_IO_SEGMENT_HEADER | GMT_IO_EOF))) {	/* Keep going until FALSE or = 2 segment header */
				if (GMT_io.status & GMT_IO_MISMATCH) {
					fprintf (stderr, "%s: Mismatch between actual (%d) and expected (%d) fields near line %d\n", GMT_program, n_fields, n_expected_fields, n_total_read);
					exit (EXIT_FAILURE);
				}

				/* Now output this segment */

				if (!n_outputs) n_outputs = (GMT_io.ncol[1]) ? GMT_io.ncol[1] : n_expected_fields;

				GMT_output (GMT_stdout, n_outputs, in);

				n_total_read ++;
			
				n_fields = GMT_input (fp, &n_expected_fields, &in);
			}

		}

		if (fp != GMT_stdin) GMT_fclose(fp);
	}

	if (gmtdefs.verbose) fprintf(stderr, "gmtconvert: %d records read\n", n_total_read);
	
	GMT_end (argc, argv);
}
