/* Copyright (C) 2000 Damir Zucic */

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

				    cpk.c

Purpose:
	CPK color scheme (Corey, Pauling and Kultun).

Input:
	(1) Pointer to MolComplexS structure, with macromol. complexes.
	(2) Number of macromolecular complexes.
	(3) Pointer to GUIS structure, with GUI data.
	(4) Pointer to ColorSchemeS structure.

Output:
	(1) Return value.

Return value:
	(1) Positive always.

Notes:
	(1) The color scheme used here is actually a modified  CPK, not
	    the original one.

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

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

/*======CPK color scheme:====================================================*/

int CPK_ (MolComplexS *mol_complexSP, int mol_complexesN,
	  GUIS *guiSP, ColorSchemeS *color_schemeSP)
{
int			carbonI = 6, nitrogenI = 9, oxygenI = 0;
int			sulfurI = 3, phosphorusI = 12, otherI = 5;
int			mol_complexI;
MolComplexS		*curr_mol_complexSP;
size_t			atomsN, atomI;
AtomS			*curr_atomSP;
size_t			rgb_struct_size;
ColorSchemeS		*schemeSP;
int			surfaceI;

/* The size of RGBS structure: */
rgb_struct_size = sizeof (RGBS);

/* Scan 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;

	/* Number of atoms in a macromolecular complex: */
	atomsN = curr_mol_complexSP->atomsN;

	/* 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;

		/* Check is atom selected: */
		if (curr_atomSP->selectedF == 0) continue;

		/* Set the number of color surfaces: */
		curr_atomSP->surfacesN = 2;

		/* Carbon: */
		if (curr_atomSP->raw_atomS.pure_atom_nameA[0] == 'C')
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + carbonI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}

		/* Nitrogen: */
		else if (curr_atomSP->raw_atomS.pure_atom_nameA[0] == 'N')
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + nitrogenI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}

		/* Oxygen: */
		else if (curr_atomSP->raw_atomS.pure_atom_nameA[0] == 'O')
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + oxygenI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}

		/* Sulfur: */
		else if (curr_atomSP->raw_atomS.pure_atom_nameA[0] == 'S')
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + sulfurI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}

		/* Phosphorus: */
		else if (curr_atomSP->raw_atomS.pure_atom_nameA[0] == 'P')
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + phosphorusI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}

		/* Any other atom: */
		else
			{
			/* Pointer to the current color scheme: */
			schemeSP = color_schemeSP + otherI;

			/* Copy the color specifications: */
			for (surfaceI = 0; surfaceI < 2; surfaceI++)
				{
				/* Left color: */
				memcpy (curr_atomSP->left_rgbSA + surfaceI,
					schemeSP->left_rgbSA + surfaceI,
					rgb_struct_size);

				/* Middle color: */
				memcpy (curr_atomSP->middle_rgbSA + surfaceI,
					schemeSP->middle_rgbSA + surfaceI,
					rgb_struct_size);

				/* Right color: */
				memcpy (curr_atomSP->right_rgbSA + surfaceI,
					schemeSP->right_rgbSA + surfaceI,
					rgb_struct_size);
				}
			}
		}

	/* Reset the position_changedF: */
	curr_mol_complexSP->position_changedF = 1;
	}

/* Return positive value: */
return 1;
}

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


