/* Copyright (C) 2004 Damir Zucic */

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

				select_5cz7.c

Purpose:
	Select the sequence fragment which contains  five or more charged
	or zwitterionic residues in a window of seven residues. ASP, GLU,
	ASN, GLN, ARG, LYS and HIS are taken into account.

Input:
	(1) Pointer to MolComplexS structure, with macromol. complexes.
	(2) Number of macromolecular complexes.
	(3) Selection mode index (0 = overwrite, 1 = restrict, 2 = expand
	    previous selection).

Output:
	(1) The  flag  selectedF  set to one for selected atoms  in every
	    caught macromolecular complex.
	(2) Return value.

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

========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"

/*======select five or more charged or zwitterionic residues:================*/

long Select5CZ7_ (MolComplexS *mol_complexSP, int mol_complexesN,
		  int selection_modeI)
{
long		selected_atomsN = 0;
int		mol_complexI;
MolComplexS	*curr_mol_complexSP;
int		atomsN, atomI;
AtomS		*curr_atomSP;
int		residuesN, residueI, windowI, combinedI;
ResidueS	*curr_residueSP;
AtomS		*first_atomSP;
char		*nameP;
int		very_polarN;
int		first_atomI, last_atomI;

/* Check every macromolecular complex: */
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
	{
	/* Pointer to the current macromolecular complex: */
	curr_mol_complexSP = mol_complexSP + mol_complexI;

	/* Check is the current macromolecular complex caught: */
	if (curr_mol_complexSP->catchF == 0) continue;

	/* Prepare and check the number of atoms in the current complex: */
	atomsN = curr_mol_complexSP->atomsN;
	if (atomsN == 0) continue;

        /* Copy the number of residues in the current macromol. complex: */
        residuesN = curr_mol_complexSP->residuesN;
	if (residuesN == 0) continue;

	/* Backup the current selection if selection mode is restrict: */
	if (selection_modeI == 1)
		{
		for (atomI = 0; atomI < atomsN; atomI++)
			{
			/* Pointer to the current atom: */
			curr_atomSP = curr_mol_complexSP->atomSP + atomI;

			/* Copy the selection flag: */
			curr_atomSP->previous_selectedF =
						curr_atomSP->selectedF;
			}
		}

	/* Unselect everything if selection mode is overwrite or restrict: */
	if ((selection_modeI == 0) || (selection_modeI == 1))
		{
		for (atomI = 0; atomI < atomsN; atomI++)
			{
			/* Pointer to the current atom: */
			curr_atomSP = curr_mol_complexSP->atomSP + atomI;

			/* Unselect the current atom: */
			curr_atomSP->selectedF = 0;
			}
		}

	/* Scan the residues of the current macromolecular complex: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Reset the counter which counts very polar residues: */
		very_polarN = 0;

		/* Scan the window of seven residues, */
		/* starting from the current residue: */
		for (windowI = 0; windowI < 7; windowI++)
			{
			/* Prepare and check the combined index: */
			combinedI = residueI + windowI;
			if (combinedI >= residuesN) break;

			/* Residue associated with the combined index: */
			curr_residueSP = curr_mol_complexSP->residueSP +
					 combinedI;

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

			/* Pointer to the name of the current residue: */
			nameP = first_atomSP->raw_atomS.pure_residue_nameA;

			/* Check is this residue very polar: */
			if ((strcmp (nameP, "ASP") == 0) ||
			    (strcmp (nameP, "GLU") == 0) ||
			    (strcmp (nameP, "ASN") == 0) ||
			    (strcmp (nameP, "GLN") == 0) ||
			    (strcmp (nameP, "ARG") == 0) ||
			    (strcmp (nameP, "LYS") == 0) ||
			    (strcmp (nameP, "HIS") == 0)) very_polarN++;
			}

		/* If there were  five or more very polar residues in */
		/* a window of seven residues,  the quintet is found. */
		/* If there were four or less, take the next residue. */
		if (very_polarN < 5) continue;

		/* If this point is reached, scan the window of seven */
		/* residues  again  and select  very polar  residues. */

		/* Scan the window of seven residues, */
		/* starting from the current residue: */
		for (windowI = 0; windowI < 7; windowI++)
			{
			/* Prepare and check the combined index: */
			combinedI = residueI + windowI;
			if (combinedI >= residuesN) break;

			/* Residue associated with the combined index: */
			curr_residueSP = curr_mol_complexSP->residueSP +
					 combinedI;

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

			/* Pointer to the name of the current residue: */
			nameP = first_atomSP->raw_atomS.pure_residue_nameA;

			/* Check is this residue very polar: */
			if ((strcmp (nameP, "ASP") != 0) &&
			    (strcmp (nameP, "GLU") != 0) &&
			    (strcmp (nameP, "ASN") != 0) &&
			    (strcmp (nameP, "GLN") != 0) &&
			    (strcmp (nameP, "ARG") != 0) &&
			    (strcmp (nameP, "LYS") != 0) &&
			    (strcmp (nameP, "HIS") != 0)) continue;

			/* If this point is reached,  select */
			/* all atoms of the current residue. */

			/* The indices of the first  and the */
			/* last atom of the current residue: */
			first_atomI = curr_residueSP->residue_startI;
			last_atomI  = curr_residueSP->residue_endI;

			/* Select all atoms of the current residue: */
			for (atomI = first_atomI; atomI <= last_atomI; atomI++)
				{
				/* Pointer to the current atom: */
				curr_atomSP = curr_mol_complexSP->atomSP +
					      atomI;

				/* Select the current atom: */
				curr_atomSP->selectedF = 1;

				/* Update the counter of selected atoms: */
				selected_atomsN++;
				}
                        }

		/* End of residueI loop: */
		}

	/* Combine  the current selection  with the */
	/* previous, if selection mode is restrict: */
	if (selection_modeI == 1)
		{
		/* Reset the counter of selected atoms. The */
		/* selected atoms should be  counted again. */
		selected_atomsN = 0;

		/* Combine the old and the new selection flag: */
		for (atomI = 0; atomI < atomsN; atomI++)
			{
			/* Pointer to the current atom: */
			curr_atomSP = curr_mol_complexSP->atomSP + atomI;

			/* Combine selection flags: */
			curr_atomSP->selectedF *=
					curr_atomSP->previous_selectedF;

			/* Check the selection flag;  increase */
			/* the count of  selected  residues if */
			/* the selection flag is equal to one: */
			if (curr_atomSP->selectedF) selected_atomsN++;
			}
		}

	/* Update the position_changedF (some atoms may have bad color): */
	curr_mol_complexSP->position_changedF = 1;

	/* End of mol_complexI loop: */
	}

/* Return the number of selected atoms: */
return selected_atomsN;
}

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


