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

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

				resize_complex.c

Purpose:
	Resize the selected portion of  the macromolecular complex.  This
	operation is  not suitable  for real molecular structures.  It is
	suitable  for special objects,  i.e. the objects  which are build
	from imaginary atoms (quarkonium and jellium). The operation will
	affect only one  of three dimensions of  the object.  If the size
	should be proportionaly changed, three consecutive operations (in
	three different directions) are required.

Input:
	(1) Pointer to MolComplexS structure, with macromolecular data to
	    be modified.
	(2) Translation shift (will be replaced by  three scale factors).
	(3) Axis identifier (1 = x, 2 = y, 3 = z).
	(4) Pointer to ConfigS structure.

Output:
	(1) The structure will be resized.

Return value:
	No return value.

Notes:
	(1) The shift is replaced  by three  scale factors.  Two of these
	    factors are equal to one.

	(2) This function will not update  the geometric center  and some
	    other geometric data. Use the command CEN (CENTER) to refresh
	    these parameters.

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

#include <stdio.h>
#include <stdlib.h>
#include <math.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		PrepareStereoData_ (MolComplexS *, ConfigS *);

/*======resize macromolecular complex:=======================================*/

void ResizeComplex_ (MolComplexS *mol_complexSP,
		     double shift, int axisID, ConfigS *configSP)
{
double		abs_shift;
double		scale_factor_x = 1.0;
double		scale_factor_y = 1.0;
double		scale_factor_z = 1.0;
double		x0, y0, z0;
size_t		atomI;
AtomS		*curr_atomSP;
double		delta_x, delta_y, delta_z;

/* Prepare the absolute value of the translation shift: */
abs_shift = fabs (shift);

/* Replace the translation shift with three scale factors: */
if (fabs (abs_shift - configSP->translation_stepA[0]) < 0.0001)
	{
	scale_factor_x = 1.01;
	scale_factor_y = 1.01;
	scale_factor_z = 1.01;
	}
else if (fabs (abs_shift - configSP->translation_stepA[1]) < 0.0001)
	{
	scale_factor_x = 1.05;
	scale_factor_y = 1.05;
	scale_factor_z = 1.05;
	}
else if (fabs (abs_shift - configSP->translation_stepA[2]) < 0.0001)
	{
	scale_factor_x = 1.15;
	scale_factor_y = 1.15;
	scale_factor_z = 1.15;
	}
else if (fabs (abs_shift - configSP->translation_stepA[3]) < 0.0001)
	{
	scale_factor_x = 1.50;
	scale_factor_y = 1.50;
	scale_factor_z = 1.50;
	}
else if (fabs (abs_shift - configSP->translation_stepA[4]) < 0.0001)
	{
	scale_factor_x = 2.00;
	scale_factor_y = 2.00;
	scale_factor_z = 2.00;
	}

/* The scale factors should be used to reduce the */
/* size of the object  if the shift  is negative: */
if (shift < 0.0)
	{
	scale_factor_x = 1.0 / scale_factor_x;
	scale_factor_y = 1.0 / scale_factor_y;
	scale_factor_z = 1.0 / scale_factor_z;
	}

/* Reset two scale factors: */
if (axisID == 1)
	{
	scale_factor_y = 1.0;
	scale_factor_z = 1.0;
	}
else if (axisID == 2)
	{
	scale_factor_x = 1.0;
	scale_factor_z = 1.0;
	}
else if (axisID == 3)
	{
	scale_factor_x = 1.0;
	scale_factor_y = 1.0;
	}

/* Prepare the coordinates of the geometric center: */
x0 = mol_complexSP->geometric_center_vectorS.x;
y0 = mol_complexSP->geometric_center_vectorS.y;
z0 = mol_complexSP->geometric_center_vectorS.z;

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

	/* If this atom is not selected, skip it: */
	if (curr_atomSP->selectedF == 0) continue;

	/* The distance from the current atom to the geometric center: */
	delta_x = curr_atomSP->raw_atomS.x[0] - x0;
	delta_y = curr_atomSP->raw_atomS.y    - y0;
	delta_z = curr_atomSP->raw_atomS.z[0] - z0;

	/* Scale this distance: */
	delta_x = scale_factor_x * delta_x;
	delta_y = scale_factor_y * delta_y;
	delta_z = scale_factor_z * delta_z;

	/* Update the position of the current atom: */
	curr_atomSP->raw_atomS.x[0] = x0 + delta_x;
	curr_atomSP->raw_atomS.y    = y0 + delta_y;
	curr_atomSP->raw_atomS.z[0] = z0 + delta_z;
	}

/* Update stereo data, if required: */
if (configSP->stereoF) PrepareStereoData_ (mol_complexSP, configSP);

/* Update the position_changedF flag: */
mol_complexSP->position_changedF = 1;
}

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


