/* This file is part of Cloudy and is copyright (C) 1978-2004 by Gary J. Ferland.
 * For conditions of distribution and use, see copyright notice in license.txt */
/*ParsePlot parse the plot command */
/*ParsePlotRangeOption parse range from plot command */
#include "cddefines.h"
#include "plot.h"
#include "rfield.h"
#include "parse.h"

/*ParsePlotRangeOption parse range from plot command, located below */
void ParsePlotRangeOption(char*);

/*ParsePlotRangeContin parse range option for continuum on map command, located below */
void ParsePlotRangeContin(char*);

void ParsePlot(char *chCard )
{

#	ifdef DEBUG_FUN
	fputs( "<+>ParsePlot()\n", debug_fp );
#	endif

	/* total number of plots so far */
	plotCom.nplot += 1;

	/* plots are turned on */
	plotCom.lgPlotON = TRUE;

	/* make sure we have not hit the limit, the dimension of variables in plot.h */
	if( plotCom.nplot > NDPLOT )
	{
		fprintf( ioQQQ, 
			" Too many plots; the limit is%3ld This one ignored.\n", 
		  NDPLOT );
		plotCom.nplot = NDPLOT;
	}

	if( lgMatch(" MAP",chCard) )
	{
		/*  option to make plot of heating - cooling map */
		strcpy( plotCom.chPType[plotCom.nplot-1], " MAP" );
	}

	else if( lgMatch("CONT",chCard) )
	{
		/* option to make "raw" plot, in internal units */
		if( lgMatch(" RAW",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "CRAW" );
			/* option to make diffuse continuum plot */
		}
		else if( lgMatch("DIFF",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "DIFF" );
			/* this is emitted continuum */
		}
		else if( lgMatch("EMIT",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "EMIT" );
			/* this is outward and attenuated continuum */
		}
		else if( lgMatch("OUTW",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "OUTW" );
			/* this is reflected continuum */
		}
		else if( lgMatch("REFL",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "REFL" );
			/* this is continuum in photons */
		}
		else if( lgMatch("PHOT",chCard) )
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "CPHT" );
		}
		else
		{
			strcpy( plotCom.chPType[plotCom.nplot-1], "CONT" );
		}
	}

	else if( lgMatch("OPAC",chCard) )
	{
		if( lgMatch("ABSO",chCard) )
		{
			/* plot absorption opacity */
			strcpy( plotCom.chPType[plotCom.nplot-1], "OPAA" );
		}
		else if( lgMatch("SCAT",chCard) )
		{
			/* plot scattering opacity */
			strcpy( plotCom.chPType[plotCom.nplot-1], "OPAS" );
		}
		else if( lgMatch("TOTA",chCard) )
		{
			/* plot total opacity */
			strcpy( plotCom.chPType[plotCom.nplot-1], "OPAT" );
		}
		else
		{
			/* plot total opacity for default */
			strcpy( plotCom.chPType[plotCom.nplot-1], "OPAT" );
		}
	}
	else
	{
		fprintf( ioQQQ, " The second keyword on the PLOT command must be CONTINUUM, _MAP, or OPACITY.\n" );
		puts( "[Stop in ParsePlot]" );
		cdEXIT(EXIT_FAILURE);
	}

	/* option to turn on trace of plot logic */
	if( lgMatch("TRAC",chCard) )
	{
		plotCom.lgPltTrace[plotCom.nplot-1] = TRUE;
	}
	else
	{
		plotCom.lgPltTrace[plotCom.nplot-1] = FALSE;
	}

	/* option to set min and max x-axis */
	if( strcmp(plotCom.chPType[plotCom.nplot-1]," MAP") == 0 )
	{
		/* this will be map of cooling and heating vs temp */
		ParsePlotRangeOption(chCard);
	}
	else
	{
		/* continuum map */
		ParsePlotRangeContin(chCard);
	}


#	ifdef DEBUG_FUN
	fputs( " <->ParsePlot()\n", debug_fp );
#	endif
	return;
}

