/*--------------------------------------------------------------------
 *	$Id: testgmtio.c 12822 2014-01-31 23:39:56Z remko $
 *
 *	Copyright (c) 1991-2014 by P. Wessel, W. H. F. Smith, R. Scharroo, J. Luis and F. Wobbe
 *	See LICENSE.TXT 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 Lesser General Public License as published by
 *	the Free Software Foundation; version 3 or 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 Lesser General Public License for more details.
 *
 *	Contact info: gmt.soest.hawaii.edu
 *--------------------------------------------------------------------*/
/*
 * Demonstrate how to use the table i/o machinery on a record-by-record
 * basis, including the various checks for gaps, headers, etc.
 *
 * Version:	5
 * Created:	19-Mar-2010
 *
 */

#include "gmt_dev.h"

#define GMT_PROG_OPTIONS "->Vghi"

int main (int argc, char *argv[]) {
	int n_fields = 0, mode = 0,  error = 0;
	double *in = NULL;
	struct GMT_OPTION *options = NULL;	/* Linked list of options */
	struct GMTAPI_CTRL *API = NULL;		/* GMT API control structure */
	struct GMT_CTRL *GMT = NULL;

	/* 1. Initializing new GMT session */
	if ((API = GMT_Create_Session ("TEST", 2U, 0U, NULL)) == NULL) exit (EXIT_FAILURE);
	GMT = API->GMT;

	/* 2. Convert command line arguments to local linked option list */
	if ((options = GMT_Create_Options (API, argc-1, (argv+1))) == NULL) exit (EXIT_FAILURE);

	/* 3. Parse the common GMT options (e.g., -h -V) */
	if (GMT_Parse_Common (API, GMT_PROG_OPTIONS, options)) exit (EXIT_FAILURE);

	/* 4. Initializing data input via stdin */
	
	if ((error = GMT_set_cols (GMT, GMT_IN, 0))) exit (EXIT_FAILURE);
	if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN,  GMT_ADD_DEFAULT, 0, options) != GMT_OK) exit (EXIT_FAILURE);	/* Establishes data input */
	if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_OUT, GMT_ADD_DEFAULT, 0, options) != GMT_OK) exit (EXIT_FAILURE);	/* Establishes data output */
	
	/* 5. Read individual records until end of data set */
	/*    The GMT_FILE_BREAK in GMT_Get_Record means we will return a special EOF marker at the end of each
	 *    data table when there are more tables to process.  The end of the last file yields the actual EOF.
	 *    This lets us do special processing after a file has been fully read. */

	/* Initialize the i/o for doing record-by-record reading/writing */
	if ((error = GMT_Begin_IO (API, GMT_IS_DATASET,  GMT_IN, GMT_HEADER_ON)) != GMT_OK) exit (error);				/* Enables data input and sets access mode */
	if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON)) != GMT_OK) exit (error);				/* Enables data output and sets access mode */
	
	do {	/* Keep returning records until we reach EOF */
		mode = GMT_WRITE_DOUBLE;	/* Normally we treat data as double precision values */
		if ((in = GMT_Get_Record (API, GMT_READ_DOUBLE | GMT_FILE_BREAK, &n_fields)) == NULL) {	/* Read next record, get NULL if special case */
			if (GMT_REC_IS_ERROR (GMT)) {	/* This check kicks in if the data has bad formatting, text etc */
				GMT_Report (API, GMT_MSG_VERBOSE, "Error found in record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "E: ");
				mode = GMT_WRITE_TEXT;	/* Switch to text so we can see the bad record as is */
			}
			if (GMT_REC_IS_FILE_BREAK (GMT)) {	/* End of a file but not end of all files */
				GMT_Report (API, GMT_MSG_VERBOSE, "End of intermediate data file after record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "B: --- End of File except last one ---\n");
				continue;	/* Since no actual data record was returned, just the intermediate "EOF" signal */
			}
			if (GMT_REC_IS_TABLE_HEADER (GMT)) {	/* Found a table header */
				GMT_Report (API, GMT_MSG_VERBOSE, "Table header found in record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "H: ");
				mode = GMT_WRITE_TABLE_HEADER;	/* Special flag to report the table header */
			}
			if (GMT_REC_IS_SEGMENT_HEADER (GMT)) {	/* Found segment header */
				GMT_Report (API, GMT_MSG_VERBOSE, "Segment header found in record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "S: ");
				mode = GMT_WRITE_SEGMENT_HEADER;	/* Special flag to report the segment header */
			}
			if (GMT_REC_IS_NAN (GMT)) {	/* Found NaN record */
				GMT_Report (API, GMT_MSG_VERBOSE, "NaN data found in record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "N: ");
				mode = GMT_WRITE_TEXT;	/* Switch to text so we can see the nan record as is */
			}
			if (GMT_REC_IS_GAP (GMT)) {	/* Found a gap */
				GMT_Report (API, GMT_MSG_VERBOSE, "A gap found in record %" PRIu64 "\n", GMT->current.io.rec_no);
				API->print_func (stdout, "G: ");
			}
		}
		if (GMT_REC_IS_DATA (GMT)) {	/* Found a data record */
			if ((error = GMT_set_cols (GMT, GMT_IN, n_fields))) exit (EXIT_FAILURE);
			if ((error = GMT_set_cols (GMT, GMT_OUT, n_fields))) exit (EXIT_FAILURE);
			GMT_Report (API, GMT_MSG_VERBOSE, "Data found in record %" PRIu64 "\n", GMT->current.io.rec_no);
			API->print_func (stdout, "D: ");
		}
		GMT_Put_Record (API, mode, in);
	} while (true);
	
	API->print_func (stdout, "B: --- End of All Files ---\n");
	if ((error = GMT_End_IO (API, GMT_IN,  0)) != GMT_OK) exit (error);				/* Disables further data input */
	if ((error = GMT_End_IO (API, GMT_OUT, 0)) != GMT_OK) exit (error);				/* Disables further data output */
	
	/* 5. Destroy local linked option list */
	if (GMT_Destroy_Options (API, &options)) exit (EXIT_FAILURE);

	/* 6. Destroy GMT session */
	if (GMT_Destroy_Session (API)) exit (EXIT_FAILURE);

	exit (GMT_OK);		/* Return the status from this program */
}
