/* 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 */
/*ParseTrace read in options off the trace command line */
#include "cddefines.h"
#include "iterations.h"
#include "geometry.h"
#include "trace.h"
#include "parse.h"

void ParseTrace(char *chCard )
{
	int lgEOL ;
	long int i;

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

	/* turn on trace at a certain zone; .LE.0 or none for starting trace
	 * optional second number is iteration to start debugger */

	/* generate string that says debug turned on - this is caught by perl script */
	fprintf(ioQQQ,"DEBUG trace output turned on.\n");

	i = 5;
	/* this is which zone to turn on */
	trace.nznbug = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
	if( lgEOL )
	{
		trace.lgTrace = TRUE;
	}

	/* this is which iteration to turn on */
	trace.npsbug = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
	if( lgEOL )
	{
		trace.npsbug = 1;
	}

	/* turn trace on now if no numbers on line */
	if( trace.nznbug == 0 && trace.npsbug <= 1 )
	{
		trace.lgTrace = TRUE;
		geometry.nprint = 1;
		iterations.IterPrnt[0] = 1;
	}

	/* >>chng 02 jun 14, change to set of if else rather than simply series of if 
	 * makes it possible to use keywords on converge without triggering other trace */

	/* >>chng 05 apr 13, changed all from else if to if, so that more than one
	 * keyword can be recognized on each command line */
	/* trace convergence is a special command, 
	 * only convergence loops, not full trace */
	if( lgMatch("CONV",chCard) )
	{
		/* check for keyword, if not present
		 * then set to very high level of debugging - initially set to negative number, a sign
		 * that trace is not on yet, but to turn on trace convergence when we hit the right zone */
		/* 1 ConvPresTempEdenIoniz */
		if( lgMatch("PRES",chCard) )
			trace.lgTrConvg = -1;
		/* 2 ConvTempEdenIoniz*/
		else if( lgMatch("TEMP",chCard) )
			trace.lgTrConvg = -2;
		/* 3 ConvEdenIoniz*/
		else if( lgMatch("EDEN",chCard) )
			trace.lgTrConvg = -3;
		/* 4 ConvIoniz*/
		else if( lgMatch("IONI",chCard) )
			trace.lgTrConvg = -4;
		/* 5 below ConvBase*/
		/* > 5 all levels*/
		else
			trace.lgTrConvg = -100;

		/* turn off normal trace parameters, this is a special case */
		trace.lgTrace = FALSE;
		/*trace.nznbug = 10000;*/
		geometry.nprint = 10000;
		iterations.IterPrnt[0] = 10000;

		/* this is an option to also turn on ots rate debug prints */
		if( lgMatch(" OTS",chCard) )
			trace.lgOTSBug = TRUE;
	
	}

	/* trace he-like and h-like must come early since they may have name of element */
	/* the trace h-like hydrogenic species command, with lots of options */
	if( lgMatch("H-LI",chCard) )
	{
		/* turn on short trace for h-like species */
		trace.lgHBug = TRUE;

		/* option to turn on full printout */
		if( lgMatch("FULL",chCard) )
		{
			trace.lgIsoTraceFull[ipH_LIKE] = TRUE;
		}
		else
		{
			trace.lgIsoTraceFull[ipH_LIKE] = FALSE;
		}

		/* look for one of the element names on the line*/
		trace.ipIsoTrace[ipH_LIKE] = GetElem(chCard);

		/* if no element appears on the line GetElem fcn returns -1,
		 * in this case we want to do hydrogen */
		trace.ipIsoTrace[ipH_LIKE] = MAX2(0, trace.ipIsoTrace[ipH_LIKE] );
	}

	/* the trace h-like hydrogenic species command, with lots of options */
	if( lgMatch("HE-L",chCard) )
	{
		/* turn on short trace for helium - like species */
		trace.lgHeBug = TRUE;

		/* option to turn on full printout */
		if( lgMatch("FULL",chCard) )
		{
			trace.lgIsoTraceFull[ipHE_LIKE] = TRUE;
		}
		else
		{
			trace.lgIsoTraceFull[ipHE_LIKE] = FALSE;
		}

		/* look for one of the element names on the line*/
		trace.ipIsoTrace[ipHE_LIKE] = GetElem(chCard);

		/* if no element appears on the line fcn returns -1,
		 * in this case we want to do helium */
		trace.ipIsoTrace[ipHE_LIKE] = MAX2(1, trace.ipIsoTrace[ipHE_LIKE] );
	}

	/* were there any keywords on the line? */
	if( lgMatch("BETA",chCard) )
		trace.lgTr8446 = TRUE;

	if( lgMatch("CARB",chCard) )
		trace.lgCarBug = TRUE;

	if( lgMatch("CALC",chCard) )
		trace.lgCalBug = TRUE;

	if( lgMatch("COMP",chCard) )
		trace.lgComBug = TRUE;

	if( lgMatch("CONT",chCard) )
		trace.lgConBug = TRUE;

	if( lgMatch("COOL",chCard) )
		trace.lgCoolTr = TRUE;

	if( lgMatch("DIFF",chCard) )
		trace.lgTrDiff = TRUE;

	if( lgMatch(" DR ",chCard) )
		trace.lgDrBug = TRUE;

	if( lgMatch("EDEN",chCard) || lgMatch("ELECTRON",chCard) )
		trace.lgNeBug = TRUE;

	if( lgMatch("GAUN",chCard) )
		trace.lgTrGant = TRUE;

	if( lgMatch("GRAI",chCard) )
		trace.lgDustBug = TRUE;

	if( lgMatch("HEAV",chCard) )
		trace.lgHeavyBug = TRUE;

	if( lgMatch("HEAT",chCard) )
		trace.lgHeatBug = TRUE;

	/* trace helium, but not h-like or he-like */
	if( lgMatch("HELI",chCard) && !lgMatch("H-LI",chCard)  && !lgMatch("HE-L",chCard) )
	{
		trace.lgHeBug = TRUE;
		if( lgMatch("SING",chCard) )
			trace.lgHe1Bug = TRUE;

		if( lgMatch("ATOM",chCard) )
			trace.lgHe1Bug = TRUE;

		/* this will match either ionzed or ion */
		if( lgMatch(" ION",chCard) )
			trace.lgHe2Bug = TRUE;

		if( lgMatch("TRIP",chCard) )
			trace.lgHe3Bug = TRUE;
	}

	/* the simple trace hydrogen command */
	if( lgMatch("HYDR",chCard) && !lgMatch("H-LI",chCard))
	{
		trace.lgHBug = TRUE;
		trace.lgIsoTraceFull[ipH_LIKE] = FALSE;
		/* this says which element, on the C scale (H=0), to trace */
		trace.ipIsoTrace[ipH_LIKE] = 0;

	}

	if( lgMatch("IRON",chCard) )
		trace.lgFeBug = TRUE;

	if( lgMatch("VELN",chCard) )
		trace.lgTrLevN = TRUE;

	if( lgMatch("LINE",chCard) )
		trace.lgTrLine = TRUE;

	if( lgMatch("NEON",chCard) )
		trace.lgNeonBug = TRUE;

	if( lgMatch("MOLE",chCard) )
	{
		/* turn on molecular trace - either CO or H2, or both */
		if( lgMatch("HMOL",chCard) )
		{
			/* H2 network */
			trace.lgTr_H2_Mole = TRUE;
		}
		if( lgMatch("CMOL",chCard ) )
		{
			/* CO network */
			trace.lgTr_CO_Mole = TRUE;
		}
		else
		{
			/* turn them both on */
			trace.lgTr_CO_Mole = TRUE;
			trace.lgTr_H2_Mole = TRUE;
		}
	}

	/* trace pointers */
	if( lgMatch("POIN",chCard) )
		trace.lgPointBug = TRUE;
	
	/* following two are optical, optimize */
	if( lgMatch("PTIC",chCard) )
		trace.lgOptcBug = TRUE;
	
	if( lgMatch("PTIM",chCard) )
		trace.lgTrOptm = TRUE;
	
	if( lgMatch(" OTS",chCard) )
		trace.lgOTSBug = TRUE;
	
	if( lgMatch("SECO",chCard) && lgMatch("IONI",chCard) )
		/* secondary ionization */
		trace.lgSecIon = TRUE;
	
	if( lgMatch("THRE",chCard) )
		trace.lgTrace3Bod = TRUE;

	/* two photon emission, spontaneous and induced */
	if( lgMatch(" TWO",chCard) )
		trace.lgBug2nu = TRUE;

	/* falling through is fine - just turn on minimal trace */

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