/* Copyright (C) 2001, 2002 Damir Zucic */

/*=============================================================================

			     read_template_file.c

Purpose:
	Read  the template file  (file with atomic templates).  These data
	will be used later to create new peptides and to replace or insert
	the residues. The input file format should be compatible with PDB.

Input:
	(1) Pointer to RuntimeS structure.
	(2) Pointer to the template file.
	(3) Pointer to ConfigS structure.

Output:
	(1) Atomic data stored to RuntimeS structure.
	(2) Return value.

Return value:
	(1) The number of atoms read (zero or positive).

========includes:============================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======function prototypes:=================================================*/

int		ParsePDBAtomicData_ (AtomS *, char *);
int		ExtractTemplateResidues_ (RuntimeS *);

/*======read template file:==================================================*/

int ReadTemplateFile_ (RuntimeS *runtimeSP,
		       FILE *template_fileP, ConfigS *configSP)
{
size_t		rgb_struct_size;
int		line_size;
char		lineA[STRINGSIZE];
int		first_char;
int		rec_typeI = 0;
int		template_atomI = 0;
AtomS		*curr_atomSP;
int		surfaceI;

/* Prepare the size of the RGBS structure: */
rgb_struct_size = sizeof (RGBS);

/* Prepare the line_size: */
line_size = sizeof (lineA);

/* Read the entire file, line by line: */
while (fgets (lineA, line_size, template_fileP))
	{
	/* Prepare the first character, it will be used */
	/* to speed up the recognition of  record type: */
	first_char = *lineA;

	/* Check is there a chance that input line is ATOM or HETATM record: */
	rec_typeI = 0;
	switch (first_char)
		{
		case 'A':
			if (strstr (lineA, "ATOM") == lineA) rec_typeI = 1;
			break;
		case 'H':
			if (strstr (lineA, "HETATM") == lineA) rec_typeI = 2;
			break;
		default:
			;
		}

	/* Ignore this line if it is neither ATOM nor HETATM record: */
	if (rec_typeI == 0) continue;

	/* If this point is reached,  extract data if */
	/* input line contains ATOM or HETATM record: */

	/* Prepare the pointer to the current atom: */
	curr_atomSP = runtimeSP->template_atomSP + template_atomI;

	/* Try to parse ATOM or HETATM line: */
	if (ParsePDBAtomicData_ (curr_atomSP, lineA) < 0) continue;

	/* If this point is reached, parsing was successful! */

	/* The initial drawing style for atoms: */
	curr_atomSP->raw_atomS.atom_styleI = configSP->default_atom_styleI;

	/* Initialize the model serial number (trivial value): */
	curr_atomSP->raw_atomS.model_serialI = 0;

	/* Initialize the selection flag: */
	curr_atomSP->selectedF = 1;

	/* Initialize the hiddenF: */
	curr_atomSP->hiddenF = 0;

	/* Put the atom inside the slab: */
	curr_atomSP->inside_slabF = 1;

	/* Hide atomic label: */
	curr_atomSP->labelF = 0;

	/* Set flag which distinguishes ATOM and HETATM data: */
	if (rec_typeI == 1) curr_atomSP->raw_atomS.heteroF = 0;
	else curr_atomSP->raw_atomS.heteroF = 1;

	/* Set the number of color fading surfaces: */
	curr_atomSP->surfacesN = configSP->default_surfacesN;

	/* Copy default basic colors: */
	for (surfaceI = 0; surfaceI < MAXCOLORSURFACES; surfaceI++)
		{
		memcpy (curr_atomSP->left_rgbSA + surfaceI,
			configSP->left_rgbSA + surfaceI,
			rgb_struct_size);
		memcpy (curr_atomSP->middle_rgbSA + surfaceI,
			configSP->middle_rgbSA + surfaceI,
			rgb_struct_size);
		memcpy (curr_atomSP->right_rgbSA + surfaceI,
			configSP->right_rgbSA + surfaceI,
			rgb_struct_size);
		}

	/* Increment the counter: */
	template_atomI++;

	/* Do not allow memory leak: */
	if (template_atomI >= MAXTEMPLATEATOMS) break;
	}

/* Store the number of template atoms: */
runtimeSP->template_atomsN = template_atomI;

/* Initialize the residue data. If this function failes, the template */
/* file was bad; free storage and reset the number of template atoms. */
if (ExtractTemplateResidues_ (runtimeSP) < 0)
	{
	runtimeSP->template_atomsN = 0;
	if (runtimeSP->template_atomSP)
		{
		free (runtimeSP->template_atomSP);
		runtimeSP->template_atomSP = NULL;
		}
	return 0;
	}

/* Return the number of template atoms on success: */
return template_atomI;
}

/*===========================================================================*/


