/* This file is part of Cloudy and is copyright (C)1978-2006 by Gary J. Ferland
 * For conditions of distribution and use see copyright notice in license.txt */
/*ParseDont parse the dont command - do not do something */
#include "cddefines.h"
#include "taulines.h"
#include "opacity.h"
#include "phycon.h"
#include "secondaries.h"
#include "pressure.h"
#include "prt.h"
#include "coolheavy.h"
#include "input.h"
#include "thermal.h"
#include "rfield.h"
#include "dynamics.h"
#include "mole.h"
#include "rt.h"
#include "hmi.h"
#include "atomfeii.h"
#include "yield.h"
#include "ionbal.h"
#include "atmdat.h"
#include "grainvar.h"
#include "hyperfine.h"
#include "parse.h"

void ParseDont(char *chCard )
{
	long int nelem, 
	  nshell, 
	  nstage;

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

	if( (lgMatch( "21CM" , chCard ) || lgMatch( "21 CM" , chCard )) && 
		lgMatch( " LYA" , chCard ) && lgMatch( "PUMP" , chCard ) )
	{
		/* no Lya 21 cm pump turns off 21 cm pumping of Lya */
		hyperfine.lgLya_pump_21cm = FALSE;
	}
	else if( lgMatch("ADVE",chCard) )
	{
		/*  turn off different aspects of advection */
		if( lgMatch("H-LI",chCard) )
		{
			/* advection for the H-like ion sequence */
			dynamics.lgISO[ipH_LIKE] = 0;
		}
		else if( lgMatch("HE-L",chCard) )
		{
			/* advection for the He-like ion sequence */
			dynamics.lgISO[ipHE_LIKE] = 0;
		}
		else if( lgMatch("META",chCard) )
		{
			/* advection for the everything else - those done in bidiag */
			dynamics.lgMETALS = 0;
		}
		else if( lgMatch("COOL",chCard) )
		{
			/* turn off cooling - heating due to  advection */
			dynamics.lgCoolHeat = 0;
		}
		else
		{
			/* no sub option, so turn them all off */
			dynamics.lgISO[ipH_LIKE] = 0;
			dynamics.lgISO[ipHE_LIKE] = 0;
			dynamics.lgMETALS = 0;
		}

	}

	else if( lgMatch("AUGE",chCard) )
	{
		/*  turn off auger effect by killing its block data */
		yield.lgKillAuger = TRUE;
		phycon.lgPhysOK = FALSE;
		for( nelem=0; nelem < LIMELM; nelem++ )
		{
			for( nstage=0; nstage < nelem; nstage++ )
			{
				for( nshell=0; nshell < 7; nshell++ )
				{
					/* only one electron comes out */
					yield.n_elec_eject[nelem][nstage][nshell] = 1;
					yield.frac_elec_eject[nelem][nstage][nshell][0] = 1.;
				}
			}
		}
	}

	else if( lgMatch("BUFF",chCard) )
	{
		/* NO BUFFERING turn off buffered io for standard output, 
		 * used to get output when code crashes */
		setbuf( ioQQQ , NULL );
		/* will be used to generate comment at end */
		input.lgSetNoBuffering = FALSE;
	}

	else if( lgMatch("CHAR",chCard) )
	{
		/* turn off all charge transfer interactions */
		atmdat.lgCTOn = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("CTHE",chCard) )
	{
		/* turn off charge transfer heating */
		atmdat.HCharHeatOn = 0.;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("COMP",chCard) )
	{
		/* turn off both recoil ionization and compton heating of free electron */
		rfield.comoff = 0.;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("FEII",chCard) )
	{
		/* turn off feii ly-alpha pumping - rate evaluated in FeIILyaPump */
		FeII.lgLyaPumpOn = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("FILE",chCard) && lgMatch("OPAC",chCard) )
	{
		/* no file opacities, generate them on the fly even if file present */
		opac.lgUseFileOpac = FALSE;
	}

	else if( lgMatch("FINE",chCard) && lgMatch("OPAC",chCard) )
	{
		/* no fine opacities */
		rfield.lgOpacityFine = FALSE;
	}

	else if( lgMatch("FINE",chCard) )
	{
		/* turn off fine structure optical depths */
		rt.lgFstOn = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("FREE",chCard) )
	{
		/* turn off free free heating and cooling */
		CoolHeavy.lgFreeOn = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("GRAI",chCard) )
	{
		if( lgMatch("NEUT",chCard) )
		{
			/* turn off ion grain recombination "NO GRAIN NEUTRALIZATION" */
			ionbal.lgGrainIonRecom = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else if( lgMatch("GAS ",chCard) && lgMatch("COLL",chCard) && lgMatch("ENER",chCard) )
		{
			/* turn off grain - gas collisional energy exchange 
			 * "NO GRAIN GAS COLLISIONAL ENERGY EXCHANGE " */
			gv.lgDColOn = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else if( lgMatch("ELEC",chCard) )
		{
			/* turn off grain contributions to electrons "NO GRAIN ELECTRONS" */
			gv.lgGrainElectrons = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else if( lgMatch("MOLE",chCard) )
		{
			/* turn off capture of molecules on grain surfaces "NO GRAIN MOLECULES" */
			mole.lgGrain_mole_deplete = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else if( lgMatch("QHEA",chCard) )
		{
			/* turn off quantum heating of grains "NO GRAIN QHEAT" */
			gv.lgQHeatOn = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else if( lgMatch("PHYSICS",chCard) )
		{
			/* turn off grain physics "NO GRAIN PHYSICS" */
			gv.lgGrainPhysicsOn = FALSE;
			phycon.lgPhysOK = FALSE;
		}
		else
		{
			fprintf( ioQQQ, " No key recognized on this line.\n" );
			puts( "[Stop in ParseDont]" );
			cdEXIT(EXIT_FAILURE);
		}
	}

	/* no induced processes */
	else if( lgMatch("INDU",chCard) )
	{
		/* turn off induced recombination, stimulated emission,
		 * continuum fluorescent excitation of lines, 
		 * stimulated emission correction to optical depths attenuation */
		rfield.lgInducProcess = FALSE;
	}

	/* no collisional ionization */
	else if( lgMatch("COLL",chCard) && lgMatch("IONI",chCard) )
	{
		/* turn off collisional ionization */
		atmdat.lgCollIonOn = FALSE;
	}

	else if( lgMatch("LEVE",chCard) )
	{
		/* turn off the set of level 2 lines, safe for lower densities 
		 * this is the upper limit to the counter that is always used,
		 * so no loops will ever occur */
		nWindLine = -1;
	}

	/* various no line options */
	else if( lgMatch("LINE",chCard) && !lgMatch(" OTS",chCard) )
	{
		if( lgMatch("DIFF",chCard) && lgMatch("PUMP",chCard) )
		{
			/* no diffuse line pumping, 
			* turn off pumping of lines by diffuse continuum*/
			rfield.DiffPumpOn = 0.;
		}
		else if( lgMatch("TRAN",chCard) )
		{
			/* no line transfer command */
			rfield.lgDoLineTrans = FALSE;
		}
		else
		{
			/* missing no line option */
			fprintf( ioQQQ, " There has to be an option on the NO LINE command.\n" );
			fprintf( ioQQQ, " The optinoas are DIFFUSE PUMP and TRANSFER.\n Sorry.\n" );
			puts( "[Stop in ParseDont]" );
			cdEXIT(EXIT_FAILURE);
		}
	}


	else if( lgMatch("OPAC",chCard) && lgMatch("REEVAL",chCard) )
	{
		/* don't constantly reevaluate the opacities */
		rfield.lgOpacityReevaluate = FALSE;
	}

	else if( lgMatch("IONI",chCard) && lgMatch("REEVAL",chCard) )
	{
		/* "no ionization reevaluation" - don't constantly reevaluate the ionization */
		rfield.lgIonizReevaluate = FALSE;
	}

	/* options to kill ots components as debugging aids */
	else if( lgMatch(" OTS",chCard) )
	{
		if( lgMatch(" LYA",chCard) )
		{
			/* turn off Lya ots rates - for debugging oscillations */
			rfield.lgLyaOTS = FALSE;
		}

		else if( lgMatch("HEII",chCard) )
		{
			/* turn off Lya ots rates - for debugging oscillations */
			rfield.lgHeIIOTS = FALSE;
		}

		else if( lgMatch("LINE",chCard) )
		{
			/* turn off line ots rates - for debugging oscillations */
			rfield.lgKillOTSLine = TRUE;
		}
	}

	/* options to kill outward compoents as a debugging aid */
	else if( lgMatch("OUTW",chCard) )
	{
		if( lgMatch("LINE",chCard) )
		{
			/* turn off Lya ots rates - for debugging oscillations */
			rfield.lgKillOutLine = TRUE;
		}
		else if( lgMatch("CONT",chCard) )
		{
			/* turn off Lya ots rates - for debugging oscillations */
			rfield.lgKillOutCont = TRUE;
		}
	}
	else if( lgMatch("MOLE",chCard) )
	{
		/* disable molecule formation, first option is to turn off only H2 part */
		if( lgMatch(" H2 ",chCard) )
		{
			/* turn off only H2 */
			hmi.lgNoH2Mole = TRUE;
		}
		else if( lgMatch(" CO ",chCard) )
		{
			/* turn off CO network */
			co.lgNoCOMole = TRUE;
		}
		else
		{
			/* turn off both CO and H2 networks */
			hmi.lgNoH2Mole = TRUE;
			co.lgNoCOMole = TRUE;
		}
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("PHOT",chCard) )
	{
		/* disable photoionization */
		ionbal.lgPhotoIoniz_On = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("RADI",chCard) )
	{
		/* don't include line radiation pressure */
		pressure.lgLineRadPresOn = FALSE;
	}

	else if( lgMatch("RECO",chCard) )
	{
		/* disable compton recoil of bound electrons - "no recoil ioniz" */
		ionbal.lgCompRecoil = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("SCAT",chCard) && lgMatch("OPAC",chCard))
	{
		/* no scattering opacity, for Compton thick spherical geometry */
		opac.lgScatON = FALSE;
	}

	else if( lgMatch("SCAT",chCard) && lgMatch("ESCA",chCard))
	{
		/* no electron scattering contribution to line escape probs */
		rt.lgElecScatEscape = FALSE;
	}

	else if( lgMatch("SECO",chCard) )
	{
		/* turn off secondary electron ionizations */
		secondaries.lgSecOFF = TRUE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("SPOT",chCard) )
	{
		/* no on-the-spot; turn on all ground state rec */
		opac.otsmin = 1.;
	}

	else if( lgMatch("STAR",chCard) )
	{
		/* no stark broadening */
		rt.lgStarkON = FALSE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("STAT",chCard) )
	{
		/* no static opacities - constantly reevaluate them */
		opac.lgOpacStatic = FALSE;
	}

	else if( lgMatch("TEPR",chCard) )
	{
		/* no tepredictor */
		/* turn off prediction of next zone's temperature, as guessed in ZoneStart */
		thermal.lgPredNextTe = FALSE;
	}

	else if( lgMatch("THRE",chCard) )
	{
		/* turn off Cota's three body rec subroutine */
		ionbal.lgNoCota = TRUE;
		phycon.lgPhysOK = FALSE;
	}

	else if( lgMatch("TIME",chCard) )
	{
		/* don't print anything with a time, so that we can expect
		 * perfect agreement between separate runs */
		prt.lgPrintTime = FALSE;
	}

	else if( lgMatch(" UTA",chCard) )
	{
		if( lgMatch( "ROMAS", chCard ) )
		{
			/* turn off only new romas inner shell absorption ionization */
			ionbal.lgInnerShell_Romas = FALSE;
		}
		else
		{
			/* turn off ALL inner shell absorption ionization */
			ionbal.lgInnerShellLine_on = FALSE;
			phycon.lgPhysOK = FALSE;
		}
	}

	/* the no vary command is parsed well before we get to this point,
	 * but we have to do something here or the parser will say that
	 * no command existed on the command line */
	else if( strncmp(chCard , "NO VARY" , 7 ) == 0 )
	{
		/* this is a no-nothing, picked up to stop optimizer */
		nshell = 0;
	}

	else
	{
		/* end of else if trap */
		fprintf( ioQQQ, " I dont understand what not to do.\n Sorry.\n" );
		puts( "[Stop in ParseDont]" );
		cdEXIT(EXIT_FAILURE);
	}

	/* this option, if keyword (OK) appears, then do not set warning */
	if( lgMatch("(OK)",chCard) )
	{
		/* say that physical conditions are actually ok */
		phycon.lgPhysOK = TRUE;
	}

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