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

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

			    are_atoms_bound.c

Purpose:
	Check are two specified atoms covalently bound. Both atoms belong to
	the same macromolecular complex. If atoms are bound, store the array
	indices.

Input:
	(1) Pointer to size_t,  where the array index of the first atom will
	    be stored.
	(2) Pointer to size_t, where the array index of the second atom will
	    be stored.
	(3) Pointer to MolComplexS structure, pointing to the first complex.
	(4) The macromolecular complex index.
	(5) The serial number of the first atom.
	(6) The serial number of the second atom.

Output:
	(1) Return value.
	(2) Array index of the first atom.
	(3) Array index of the second atom.

Return value:
	(1) Positive if two atoms exist and are covalently bound.
	(2) Negative in all other cases.

Notes:
	(1) Disulfide bond and pseudo-bonds are not treated as covalent.

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

#include <stdio.h>

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

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

/*======check are two atoms bound:===========================================*/

int AreAtomsBound_ (size_t *atom1_arrayIP, size_t *atom2_arrayIP,
		    MolComplexS *mol_complexSP, int  mol_complexI,
		    int atom1_serialI, int atom2_serialI)
{
MolComplexS	*curr_mol_complexSP;
size_t		atomsN, atomI, atom1I = 0, atom2I = 0;
AtomS		*curr_atomSP;
int		serial1F, serial2F;
int		curr_atom_serialI;
AtomS		*atom1SP;
int		bonds1N, bond1I;
TrueBondS	*curr_bondSP;

/* Initialize array indices: */
*atom1_arrayIP = 0;
*atom2_arrayIP = 0;

/* Pointer to chosen macromolecular complex: */
curr_mol_complexSP = mol_complexSP + mol_complexI;

/* Prepare and check the number of atoms: */
atomsN = curr_mol_complexSP->atomsN;
if (atomsN == 0) return -1;

/* Initialize the flags which will signal */
/* the presence  of both  serial numbers: */
serial1F = 0;
serial2F = 0;

/* Scan the macromolecular complex: */
for (atomI = 0; atomI < atomsN; atomI++)
	{
	/* Pointer to the current atom: */
	curr_atomSP = curr_mol_complexSP->atomSP + atomI;

	/* Copy the atomic serial number: */
	curr_atom_serialI = curr_atomSP->raw_atomS.serialI;

	/* Compare the serial number of the current */
	/* atom  with   the  first  serial  number: */
	if (curr_atom_serialI == atom1_serialI)
		{
		atom1I = atomI;
		serial1F = 1;
		}

	/* Compare the serial number of the current */
	/* atom  with  the  second  serial  number: */
	if (curr_atom_serialI == atom2_serialI)
		{
		atom2I = atomI;
		serial2F = 1;
		}
	}

/* If one serial number was not found (or both), return negative value: */
if ((serial1F == 0) || (serial2F == 0)) return -2;

/* If this point is reached, both serial numbers */
/* were found.  Check is there  a covalent bond! */

/* Pointer to the atom specified by the first serial number: */
atom1SP = curr_mol_complexSP->atomSP + atom1I;

/* The number of bonds: */
bonds1N = atom1SP->bondsN;

/* Scan bonds: */
for (bond1I = 0; bond1I < bonds1N; bond1I++)
	{
	/* Pointer to the current bond: */
	curr_bondSP = atom1SP->true_bondSA + bond1I;

	/* If this is not a covalent bond, skip it: */
	if (curr_bondSP->bond_typeI != 1) continue;

	/* Check to which complex belongs the partner: */
	if (curr_bondSP->neighbor_mol_complexI != mol_complexI) continue;

	/* If this point is reached, this bond is covalent. Check who is the */
	/* partner - is it the atom  specified by  the second serial number? */
	if (curr_bondSP->neighbor_arrayI == atom2I)
		{
		*atom1_arrayIP = atom1I;
		*atom2_arrayIP = atom2I;
		return 1;
		}
	}

/* Return negative value if this point is reached: */
return -3;
}

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


