/* 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 */
/*cdGetLineList routine to read in master list of emission line wavelengths and ids, for
 * generating loc grids,
 * someday add cdGetNLRLineList */
#include "cddefines.h"
#include "path.h"
#include "cddrive.h"

/* return value is number of lines, -1 if file could not be opened */
long int cdGetLineList( 
	/* chFile is optional filename, if void then use BLRLineList,
	 * if not void then use file specified */
	 char chFile[] ,
	/* 2d array of null term strings giving line labels char chLabels[nLines][10] */
	char ***chLabels ,
	/* a 1-d array of line wavelengths */
	float **wl )
{
	long int i ,
		nLines;
	int lgDONE;
	FILE *ioData ;

	char chFile1[FILENAME_PATH_LENGTH_2];

	char chLine[FILENAME_PATH_LENGTH_2] , chFilename[FILENAME_PATH_LENGTH_2]  ;

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

	/* first check that cdInit has been called, since we may have to write
	 * error output */
	if( !lgcdInitCalled )
	{
		fprintf(stderr," cdInit must be called before cdGetLineList.\n");
		cdEXIT(EXIT_FAILURE);
	}

	/* use default filename LineList_BLR.dat if void string, else use file specified */
	if( strlen( chFile )==0 )
	{
		/* void string, use default name */
		strcpy( chFile1 , "LineList_BLR.dat" );
	}
	else
	{
		/* not void, use filename given us */
		strcpy( chFile1 , chFile );
	}

	/* >>chng 04 nov 06, had searched only on path, now search locally 
	 * and then on path if not found */
	/* we will check local space first, then on path if not present */
	strcpy( chFilename , chFile1 );

	if( ( ioData = fopen( chFilename , "r" ) ) == NULL )
	{
		/* could not open locally, check if path set then check there if is set */
		if( lgDataPathSet == TRUE )
		{
			/*path set, so look there */
			strcpy( chFilename , chDataPath );
			strcat( chFilename , chFile1 );
			if( ( ioData = fopen( chFilename , "r" ) ) == NULL )
			{
				fprintf( ioQQQ, " cdGetLineList could not open line list\n" );
				if( lgDataPathSet == TRUE )
					fprintf( ioQQQ, " even tried path\n" );

				if( lgDataPathSet == TRUE )
				{
					fprintf( ioQQQ, " cdGetLineList could not open line list\n");
					fprintf( ioQQQ, " path is ==%s==\n",chDataPath );
					fprintf( ioQQQ, " final path is ==%s==\n",chFilename );
				}

				return( -1 );
			}
		}
	}

	/* count how many lines are in the file, ignoring all lines
	 * starting with '#' */
	nLines = 0;
	lgDONE = FALSE;
	/*lint -e668 passing null pointer */
	while( (fgets( chLine , (int)sizeof(chLine) , ioData ) != NULL) && !lgDONE )
	{
		if( chLine[0] == '\n')
		{
			lgDONE = TRUE;
			continue;
		}

		/* we want to count the lines that do not start with #
		 * since these contain data */
		if( (chLine[0] != '#') )
			++nLines;
	}
	/*lint +e668 passing null pointer */

	if( (*wl = (float *)MALLOC( (size_t)(nLines+1)*sizeof(float ) )) == NULL )
		BadMalloc();

	/* create 1-d array of string labels */
	/* create first dim of space for labels */
	if( (*chLabels = (char**)MALLOC((size_t)(nLines+1)*sizeof(char *) )) == NULL )
		BadMalloc();

	/* now rewind the file so we can read it a second time*/
	if( fseek( ioData , 0 , SEEK_SET ) != 0 )
	{
		fprintf( ioQQQ, " cdGetLineList could not rewind line list.\n");
		return( -1 );
	}

	/* actually read and save the lines */
	i = 0;
	lgDONE = FALSE;
	while( (fgets( chLine , (int)sizeof(chLine) , ioData ) != NULL) && !lgDONE)
	{
		long j;
		int lgEOL;

		if( chLine[0] == '\n')
		{
			lgDONE = TRUE;
			continue;
		}
		/* skip lines that begin with # */
		if( chLine[0] == '#')
			continue;

		/* create second dim of space for labels */
		if( ((*chLabels)[i] = (char*)MALLOC(5*sizeof(char) )) == NULL )
			BadMalloc();

		strncpy( (*chLabels)[i] , chLine , 4);
		(*chLabels)[i][4] = 0;

		/* get and save the wavelength */
		j = 5;
		(*wl)[i] = (float)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);

		/* check for optional micron or cm units, else interpret as Angstroms */
		if( chLine[j-1] == 'M' || chLine[j-1] == 'm')
		{
			/* microns */
			(*wl)[i] *= 1e4;
		}
		else if( chLine[j-1] == 'C'  || chLine[j-1] == 'c')
		{
			/* centimeters */
			(*wl)[i] *= 1e8;
		}

		++i;
	}

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

	/* return number of lines we found */
	return nLines;
}

