/* Copyright (C) 2001 Damir Zucic */

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

				edit_psi.c

Purpose:
	Edit psi angle. If edit_single_bondF is zero, edit psi for every
	selected residue in the specified macromolecular complex. If the
	flag edit_single_bondF is different from zero, edit only the psi
	angle for the bond specified by the given  atomic array indices.
	A residue  is treated  as selected  if the  first  atom  of this
	residue is selected.  For protein residues,  this is typically N
	atom (nitrogen).

Input:
	(1) Pointer to MolComplexS structure.
	(2) Pointer to RuntimeS structure.
	(3) Pointer to ConfigS structure.
	(4) Rotation angle.

Output:
	(1) Psi angle changed for chosen residue(s).
	(2) Return value.

Return value:
	(1) Positive always (trivial).

========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 "typedefs.h"

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

int		ExtractCAC_ (VectorS *, VectorS *, AtomS *, size_t, size_t);
int		RotateAtom_ (AtomS *, VectorS *, VectorS *, double);
int		DihedralAngles_ (MolComplexS *, ConfigS *);

/*======change psi angle for selected residues:==============================*/

int EditPsi_ (MolComplexS *mol_complexSP,
	      RuntimeS *runtimeSP, ConfigS *configSP,
	      double delta_psi)
{
int			residuesN, residueI;
size_t			atomsN;
ResidueS		*residueSP;
size_t			atom_startI, atom_endI, atomI;
AtomS			*atomSP;
int			n;
static VectorS		CA_vectorS, C_vectorS;

/* Copy the number of residues in the current complex: */
residuesN = mol_complexSP->residuesN;

/* Copy the number of atoms in the current complex: */
atomsN = mol_complexSP->atomsN;

/* Scan residues: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Pointer to the current residue: */
	residueSP = mol_complexSP->residueSP + residueI;

	/* Prepare the atomic index range: */
	atom_startI = residueSP->residue_startI;
	atom_endI   = residueSP->residue_endI;

	/* Pointer to the first atom: */
	atomSP = mol_complexSP->atomSP + atom_startI;

	/* Check the edit_single_bondF flag. If this flag is equal */
	/* to zero,  the current  selection  should be  taken into */
	/* account.  Otherwise,  the selection  should be ignored. */

	/* Editing of a single psi angle requested: */
	if (runtimeSP->edit_single_bondF)
		{
		/* Check the array indices of CA and C: */
		if ((runtimeSP->atom1_arrayI < atom_startI) ||
		    (runtimeSP->atom1_arrayI > atom_endI)   ||
		    (runtimeSP->atom2_arrayI < atom_startI) ||
		    (runtimeSP->atom2_arrayI > atom_endI))
			{
			continue;
			}
		}

	/* Editing of psi angles for all selected residues requested: */
	else
		{
		/* If the first atom of the current residue is */
		/* not selected,  the residue is not selected: */
		if (atomSP->selectedF == 0) continue;
		}

	/* Extract CA and C coordinates: */
	n = ExtractCAC_ (&CA_vectorS, &C_vectorS,
			 mol_complexSP->atomSP, atom_startI, atom_endI);
	if (n < 2) continue;

	/* Change the psi angle: */
	for (atomI = atom_startI; atomI <= atom_endI; atomI++)
		{
		/* Pointer to the current atom: */
		atomSP = mol_complexSP->atomSP + atomI;

		/* Rotate only the O atom: */
		if (strcmp (atomSP->raw_atomS.pure_atom_nameA, "O") != 0)
			{
			continue;
			}

		/* If this point is reached, rotate O atom about CA-C bond: */
		RotateAtom_ (atomSP, &CA_vectorS, &C_vectorS, delta_psi);
		}

	/* Rotate all atoms after the current residue about CA-C bond: */
	for (atomI = atom_endI + 1; atomI < atomsN; atomI++)
		{
		/* Pointer to the current atom: */
		atomSP = mol_complexSP->atomSP + atomI;

		/* Rotate atom: */
		RotateAtom_ (atomSP, &CA_vectorS, &C_vectorS, delta_psi);
		}
	}

/* Update dihedral angles and cis-trans flags: */
DihedralAngles_ (mol_complexSP, configSP);

/* Return positive value (trivial): */
return 1;
}

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


