/*--------------------------------------------------------------------
 *	$Id: grdedit.c,v 1.3.4.1 2002/01/17 17:42:51 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
 *--------------------------------------------------------------------*/
/*
 * grdedit reads an existing grdfile and takes command line
 * arguments to redefine some of the grdheader parameters:
 *
 *	x_min/x_max OR x_inc (the other is recomputed)
 *	y_min/y_max OR y_inc (the other is recomputed)
 *	z_scale_factor/z_add_offset
 *	x_units/y_units/z_units
 *	title/command/remark
 *
 * Author:	Paul Wessel
 * Date:	9-SEP-1998
 * Modified:	19-FEB-2000 PW: Added -V option
 * Version:	3.4.1
 */
 
#include "gmt.h"

float *a;

main (int argc, char **argv)
{
	BOOLEAN error = FALSE, got_input = FALSE, got_region = FALSE, shift = FALSE, adjust = FALSE;
	
	int i, one_or_zero;

	double w, e, s, n, shift_amount = 0.0;
	
	char *grdfile, input[BUFSIZ];
	
	struct GRD_HEADER grd;
	
	input[0] = 0;
	grdfile = CNULL;
	w = e = s = n = 0.0;
	
	argc = GMT_begin (argc, argv);

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
				/* Common parameters */
			
				case 'R':
				case 'V':
				case '\0':
					error += GMT_get_common_args (argv[i], &w, &e, &s, &n);
					if (argv[i][1] == 'R') got_region = TRUE;
					break;

				/* Supplemental parameters */
			
				case 'D':
					strcpy (input, &argv[i][2]);
					got_input = TRUE;
					break;
				case 'A':
					adjust = TRUE;
					break;
				case 'S':
					shift = TRUE;
					break;
				default:
					error = TRUE;
					GMT_default_error (argv[i][1]);
					break;
			}
		}
		else
			grdfile = argv[i];
	}
		
	if (argc == 1 || GMT_quick) {
		fprintf (stderr, "grdedit %s - Modifying the header in a netCDF grdfile\n\n", GMT_VERSION);
		fprintf (stderr, "usage: grdedit grdfile [-A] [-R<west>/<east>/<south>/<north>]\n");
		fprintf (stderr, "\t[-S] [-Dxunit/yunit/zunit/scale/offset/title/remark] [-V]\n");
		
		if (GMT_quick) exit (EXIT_FAILURE);
		
		fprintf (stderr, "\tgrdfile is file to be modified\n");
		fprintf (stderr, "\n\tOPTIONS:\n");
		fprintf (stderr, "\t-A will adjust dx/dy to be compatible with the files domain or -R\n");
		fprintf (stderr, "\t-D to enter information.  Specify '=' to get default value\n");
		GMT_explain_option ('R');
		fprintf (stderr, "\t-S For global grids of 360 degree longitude range.\n");
		fprintf (stderr, "\t   Will rotate entire grid to coincide with new borders in -R\n");
		GMT_explain_option ('V');
		exit (EXIT_FAILURE);
	}
	
	if (shift && adjust) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -S option:  Incompatible with -A\n", GMT_program);
		error++;
	}
	if (shift && !got_region) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -S option:  Must also specify -R\n", GMT_program);
		error++;
	}
	if (shift && fabs (w - e) != 360.0) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -S option:  -R longitudes must span exactly 360 degrees\n", GMT_program);
		error++;
	}
	if (!grdfile) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify input file\n", GMT_program);
		error++;
	}
	if (error) exit (EXIT_FAILURE);

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

			
	if (!strcmp (grdfile,  "=")) {
		fprintf (stderr, "%s: Piping of grdfile not supported!\n", GMT_program);
		exit (EXIT_FAILURE);
	}

	if (GMT_read_grd_info (grdfile, &grd)) {
		fprintf (stderr, "%s: Error opening file %s\n", GMT_program, grdfile);
		exit (EXIT_FAILURE);
	}
	
	if (shift && fabs (grd.x_max - grd.x_min) != 360.0) {
		fprintf (stderr, "%s: Shift only allowed for global grids\n", GMT_program);
		exit (EXIT_FAILURE);
	}
	
	if (gmtdefs.verbose) fprintf (stderr, "%s: Editing parameters for file %s\n", GMT_program, grdfile);
	
	/* Decode grd information given, if any */
	
	if (got_input) {
		if (gmtdefs.verbose) fprintf (stderr, "%s: Decode and change attributes in file %s\n", GMT_program, grdfile);
		GMT_decode_grd_h_info (input, &grd);

	}
	
	if (!shift) {
		one_or_zero = (grd.node_offset) ? 0 : 1;
		if (got_region) {
			if (gmtdefs.verbose) fprintf (stderr, "%s: Reset region in file %s to %lg/%lg/%lg/%lg\n",
				GMT_program, grdfile, w, e, s, n);
			grd.x_min = w;	grd.x_max = e;
			grd.y_min = s;	grd.y_max = n;
			adjust = TRUE;	/* Must ensure -R -I compatibility */
		}
		if (adjust) {
			grd.x_inc = (grd.x_max - grd.x_min) / (grd.nx - one_or_zero);
			grd.y_inc = (grd.y_max - grd.y_min) / (grd.ny - one_or_zero);
			if (gmtdefs.verbose) fprintf (stderr, "%s: Reset grid-spacing in file %s to %lg/%lg\n",
				GMT_program, grdfile, grd.x_inc, grd.y_inc);
		}
		if (GMT_write_grd_info (grdfile, &grd)) {
			fprintf (stderr, "%s: Error updating file %s\n", GMT_program, grdfile);
			exit (EXIT_FAILURE);
		}
	}
	else {
		shift_amount = w - grd.x_min;
		if (gmtdefs.verbose) fprintf (stderr, "%s: Shifting longitudes in file %s by %lg degrees\n", GMT_program, grdfile, shift_amount);
		a = (float *) GMT_memory (VNULL, (size_t)(grd.nx * grd.ny), sizeof (float), GMT_program);
		if (GMT_read_grd (grdfile, &grd, a, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE)) {
			fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grdfile);
			exit (EXIT_FAILURE);
		}
		GMT_grd_shift (&grd, a, shift_amount);
		if (GMT_write_grd (grdfile, &grd, a, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE)) {
			fprintf (stderr, "%s: Error writing file %s\n", GMT_program, grdfile);
			exit (EXIT_FAILURE);
		}
		GMT_free ((void *)a);
	}
	if (gmtdefs.verbose) fprintf (stderr, "%s: File %s updated.\n", GMT_program, grdfile);
	
	GMT_end (argc, argv);
}