/*ParsePlotRangeOption parse range from plot command */
void ParsePlotRangeOption(char *chCard )
{
	int lgEOL, 
	  lgLogOn;
	long int i;
	float a;

#	ifdef DEBUG_FUN
	fputs( "<+>ParsePlotRangeOption()\n", debug_fp );
#	endif

	i = 4;
	/* pltxmn is min for x axis of plot */
	plotCom.pltxmn[plotCom.nplot-1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);

	if( !lgMatch("RANG",chCard) )
	{
		/* no lines were enterd, so use default temperature limits */
		plotCom.pltxmn[plotCom.nplot-1] = 1.;
		plotCom.pltxmx[plotCom.nplot-1] = 9.;
		lgLogOn = TRUE;
	}
	else if( lgEOL )
	{
		/* no lines were enterd, so use default temperature limits */
		plotCom.pltxmn[plotCom.nplot-1] = 1.;
		plotCom.pltxmx[plotCom.nplot-1] = 9.;
		lgLogOn = TRUE;
	}
	else
	{
		/* number entered, now interprete it */
		if( plotCom.pltxmn[plotCom.nplot-1] <= 10. )
		{
			lgLogOn = TRUE;
		}
		else
		{
			lgLogOn = FALSE;
		}
		/* linear option for temperature */
		if( lgMatch("LINE",chCard) )
			lgLogOn = FALSE;
		/* lower temp was entered, now how about upper temp */
		plotCom.pltxmx[plotCom.nplot-1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
		if( lgEOL )
		{
			if( lgLogOn )
			{
				plotCom.pltxmx[plotCom.nplot-1] = 9.;
			}
			else
			{
				plotCom.pltxmx[plotCom.nplot-1] = 1e9;
			}
		}
		else
		{
			/*  second number was entered, check for sanity */
			if( plotCom.pltxmx[plotCom.nplot-1] <= plotCom.pltxmn[plotCom.nplot-1] )
			{
				fprintf( ioQQQ, 
					" The second (maximum) temperature for the map is%10.2e, but this is less than the first (minimum) temperature,%10.2e\n", 
				  plotCom.pltxmx[plotCom.nplot-1], plotCom.pltxmn[plotCom.nplot-1] );
				fprintf( ioQQQ, " HELP!  I am confused!!\n" );
				puts( "[Stop in ParsePlotRangeOption]" );
				cdEXIT(EXIT_FAILURE);
			}
		}
	}

	/* now force to be log */
	if( !lgLogOn )
	{
		if( plotCom.pltxmx[plotCom.nplot-1] <= 0. || plotCom.pltxmn[plotCom.nplot-1] <= 
		  0. )
		{
			fprintf( ioQQQ, 
				" Limits for temperature are negative.  This is impossible.   Sorry.\n" );
			puts( "[Stop in ParsePlotRangeOption]" );
			cdEXIT(EXIT_FAILURE);
		}
		plotCom.pltxmx[plotCom.nplot-1] = (float)log10(plotCom.pltxmx[plotCom.nplot-1]);
		plotCom.pltxmn[plotCom.nplot-1] = (float)log10(plotCom.pltxmn[plotCom.nplot-1]);
	}

	/* check that min is less than max */
	if( plotCom.pltxmn[plotCom.nplot-1] == plotCom.pltxmx[plotCom.nplot-1] )
	{
		fprintf( ioQQQ, " Upper and lower plot boundaries are equal.\n" );
		puts( "[Stop in ParsePlotRangeOption]" );
		cdEXIT(EXIT_FAILURE);
	}
	else if( plotCom.pltxmn[plotCom.nplot-1] > plotCom.pltxmx[plotCom.nplot-1] )
	{
		a = plotCom.pltxmx[plotCom.nplot-1];
		plotCom.pltxmx[plotCom.nplot-1] = plotCom.pltxmn[plotCom.nplot-1];
		plotCom.pltxmn[plotCom.nplot-1] = a;
	}


#	ifdef DEBUG_FUN
	fputs( " <->ParsePlotRangeOption()\n", debug_fp );
#	endif
	return;
}

/*ParsePlotRangeContin set range for map to parse range option on map command */
void ParsePlotRangeContin(char *chCard )
{
	int lgEOL, 
	  lgLogOn;
	long int i;
	float a;

#	ifdef DEBUG_FUN
	fputs( "<+>ParsePlotRangeContin()\n", debug_fp );
#	endif

	i = 4;
	plotCom.pltxmn[plotCom.nplot-1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);

	if( !lgMatch("RANG",chCard) )
	{
		/* no numbers on line, just set default limits to energy array */
		plotCom.pltxmn[plotCom.nplot-1] = (float)log10(rfield.emm);
		plotCom.pltxmx[plotCom.nplot-1] = (float)log10(rfield.egamry);
		lgLogOn = TRUE;
	}
	else if( lgEOL )
	{
		/* no numbers on line, just set default limits to energy array */
		plotCom.pltxmn[plotCom.nplot-1] = (float)log10(rfield.emm);
		plotCom.pltxmx[plotCom.nplot-1] = (float)log10(rfield.egamry);
		lgLogOn = TRUE;
	}
	else
	{
		/* lower limit entered, now interprete it */
		if( plotCom.pltxmn[plotCom.nplot-1] < 0. )
		{
			lgLogOn = TRUE;
		}
		else if( plotCom.pltxmn[plotCom.nplot-1] == 0.0 )
		{
			/* option for first number to be zero, lower edge of array */
			lgLogOn = FALSE;
			plotCom.pltxmn[plotCom.nplot-1] = rfield.emm;
		}
		else
		{
			/* a positive number was entered */
			lgLogOn = FALSE;
		}

		/* now look at upper limit */
		plotCom.pltxmx[plotCom.nplot-1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
		if( lgEOL || plotCom.pltxmx[plotCom.nplot-1] == 0.0 )
		{
			/* option for second number to be omitted or zero */
			if( lgLogOn )
			{
				plotCom.pltxmx[plotCom.nplot-1] = (float)log10(rfield.egamry);
			}
			else
			{
				plotCom.pltxmx[plotCom.nplot-1] = rfield.egamry;
			}
		}
	}

	/* now force to be log */
	if( !lgLogOn )
	{
		plotCom.pltxmx[plotCom.nplot-1] = (float)log10(plotCom.pltxmx[plotCom.nplot-1]);
		plotCom.pltxmn[plotCom.nplot-1] = (float)log10(plotCom.pltxmn[plotCom.nplot-1]);
	}

	/* check that min is less than max */
	if( plotCom.pltxmn[plotCom.nplot-1] == plotCom.pltxmx[plotCom.nplot-1] )
	{
		fprintf( ioQQQ, " Upper and lower plot boundaries are equal.\n" );
		puts( "[Stop in ParsePlotRangeContin]" );
		cdEXIT(EXIT_FAILURE);
	}
	else if( plotCom.pltxmn[plotCom.nplot-1] > plotCom.pltxmx[plotCom.nplot-1] )
	{
		a = plotCom.pltxmx[plotCom.nplot-1];
		plotCom.pltxmx[plotCom.nplot-1] = plotCom.pltxmn[plotCom.nplot-1];
		plotCom.pltxmn[plotCom.nplot-1] = a;
	}


#	ifdef DEBUG_FUN
	fputs( " <->ParsePlotRangeContin()\n", debug_fp );
#	endif
	return;
}

