/* Copyright (C) 2000 Damir Zucic */

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

			    sec_structure_from.c

Purpose:
	Copy the secondary structure  from the specified macromolecular
	complex to  the secondary structure buffer.  Only the structure
	for selected range(s) is copied.  A given residue is treated as
	selected if  the first atom of  this residue  is selected.  For
	proteins, this is typically N.

Input:
	(1) Pointer to MolComplexS structure, with macromol. complexes.
	(2) The number of macromolecular complexes.
	(3) Pointer to RuntimeS structure.
	(4) Pointer to the string which contains  the macromol. complex
	    identifier.

Output:
	(1) Secondary structure from the specified complex is copied to
	    the secondary structure buffer.
	(2) Return value.

Return value:
	(1) Positive (command) code on success.
	(2) Negative (error) code on failure.

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

#include <stdio.h>

#include <string.h>

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

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

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

char		*ExtractToken_ (char *, int, char *, char *);

/*======copy secondary structure from complex to sec. str. buffer:===========*/

int SecondaryStructureFrom_ (MolComplexS *mol_complexSP, int mol_complexesN,
			     RuntimeS *runtimeSP, char *stringP)
{
char			*remainderP;
char			tokenA[SHORTSTRINGSIZE];
int			complexID;
int			mol_complexI;
static MolComplexS	*curr_mol_complexSP;
int			job_doneF = 0;
size_t			residueI, residuesN;
size_t			selected_residueI = 0;
ResidueS		*curr_residueSP;
AtomS			*first_atomSP;

/* At least one macromolecular complex should be available: */
if (mol_complexesN == 0)
	{
	strcpy (runtimeSP->messageA, "No structure loaded!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return -1;
	}

/* Take the first token; it should be present: */
remainderP = ExtractToken_ (tokenA, SHORTSTRINGSIZE, stringP, " \t\n");
if (!remainderP)
	{
	strcpy (runtimeSP->messageA, "Complex identifier missing!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return -2;
	}

/* Extract the macromolecular complex identifier: */
if (sscanf (tokenA, "%d", &complexID) != 1)
	{
	strcpy (runtimeSP->messageA, "Bad macromolecular complex identifier!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return -3;
	}

/* Check is the requested complex available at all: */
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
	{
	/** Prepare the pointer to the current macromolecular complex: **/
	curr_mol_complexSP = mol_complexSP + mol_complexI;

	/* Check the number of atoms;  for bad */
	/* and discarded complexes it is zero: */
	if (curr_mol_complexSP->atomsN == 0) continue;

	/* If macromol. complex is recognized, set the catch flag to one: */
	if (curr_mol_complexSP->mol_complexID == complexID)
		{
		job_doneF = 1;
		break;
		}
	}

/* If the requested complex is not available, return negative value: */
if (job_doneF == 0)
	{
	strcpy (runtimeSP->messageA,
		"The requested complex is not available!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return -4;
	}

/* Prepare the number of residues: */
residuesN = curr_mol_complexSP->residuesN;

/* Copy the secondary structure (for selected residues only): */
residuesN = curr_mol_complexSP->residuesN;
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Pointer to the current residue: */
	curr_residueSP = curr_mol_complexSP->residueSP + residueI;

	/* Pointer to the first atom: */
	first_atomSP = curr_mol_complexSP->atomSP +
		       curr_residueSP->residue_startI;

	/* If the first atom is not selected, do not copy the residue name: */
	if (first_atomSP->selectedF == 0) continue;

	/* Copy the secondary structure code: */
	*(runtimeSP->sec_structureP + selected_residueI) =
			*(curr_mol_complexSP->secondary_structureP + residueI);

	/* Update the selected residue index: */
	selected_residueI++;

	/* Check the number of selected residues: */
	if (selected_residueI >= MAXRESIDUES)
		{
		strcpy (runtimeSP->messageA,
			"Secondary structure too long!");
		runtimeSP->message_length = strlen (runtimeSP->messageA);
		return -5;
		}
	}

/*@@*/ /* This function should be tested with a real structure! */

/* Return positive value on success: */
return 1;
}

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


