/* Copyright (C) 2001-2003 Damir Zucic */

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

				refresh_backbone.c

Purpose:
	Refresh the backbone information.

Input:
	(1) Pointer to  MolComplexS structure.
	(2) Pointer to ConfigS structure.

Output:
	(1) The array of BackboneS structures refreshed.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Zero if there are no atoms.

========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:=================================================*/

void		ErrorMessage_ (char *, char *, char *,
			       char *, char *, char *, char *);

/*======refresh backbone data:===============================================*/

int RefreshBackbone_ (MolComplexS *mol_complexSP, ConfigS *configSP)
{
size_t		atomI, atomsN;
AtomS		*curr_atomSP;
int		c_alphaI = 0;
BackboneS	*curr_backboneSP;
size_t		atom1I, atom2I;
AtomS		*atom0SP, *atom1SP, *atom2SP;
double		x0, y0, z0, x1, y1, z1, x2, y2, z2, delta_x, delta_y, delta_z;
double		d1_squared, d2_squared;
double		max_dist_squared;

/* Return zero if there are no atoms in this macromolecular complex: */
atomsN = mol_complexSP->atomsN;
if (atomsN == 0) return 0;

/* The maximal distance squared: */
max_dist_squared = configSP->CA_CA_dist_max_squared;

/* Initialize the BackboneS pointer: */
curr_backboneSP = mol_complexSP->backboneSP;

/* Scan the macromolecular complex and copy */
/* the updated array indices of  CA  atoms: */
for (atomI = 0; atomI < atomsN; atomI++)
	{
	/** Pointer to the current atom: **/
	curr_atomSP = mol_complexSP->atomSP + atomI;

	/** Check the purified atom name: **/
	if (strcmp (curr_atomSP->raw_atomS.pure_atom_nameA, "CA") != 0)
			continue;

	/** Pointer to the current BackboneS structure: **/
	curr_backboneSP = mol_complexSP->backboneSP + c_alphaI;

	/** Copy the index of the current atom: **/
	curr_backboneSP->c_alphaI = atomI;

	/** Update and check the counter of CA atoms: **/
	c_alphaI++;
	if (c_alphaI >= (int) mol_complexSP->c_alphaN) break;
	}

/* Check distances between neighbouring CA atoms: */
for (c_alphaI = 0; c_alphaI < (int) mol_complexSP->c_alphaN; c_alphaI++)
	{
	/** Pointer to the current BackboneS: **/
	curr_backboneSP = mol_complexSP->backboneSP + c_alphaI;

	/** Pointer to the current CA atom: **/
	atom0SP = mol_complexSP->atomSP + curr_backboneSP->c_alphaI;

	/** Position of the current CA atom: **/
	x0 = atom0SP->raw_atomS.x[0];
	y0 = atom0SP->raw_atomS.y;
	z0 = atom0SP->raw_atomS.z[0];

	/** Check distances between current CA, previous CA and next CA: **/

	/*** For the first CA, the previous CA does not exist: ***/
	if (c_alphaI > 0)
		{
		atom1I = (curr_backboneSP - 1)->c_alphaI;
		atom1SP = mol_complexSP->atomSP + atom1I;
		x1 = atom1SP->raw_atomS.x[0];
		y1 = atom1SP->raw_atomS.y;
		z1 = atom1SP->raw_atomS.z[0];
		delta_x = x1 - x0;
		delta_y = y1 - y0;
		delta_z = z1 - z0;
		d1_squared = delta_x * delta_x +
			     delta_y * delta_y +
			     delta_z * delta_z;
		if (d1_squared <= max_dist_squared)
			{
			curr_backboneSP->previous_c_alphaF = 1;
			curr_backboneSP->previous_c_alphaI = atom1I;
			}
		else curr_backboneSP->previous_c_alphaF = 0;
		}

	/*** For the last CA, the next CA does not exist: ***/
	if (c_alphaI < (int) mol_complexSP->c_alphaN - 1)
		{
		atom2I = (curr_backboneSP + 1)->c_alphaI;
		atom2SP = mol_complexSP->atomSP + atom2I;
		x2 = atom2SP->raw_atomS.x[0];
		y2 = atom2SP->raw_atomS.y;
		z2 = atom2SP->raw_atomS.z[0];
		delta_x = x2 - x0;
		delta_y = y2 - y0;
		delta_z = z2 - z0;
		d2_squared = delta_x * delta_x +
			     delta_y * delta_y +
			     delta_z * delta_z;
		if (d2_squared <= max_dist_squared)
			{
			curr_backboneSP->next_c_alphaF = 1;
			curr_backboneSP->next_c_alphaI = atom2I;
			}
		else curr_backboneSP->next_c_alphaF = 0;
		}
	}

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

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


