/*--------------------------------------------------------------------
 *	$Id: makecpt.c,v 1.2.4.2 2002/02/27 17:41:10 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
 *--------------------------------------------------------------------*/
/*
 * makecpt [-C<color_table>] [-I] [-Tz0/z1/dz | -T<table>] [-V] [-Z]
 *
 * Read an existing cpt table and desired z grid and produce
 * a GMT cpt file.  Can be inverted [-I] or made continuous [-Z].
 * Discrete color jumps in cpt tables are handled correctly.
 * Default color table is still rainbow.
 *
 * Author:	Walter H.f. Smith & P. Wessel
 * Date:	04-JUL-2000
 * Version:	3.4.1
 */

#include "gmt.h"

main(int argc, char **argv)
{
	int	i, nz;

	BOOLEAN	error = FALSE, continuous = FALSE, reverse = FALSE, got_t = FALSE, got_tfile = FALSE, ok = FALSE;

	double	z_start, z_stop, z_inc, *z;

	FILE	*fpc = NULL, *fpl = NULL;

	char	*table = CNULL, *tfile = CNULL, buffer[BUFSIZ], CPT_lis[BUFSIZ], CPT_file[BUFSIZ];

	argc = GMT_begin(argc, argv);

	z_start = z_stop = z_inc = 0.0;

	/* Get list of available color tables in GMT /share */

	sprintf (CPT_lis, "%s%cshare%cGMT_CPT.lis", GMTHOME, DIR_DELIM, DIR_DELIM);

	if ((fpc = fopen (CPT_lis, "r")) == NULL) {
		fprintf (stderr, "%s: ERROR: Cannot open file %s\n", GMT_program, CPT_lis);
		exit (EXIT_FAILURE);
	}

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch(argv[i][1]) {
				case 'V':
				case '\0':
					error += GMT_get_common_args(argv[i], 0, 0, 0, 0);
					break;
				case 'C':
					table = &argv[i][2];
					break;
				case 'I':
					reverse = TRUE;
					break;
				case 'T':
					if (!access (&argv[i][2], R_OK)) {
						got_tfile = TRUE;
						tfile = &argv[i][2];
					}
					else {
						got_t = TRUE;
						sscanf (&argv[i][2], "%lf/%lf/%lf", &z_start, &z_stop, &z_inc);
					}
					break;
				case 'Z':
					continuous = TRUE;
					break;
				default:
					error = TRUE;
					GMT_default_error (argv[i][1]);
					break;
			}
		}
	}

	if (argc == 1 || GMT_quick) {
		fprintf(stderr,"makecpt %s - Make GMT color palette tables\n\n", GMT_VERSION);
		fprintf(stderr,"usage:  makecpt [-C<table>] [-I] [-T<z0/z1/dz> | -T<file>] [-V] [-Z]\n\n");
		if (GMT_quick) exit (EXIT_FAILURE);
		fprintf (stderr, "\n\tOPTIONS:\n");
		fprintf(stderr,"\t-C Specify a colortable [Default is rainbow]:\n");
		fprintf(stderr,"\t   [Default min/max values for -T are given in brackets]\n");
		fprintf(stderr,"\t   ---------------------------------\n");
		while (fgets (buffer, BUFSIZ, fpc)) if (!(buffer[0] == '#' || buffer[0] == 0)) fprintf (stderr, "\t   %s", buffer);
		fclose (fpc);
		fprintf(stderr,"\t   ---------------------------------\n");
		fprintf(stderr,"\t-I reverses the sense of the color table\n");
		fprintf(stderr,"\t-T Give start, stop, and increment for colorscale in z-units, or filename with custom z-values\n");
		fprintf(stderr,"\t   If not given, the range in the master cptfile is used\n");
		GMT_explain_option ('V');
		fprintf(stderr,"\t-Z will create a continuous color palette.\n");
		fprintf(stderr,"\t   [Default is discontinuous, i.e., constant color intervals]\n");
		exit (EXIT_FAILURE);
	}

	fclose (fpc);

	if (got_t && (z_start >= z_stop || z_inc <= 0.0)) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -T option:  Give start < stop and inc > 0.0\n", GMT_program);
		error++;
	}

	/* Open the specified master color table */

	/* First try current directory */

	if (table) {
		if (strstr (table, ".cpt"))
			strcpy (CPT_file, table);
		else
			sprintf (CPT_file, "%s.cpt", table);

		ok = !access (CPT_file, R_OK);
		if (ok && gmtdefs.verbose) fprintf (stderr, "%s: Reading %s in current directory\n", GMT_program, CPT_file);
	}

	if (!ok)	{	/* No table in current dir, try /share */
		if (table)
			sprintf (CPT_file, "%s%cshare%cGMT_%s.cpt", GMTHOME, DIR_DELIM, DIR_DELIM, table);
		else	/* Default to rainbow colors */
			sprintf (CPT_file, "%s%cshare%cGMT_rainbow.cpt", GMTHOME, DIR_DELIM, DIR_DELIM);

		ok = !access (CPT_file, R_OK);
		if (!ok) {
			fprintf (stderr, "%s: ERROR: Cannot find colortable %s\n", GMT_program, CPT_file);
			exit (EXIT_FAILURE);
		}
		else if (gmtdefs.verbose)
			fprintf (stderr, "%s: Reading %s\n", GMT_program, CPT_file);
	}

	if (got_tfile && (fpl = GMT_fopen (tfile, "r")) == NULL) {
		fprintf (stderr, "%s: Error: Could not open file %s\n", GMT_program, tfile);
		error++;
	}

	if (error) exit (EXIT_FAILURE);

	/* OK, we can now do the resampling */

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

	GMT_read_cpt (CPT_file);

	/* Set up arrays */

	if (got_tfile) {
		int n_alloc = GMT_SMALL_CHUNK;
		z = (double *) GMT_memory (VNULL, (size_t)n_alloc, sizeof(double), GMT_program);
		nz = 0;
		while (fgets (buffer, BUFSIZ, fpl)) {
			if (buffer[0] == '#') continue;
			z[nz] = atof (buffer);
			nz++;
			if (nz == n_alloc) {
				n_alloc += GMT_SMALL_CHUNK;
				z = (double *) GMT_memory ((void *)z, (size_t)n_alloc, sizeof(double), GMT_program);
			}
		}
		GMT_fclose (fpl);
		if (nz == 0) {
			fprintf (stderr, "%s: Error: No intervals in file %s\n", GMT_program, tfile);
			exit (EXIT_FAILURE);
		}
		z = (double *) GMT_memory ((void *)z, (size_t)nz, sizeof(double), GMT_program);
	}
	else if (got_t) {	/* Establish linear grid */
		nz = irint ((z_stop - z_start) / z_inc) + 1;
		z = (double *) GMT_memory (VNULL, (size_t)nz, sizeof(double), GMT_program);

		for (i = 0; i < nz; i++) z[i] = z_start + i * z_inc;	/* Desired z values */
	}
	else {	/* Just copy what was in the cpt file */
		nz = GMT_n_colors + 1;
		z = (double *) GMT_memory (VNULL, (size_t)nz, sizeof(double), GMT_program);
		for (i = 0; i < nz-1; i++) z[i] = GMT_lut[i].z_low;
		z[i] = GMT_lut[i-1].z_high;
	}
	
	/* Write to GMT_stdout.  */

	fprintf (GMT_stdout, "#\tcpt file created by: %s", GMT_program);
	for (i = 1; i < argc; i++) fprintf (GMT_stdout, " %s", argv[i]);
	fprintf (GMT_stdout, "\n");

	GMT_sample_cpt (z, nz, continuous, reverse);

	GMT_free ((void *)z);

	GMT_end (argc, argv);
}
