/* Copyright (C) 2000 Damir Zucic */

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

				extent.c

Purpose:
	Find the spatial extent of a given macromolecular complex.

Input:
	(1) Pointer to  MolComplexS structure,  with macromolecular data.
	    Input data are read from this structure;  output data will be
	    stored there too.

Output:
	(1) Two output vectors prepared.
	(2) Return value.

Return value:
	(1) Positive if macromol. complex contains at least one atom.
	(2) Zero, if there are no atoms.

Notes:
        (1) The absolute coordinate system has the following orientation:

              |
              |
            -(X)----------> x     ... z points  inside - the
              | z                     system is right-handed
              |
              |
              V y

	    See also  a small pixmap  in the top left corner  of the main
	    window.

	(2) The minimal extent in each dimension is 5.0 angstroms.

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

/*======find spatial extent:=================================================*/

int ComplexExtent_ (MolComplexS *mol_complexSP)
{
size_t		atomI, atomsN;
AtomS		*curr_atomSP;
double		x_min, x_max, y_min, y_max, z_min, z_max;
double		x, y, z;
double		x_extent, y_extent, z_extent, max_extent;

/* Initialize extent vectors: */
mol_complexSP->left_top_near_vectorS.x    = 0.0;
mol_complexSP->left_top_near_vectorS.y    = 0.0;
mol_complexSP->left_top_near_vectorS.z    = 0.0;
mol_complexSP->right_bottom_far_vectorS.x = 0.0;
mol_complexSP->right_bottom_far_vectorS.y = 0.0;
mol_complexSP->right_bottom_far_vectorS.z = 0.0;

/* Return if there are no atoms: */
atomsN = mol_complexSP->atomsN;
if (atomsN == 0) return 0;

/* Initialize extreme values using the coordinates of the first atom: */
x_min = mol_complexSP->atomSP->raw_atomS.x[0];
x_max = x_min;
y_min = mol_complexSP->atomSP->raw_atomS.y;
y_max = y_min;
z_min = mol_complexSP->atomSP->raw_atomS.z[0];
z_max = z_min;

/* Find new extreme values; skip the first atom: */
for (atomI = 1; atomI < atomsN; atomI++)
	{
	/** Current AtomS pointer: **/
	curr_atomSP = mol_complexSP->atomSP + atomI;

	/** Min./max.: **/
	x = curr_atomSP->raw_atomS.x[0];
	y = curr_atomSP->raw_atomS.y;
	z = curr_atomSP->raw_atomS.z[0];
	if (x < x_min) x_min = x;
	if (y < y_min) y_min = y;
	if (z < z_min) z_min = z;
	if (x > x_max) x_max = x;
	if (y > y_max) y_max = y;
	if (z > z_max) z_max = z;
	}

/* The extent in all three dimensions */
/* should be at least  5.0 angstroms: */
if (x_max - x_min < 5.0)
	{
	x_min = -2.5;
	x_max =  2.5;
	}
if (y_max - y_min < 5.0)
	{
	y_min = -2.5;
	y_max =  2.5;
	}
if (z_max - z_min < 5.0)
	{
	z_min = -2.5;
	z_max =  2.5;
	}

/* Set new values: */
mol_complexSP->left_top_near_vectorS.x    = x_min;
mol_complexSP->left_top_near_vectorS.y    = y_min;
mol_complexSP->left_top_near_vectorS.z    = z_min;
mol_complexSP->right_bottom_far_vectorS.x = x_max;
mol_complexSP->right_bottom_far_vectorS.y = y_max;
mol_complexSP->right_bottom_far_vectorS.z = z_max;

/* Find the maximal extent of the macromolecular complex: */
x_extent = mol_complexSP->right_bottom_far_vectorS.x -
	   mol_complexSP->left_top_near_vectorS.x;
y_extent = mol_complexSP->right_bottom_far_vectorS.y -
	   mol_complexSP->left_top_near_vectorS.y;
z_extent = mol_complexSP->right_bottom_far_vectorS.z -
	   mol_complexSP->left_top_near_vectorS.z;


max_extent = x_extent;
if (y_extent > max_extent) max_extent = y_extent;
if (z_extent > max_extent) max_extent = z_extent;
mol_complexSP->max_extent = max_extent;

/* Return 1 if there is at least one atom: */
return 1;
}

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


