/* 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 */
/*PrtLineSum parse print line sum command to enter set of lines into sum  */
#include "cddefines.h"
#include "cddrive.h"
#include "radius.h"
#include "lines.h"
#include "input.h"
/* this is the limit to the number of lines we can save */
#define	NRDSUM	300L
#include "prt.h"

double PrtLineSum( 
	/* the job to do, either " SUM" or "READ" */
	const char *chDo)
{
	char chCCap[INPUT_LINE_LENGTH], 
	  chCard[INPUT_LINE_LENGTH];

	/*static char chSMLab[NRDSUM][5];*/
	static char **chSMLab;
	int lgEND, 
	  lgEOF, 
	  lgEOL;
	long int i;
	static long int *ipLine;

	/* remember whether we have been called before */
	static int lgFirst=TRUE;

	/*static long int lamsm[NRDSUM], */
	static long nlsum;
	static float *wavelength ;

	double absint, 
	  relint ,
	  sum=-1.;

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

	if( strcmp(chDo,"READ") == 0 )
	{
#		if 0
		if( !lgFirst )
		{
			/* error - more than one read in input stream */
			fprintf(ioQQQ," more than one print line sum has appeared - only first one is used.\n");
			fprintf(ioQQQ," Sorry.\n");
			puts( "[Stop in PrtLineSum]" );
			cdEXIT(EXIT_FAILURE);
		}
		else
#		endif
		/* >>chng 03 jan 23, if not first call, do not allocate space, 
		 * had aborted, which was bad in optized runs, or in a grid. 
		 * Bug caught by Melekh Bohdan */
		if( lgFirst )
		{
			/* do not malloc space again */
			lgFirst = FALSE ;
			if( (wavelength = ((float *)MALLOC( sizeof(float )*NRDSUM )) ) == NULL )
				BadMalloc();

			/* create space for the array of array indices for lines*/
			if( (ipLine = ((long int *)MALLOC(NRDSUM*sizeof(long)))) == NULL )
				BadMalloc();

			/* create space for the array of labels*/
			if( (chSMLab = ((char **)MALLOC(NRDSUM*sizeof(char *)))) == NULL )
				BadMalloc();

			for( i=0; i<NRDSUM; ++i )
			{
				if( (chSMLab[i] = ((char *)MALLOC(5*sizeof(char )))) == NULL )
					BadMalloc();
			}
		}

		/* now read in lines */
		nlsum = 0;
		lgEND = FALSE;
		while( !lgEND )
		{
			input_readarray(chCard,&lgEOF);
			if( lgEOF )
			{
				fprintf( ioQQQ, " Hit EOF while reading line list; use END to end list.\n" );
				puts( "[Stop in PrtLineSum]" );
				cdEXIT(EXIT_FAILURE);
			}
			strcpy( chCCap, chCard );
			caps(chCCap);

			if( strncmp(chCCap , "END" , 3) != 0 )
			{
				if( nlsum >= NRDSUM )
				{
					fprintf( ioQQQ, 
						" Too many lines have been entered; the limit is %li.  Increase NRDSUM in PrtLineSum.\n", 
					  NRDSUM );
					puts( "[Stop in PrtLineSum]" );
					cdEXIT(EXIT_FAILURE);
				}

				/*  order on line is label (col 1-4), wavelength */
				strncpy( chSMLab[nlsum], chCCap , 4 );
				chSMLab[nlsum][4] = 0;
				i = 5;
				wavelength[nlsum] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
				/* check for optional micron or cm units, else interpret as Angstroms */
				if( input.chCARDCAPS[i-1] == 'M' )
				{
					/* microns */
					wavelength[nlsum] *= 1e4;
				}
				else if( input.chCARDCAPS[i-1] == 'C' )
				{
					/* microns */
					wavelength[nlsum] *= 1e8;
				}
				++nlsum;
			}
			else
			{
				lgEND = TRUE;
			}
		}
	}

	else if( strcmp(chDo," SUM" ) == 0 )
	{
		sum = 0.;
		/* this can be called during setup mode, in which case we do nothing */
		if( LineSave.ipass <= 0 )
		{ 
#			ifdef DEBUG_FUN
			fputs( " <->PrtLineSum()\n", debug_fp );
#			endif
			return( sum );
		}

		if( nzone == 1 )
		{
			for( i=0; i < nlsum; i++ )
			{
				/* save the array index for each line */
				if( (ipLine[i] = cdLine((char*)chSMLab[i],wavelength[i],&relint,&absint) ) <=0 )
				{
					fprintf( ioQQQ, " PrtLineSum could not fine line %4.4s %5f\n", 
					  chSMLab[i], wavelength[i] );
					puts( "[Stop in PrtLineSum]" );
					cdEXIT(EXIT_FAILURE);
				}
			}
		}

		/* now sum the line */
		for( i=0; i < nlsum; i++ )
		{
			/* this version of chLine uses index, does not search*/
			cdLine_ip(ipLine[i],&relint,&absint);
			absint = pow(10.,absint - radius.Conv2PrtInten);
			sum += absint;
		}
	}

	else
	{
		fprintf( ioQQQ, " unrecognized key for PrtLineSum=%s\n", 
		  chDo );
		puts( "[Stop in PrtLineSum]" );
		cdEXIT(EXIT_FAILURE);
	}

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