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

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

				select_below.c

Purpose:
	Select atoms below the plane. The normal vector defines what is up
	and what is down.

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 <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

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

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

double		ScalarProduct_ (VectorS *, VectorS *);

/*======select atoms below the plane:========================================*/

long SelectBelow_ (MolComplexS *mol_complexSP, int mol_complexesN,
		   int selection_modeI)
{
long		selected_atomsN = 0;
int		mol_complexI;
MolComplexS	*curr_mol_complexSP;
size_t		atomsN, atomI;
VectorS		normal_vectorS;
double		plane_center_x, plane_center_y, plane_center_z;
AtomS		*curr_atomSP;
double		x, y, z;
VectorS		curr_vectorS;
int		belowF;

/* Select all atoms below the plane: */
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;

	/* Number of atoms in a macromolecular complex: */
	atomsN = curr_mol_complexSP->atomsN;
	if (atomsN == 0) continue;

	/* The normal vector: */ 
	normal_vectorS.x = curr_mol_complexSP->planeS.normal_x[0];
	normal_vectorS.y = curr_mol_complexSP->planeS.normal_y;
	normal_vectorS.z = curr_mol_complexSP->planeS.normal_z[0];

	/* Position of the plane center: */
	plane_center_x = curr_mol_complexSP->planeS.center_x[0];
	plane_center_y = curr_mol_complexSP->planeS.center_y;
	plane_center_z = curr_mol_complexSP->planeS.center_z[0];

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

		/* Copy the coordinates: */
		x = curr_atomSP->raw_atomS.x[0];
		y = curr_atomSP->raw_atomS.y;
		z = curr_atomSP->raw_atomS.z[0];

		/* Position of the atom relative to the plane center: */
		curr_vectorS.x = x - plane_center_x;
		curr_vectorS.y = y - plane_center_y;
		curr_vectorS.z = z - plane_center_z;

		/* Reset the flag: */
		belowF = 0;

		/* Check the sign of the scalar product: */
		if (ScalarProduct_ (&curr_vectorS, &normal_vectorS) < 0)
			{
			belowF = 1;
			}

		/* Set the selection flag for the current atom: */
		switch (selection_modeI)
			{
			/* Overwrite the previous selection: */
			case 0:
				curr_atomSP->selectedF = belowF;
				break;

			/* Restrict the previous selection: */
			case 1:
				curr_atomSP->selectedF &= belowF;
				break;

			/* Expand the previous selection: */
			case 2:
				curr_atomSP->selectedF |= belowF;
				break;

			default:
				;
			}

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

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

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


