/* 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 */
/*punch_line parse punch lines command, or actually do the punch lines output */
#include "cddefines.h"
#include "cddrive.h"
#include "radius.h"
#include "input.h"
#include "prt.h"
#include "punch.h"
/* this is the limit to the number of lines we can store */
#define	NPUNLM	100L

void punch_line(FILE * ip, /* the file we will write to */
  char *chDo, 
  int lgLog3)
{
	char chCap[INPUT_LINE_LENGTH], 
	  chCard[INPUT_LINE_LENGTH];

	static char chPLab[NPUNLM][5];
	int lgEOF, 
	  lgEOL, 
	  lgOK;
	static int lgRelhld;
	long int i;
	static long int nLinesEntered;
	static float wavelength[NPUNLM];
	static long int ipLine[NPUNLM];
	double a[32], 
	  absint, 
	  emiss, 
	  relint;
	double dlum[NPUNLM];

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

	if( strcmp(chDo,"READ") == 0 )
	{
		/* very first time this routine is called, chDo is "READ" and we read
		 * in lines from the input stream.  The line labels and wavelengths
		 * are store locally, and output in later calls to this routine */
		lgRelhld = lgLog3;

		/* number of lines we will save */
		nLinesEntered = 0;

		/* get the next line, and check for eof */
		input_readarray(chCard,&lgEOF);
		if( lgEOF )
		{
			fprintf( ioQQQ, 
				" Hit EOF while reading line list; use END to end list.\n" );
			puts( "[Stop in punch_line]" );
			cdEXIT(EXIT_FAILURE);
		}

		/* convert line to caps */
		strcpy( chCap, chCard );
		caps(chCap);

		while( strncmp(chCap, "END" ,3 ) != 0 )
		{
			if( nLinesEntered >= NPUNLM )
			{
				fprintf( ioQQQ, 
					" Too many lines have been entered; the %ld limit is.  Increase variable NPUNLM in routine punch_line.\n", 
				  NPUNLM );
				puts( "[Stop in punch_line]" );
				cdEXIT(EXIT_FAILURE);
			}

			/* order on line is label (col 1-4), wavelength */
			strncpy( chPLab[nLinesEntered], chCard , 4 );

			/* null terminate the string*/
			chPLab[nLinesEntered][4] = 0;

			/* now get wavelength */
			i = 5;
			wavelength[nLinesEntered] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);

			/* now convert wavelength to angstroms */
			/* line was entered, look for possible micron or cm label */
			if( input.chCARDCAPS[i-1] == 'M' )
			{
				/* microns */
				wavelength[nLinesEntered] *= 1e4;
			}
			else if( input.chCARDCAPS[i-1] == 'C' )
			{
				/* microns */
				wavelength[nLinesEntered] *= 1e8;
			}

			/* this is total number stored so far */
			++nLinesEntered;

			/* get next line and check for eof */
			input_readarray(chCard,&lgEOF);
			if( lgEOF )
			{
				fprintf( ioQQQ, " Hit EOF while reading line list; use END to end list.\n" );
				puts( "[Stop in punch_line]" );
				cdEXIT(EXIT_FAILURE);
			}

			/* convert it to caps */
			strcpy( chCap, chCard );
			caps(chCap);
		}

		/*fprintf( ip, "%li lines were entered, they were;\n", 
		  nLinesEntered );*/

		fprintf( ip, "#depth\t");
		for( i=0; i < nLinesEntered; i++ )
		{
			fprintf( ip, "%s ", chPLab[i] );
			prt_wl(  ip, wavelength[i] );
			fprintf( ip, "\t" );
		}
		fprintf( ip, "\n" );
	}

	else if( strcmp(chDo,"PUNS") == 0 )
	{
		static int lgMustGetLines=TRUE;
		/* punch lines structure command */
		for( i=0; i < nLinesEntered; i++ )
		{
			if( nzone <= 1 && lgMustGetLines )
			{
				if( (ipLine[i] = cdEmis((char*)chPLab[i],wavelength[i],&emiss)) <= 0 )
				{
					/* next just to trick the lint */
					dlum[i] = emiss;
					fprintf( ioQQQ, " PUNLIN could not find line: %s %f\n", 
					  chPLab[i], wavelength[i] );
					puts( "[Stop in punch_line]" );
					cdEXIT(EXIT_FAILURE);
				}
			}
			/* 0th line is dummy, can't be used, so this is safe */
			ASSERT( ipLine[i] > 0 );
			/* this version of cdEmis uses index, does not search*/
			cdEmis_ip(ipLine[i],&dlum[i]);
		}
		lgMustGetLines = FALSE;

		/* print depth */
		fprintf( ip, "%.5e", radius.depth - radius.drad/2. );

		/* then print all line emissivity */
		for( i=0; i < nLinesEntered; i++ )
		{
			fprintf( ip, "\t%12.4e", dlum[i] );
		}
		fprintf( ip, "\n" );
	}

	else if( strcmp(chDo,"PUNC") == 0 )
	{
		/* punch lines cumulative command */
		for( i=0; i < nLinesEntered; i++ )
		{
			if( lgRelhld )
			{
				lgOK = (int)cdLine((char*)chPLab[i],wavelength[i],&a[i],&absint) ;
			}
			else
			{
				lgOK = (int)cdLine((char*)chPLab[i],wavelength[i],&relint,&a[i]) ;
			}

			if( lgOK<=0 )
			{
				fprintf( ioQQQ, " PUNLIN could not fine line: %s %f\n", 
				  chPLab[i], wavelength[i] );
				puts( "[Stop in punch_line]" );
				cdEXIT(EXIT_FAILURE);
			}
		}
		fprintf( ip, "%.5e", radius.depth - radius.drad/2. );

		for( i=0; i < nLinesEntered; i++ )
		{
			fprintf( ip, "%12.4e", a[i] );
		}
		fprintf( ip, "\n" );

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

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

