/* Copyright (C) 2001-2003 Damir Zucic */

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

				small_ramachandran.c

Purpose:
	Draw small Ramachandran plot if editing dihedral angles phi and/or
	psi.  If edit_single_bondF is zero, draw it for the first selected
	residue.  Otherwise,  draw it for the residue to which  the chosen
	dihedral angle belongs.  A residue  is treated  as selected if the
	first atom of  this residue is selected.  There is a separate type
	of Ramachadran plot for:
	(1) glycine;
	(2) proline;
	(3) residue preceding proline;
	(4) any other residue except glycine, proline and pre-proline.

Input:
	(1) Pointer to MolComplexS structure.
	(2) Pointer to RuntimeS structure.
	(3) Pointer to GUIS structure.

Output:
	(1) Small Ramachandran plot drawn to hidden pixmap.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Negative on failure.

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

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

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

int		ParseColor_ (RGBS *, unsigned long *, GUIS *, char *, char *);

/*======draw small Ramachandran plot:========================================*/

int SmallRamachandran_ (MolComplexS *mol_complexSP,
			RuntimeS *runtimeSP, GUIS *guiSP)
{
int			residuesN, residueI;
int			chosen_residue_foundF;
static ResidueS		*residueSP;
size_t			atom_startI, atom_endI;
static AtomS		*first_atomSP;
char			*residue_nameP;
ResidueS		*next_residueSP;
AtomS			*next_first_atomSP;
char			*next_residue_nameP;
static char		dummy_nameA[10] = "XXX";
int			inner_width, inner_height, outer_width, outer_height;
int			screen_x0, screen_y0, screen_x1, screen_y1;
RGBS			rgbS;
unsigned long		colorID;

static double		gly1_xA[18]  = {0.000, 0.000, 0.102, 0.201, 0.201,
					0.155, 0.000, 0.000, 0.356, 0.314,
					0.327, 0.380, 0.380, 0.274, 0.327,
					0.360, 0.366, 0.323};
static double		gly1_yA[18]  = {0.000, 0.395, 0.446, 0.541, 0.598,
					0.632, 0.615, 1.000, 1.000, 0.895,
					0.818, 0.699, 0.561, 0.466, 0.253,
					0.230, 0.030, 0.000};
static int		gly1_pointsN = 18;

static double		gly2_xA[18]  = {1.000, 0.640, 0.680, 0.667, 0.614,
					0.614, 0.723, 0.667, 0.634, 0.627,
					0.677, 1.000, 1.000, 0.891, 0.792,
					0.792, 0.838, 1.000};
static double		gly2_yA[18]  = {0.000, 0.000, 0.105, 0.180, 0.297,
					0.439, 0.534, 0.743, 0.767, 0.963,
					1.000, 1.000, 0.605, 0.551, 0.459,
					0.399, 0.368, 0.382};
static int		gly2_pointsN = 18;

static double		gly3_xA[13]  = {0.096, 0.116, 0.086, 0.043, 0.000,
					0.000, 0.030, 0.221, 0.228, 0.251,
					0.333, 0.333, 0.310};
static double		gly3_yA[13]  = {0.000, 0.047, 0.084, 0.108, 0.084,
					0.372, 0.389, 0.389, 0.294, 0.264,
					0.206, 0.020, 0.000};
static int		gly3_pointsN = 13;

static double		gly4_xA[11]  = {0.667, 0.693, 0.693, 0.660, 0.660,
					0.756, 0.822, 0.964, 1.000, 1.000,
					0.878};
static double		gly4_yA[11]  = {0.000, 0.078, 0.196, 0.260, 0.378,
					0.385, 0.351, 0.351, 0.375, 0.098,
					0.000};
static int		gly4_pointsN = 11;

static double		gly5_xA[12]  = {0.000, 0.000, 0.007, 0.112, 0.327,
					0.300, 0.300, 0.333, 0.333, 0.238,
					0.172, 0.030};
static double		gly5_yA[12]  = {0.632, 0.909, 0.909, 1.000, 1.000,
					0.926, 0.811, 0.747, 0.628, 0.622,
					0.655, 0.655};
static int		gly5_pointsN = 12;

static double		gly6_xA[12]  = {0.772, 0.766, 0.660, 0.660, 0.690,
					0.901, 0.878, 0.914, 0.951, 1.000,
					1.000, 0.964};
static double		gly6_yA[12]  = {0.608, 0.703, 0.791, 0.976, 1.000,
					1.000, 0.949, 0.905, 0.889, 0.916,
					0.625, 0.608};
static int		gly6_pointsN = 12;

static double		pro1_xA[17]  = {0.293, 0.286, 0.286, 0.286, 0.293,
					0.299, 0.309, 0.319, 0.332, 0.345,
					0.362, 0.372, 0.382, 0.388, 0.388,
					0.385, 0.382};
static double		pro1_yA[17]  = {0.000, 0.047, 0.074, 0.121, 0.161,
					0.195, 0.225, 0.238, 0.248, 0.245,
					0.232, 0.205, 0.168, 0.131, 0.050,
					0.017, 0.000};
static int		pro1_pointsN = 17;

static double		pro2_xA[21]  = {0.339, 0.329, 0.319, 0.312, 0.306,
					0.299, 0.299, 0.303, 0.313, 0.326,
					0.339, 0.355, 0.359, 0.365, 0.365,
					0.368, 0.368, 0.365, 0.355, 0.349,
					0.339};
static double		pro2_yA[21]  = {0.537, 0.537, 0.544, 0.554, 0.574,
					0.607, 0.671, 0.701, 0.725, 0.742,
					0.742, 0.725, 0.708, 0.691, 0.671,
					0.671, 0.607, 0.587, 0.557, 0.544,
					0.537};
static int		pro2_pointsN = 21;

static double		pro3_xA[14]  = {0.339, 0.332, 0.322, 0.313, 0.305,
					0.302, 0.301, 0.371, 0.371, 0.368,
					0.362, 0.355, 0.349, 0.339};
static double		pro3_yA[14]  = {0.926, 0.926, 0.933, 0.946, 0.973,
					0.987, 1.000, 1.000, 0.987, 0.970,
					0.956, 0.943, 0.933, 0.926};
static int		pro3_pointsN = 14;

static double		pro4_xA[22]  = {0.342, 0.332, 0.319, 0.316, 0.313,
					0.309, 0.306, 0.306, 0.313, 0.316,
					0.326, 0.329, 0.342, 0.355, 0.359,
					0.365, 0.368, 0.368, 0.365, 0.362,
					0.355, 0.345};
static double		pro4_yA[22]  = {0.013, 0.013, 0.023, 0.037, 0.050,
					0.057, 0.074, 0.128, 0.161, 0.188,
					0.201, 0.208, 0.208, 0.198, 0.181,
					0.148, 0.138, 0.077, 0.054, 0.037,
					0.023, 0.013};
static int		pro4_pointsN = 22;

static double		pro5_xA[16]  = {0.339, 0.329, 0.322, 0.322, 0.319,
					0.319, 0.322, 0.326, 0.329, 0.339,
					0.345, 0.345, 0.349, 0.349, 0.345,
					0.339};
static double		pro5_yA[16]  = {0.597, 0.597, 0.607, 0.617, 0.621,
					0.661, 0.664, 0.678, 0.685, 0.685,
					0.675, 0.664, 0.661, 0.624, 0.607,
					0.597};
static int		pro5_pointsN = 16;

static double		prepro1_xA[11]  = {0.000, 0.000, 0.165, 0.191, 0.284,
					   0.413, 0.432, 0.409, 0.396, 0.373,
					   0.274};
static double		prepro1_yA[11]  = {0.047, 0.327, 0.327, 0.293, 0.223,
					   0.230, 0.163, 0.143, 0.117, 0.053,
					   0.027};
static int		prepro1_pointsN = 11;

static double		prepro2_xA[7]   = {0.667, 0.667, 0.564, 0.591, 0.663,
					   0.729, 0.743};
static double		prepro2_yA[7]   = {0.037, 0.157, 0.280, 0.340, 0.340,
					   0.287, 0.067};
static int		prepro2_pointsN = 7;

static double		prepro3_xA[6]   = {1.003, 0.983, 0.944, 0.937, 0.937,
					   1.003};
static double		prepro3_yA[6]   = {0.047, 0.043, 0.070, 0.103, 0.277,
					   0.330};
static int		prepro3_pointsN = 6;

static double		prepro4_xA[10]  = {0.000, 0.033, 0.307, 0.360, 0.386,
					   0.380, 0.264, 0.155, 0.056, 0.000};
static double		prepro4_yA[10]  = {0.097, 0.077, 0.060, 0.083, 0.137,
					   0.183, 0.210, 0.293, 0.307, 0.263};
static int		prepro4_pointsN = 10;

static double		prepro5_xA[5]   = {0.677, 0.663, 0.644, 0.677, 0.690};
static double		prepro5_yA[5]   = {0.217, 0.223, 0.283, 0.277, 0.250};
static int		prepro5_pointsN = 5;

static double		prepro6_xA[5]   = {1.000, 0.990, 0.980, 0.980, 1.000};
static double		prepro6_yA[5]   = {0.100, 0.107, 0.123, 0.207, 0.257};
static int		prepro6_pointsN = 5;

static double		other1_xA[25]  = {0.000, 0.359, 0.382, 0.382, 0.316,
					  0.316, 0.313, 0.270, 0.270, 0.388,
					  0.388, 0.000, 0.000, 0.010, 0.046,
					  0.079, 0.082, 0.102, 0.135, 0.184,
					  0.194, 0.203, 0.178, 0.151, 0.000};
static double		other1_yA[25]  = {0.000, 0.000, 0.037, 0.214, 0.274,
					  0.314, 0.331, 0.418, 0.465, 0.585,
					  0.702, 0.702, 0.599, 0.599, 0.622,
					  0.625, 0.629, 0.629, 0.622, 0.605,
					  0.595, 0.562, 0.505, 0.485, 0.388};
static int		other1_pointsN = 25;

static double		other2_xA[4]   = {0.671, 0.671, 0.632, 0.632};
static double		other2_yA[4]   = {0.465, 0.231, 0.264, 0.425};
static int		other2_pointsN = 4;

static double		other3_xA[10]  = {0.000, 0.000, 0.362, 0.362, 0.355,
					  0.345, 0.336, 0.316, 0.303, 0.296};
static double		other3_yA[10]  = {0.957, 1.000, 1.000, 0.990, 0.980,
					  0.973, 0.970, 0.963, 0.960, 0.957};
static int		other3_pointsN = 10;

static double		other4_xA[8]   = {0.066, 0.303, 0.355, 0.355, 0.329,
					  0.118, 0.118, 0.066};
static double		other4_yA[8]   = {0.241, 0.241, 0.207, 0.043, 0.010,
					  0.010, 0.043, 0.114};
static int		other4_pointsN = 8;

static double		other5_xA[6]   = {0.059, 0.349, 0.349, 0.197, 0.164,
					  0.059};
static double		other5_yA[6]   = {0.676, 0.676, 0.615, 0.615, 0.649,
					  0.649};
static int		other5_pointsN = 6;

int			pointI;
double			d;
XPoint			pointSA[30];
int			phiI, psiI;

/* Prepare and check the number of residues: */
residuesN = mol_complexSP->residuesN;
if (residuesN <= 0) return -1;

/* Find the residue to which the small Ramachandran plot will be assigned: */
chosen_residue_foundF = 0;
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Pointer to the current residue: */
	residueSP = mol_complexSP->residueSP + residueI;

	/* Prepare the atomic index range: */
	atom_startI = residueSP->residue_startI;
	atom_endI   = residueSP->residue_endI;

	/* Pointer to the first atom of the current residue: */
	first_atomSP = mol_complexSP->atomSP + atom_startI;

	/* Editing of  a single dihedral angle  or a */
	/* single pair of dihedral angles requested: */
	if (runtimeSP->edit_single_bondF)
		{
		/* Check the array indices of N and CA: */
		if ((runtimeSP->atom1_arrayI >= atom_startI) &&
		    (runtimeSP->atom1_arrayI <= atom_endI)   &&
		    (runtimeSP->atom2_arrayI >= atom_startI) &&
		    (runtimeSP->atom2_arrayI <= atom_endI))
			{
			chosen_residue_foundF = 1;
			break;
			}
		}

	/* Editing of dihedral angle(s) for all selected residues requested: */
	else
		{
		/* If the first atom of the current residue is */
		/* selected,  treat this residue  as selected: */
		if (first_atomSP->selectedF)
			{
			chosen_residue_foundF = 1;
			break;
			}
		}
	}

/* Check was residue found at all: */
if (!chosen_residue_foundF) return -2;

/* The name of the chosen residue: */
residue_nameP = first_atomSP->raw_atomS.pure_residue_nameA;

/* Prepare the name of the next residue, if */
/* the chosen residue  is not the last one: */
if (residueI < residuesN - 1)
	{
	next_residueSP = mol_complexSP->residueSP + residueI + 1;
	next_first_atomSP = mol_complexSP->atomSP +
			    next_residueSP->residue_startI;
	next_residue_nameP = next_first_atomSP->raw_atomS.pure_residue_nameA;
	}
else next_residue_nameP = dummy_nameA;

/* The width of small Ramachandran plot should not */
/* exceed one third of  the main window free area: */
inner_width  = ((guiSP->main_win_free_area_width  / 3) / 30) * 30;
inner_height = ((guiSP->main_win_free_area_height / 3) / 30) * 30;
if (inner_height < inner_width) inner_width = inner_height;
else inner_height = inner_width;
outer_width  = inner_width  + 8;
outer_height = inner_height + 8;

/* The top left corner of the background square: */
screen_x0 = guiSP->main_win_free_area_width  - outer_width  - 2;
screen_y0 = guiSP->main_win_free_area_height - outer_height - 2;

/* Draw the filled square. Use a shade of orange color: */
ParseColor_ (&rgbS, &colorID, guiSP, "RGB:D8D8/B7B7/9999", "white");
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], colorID);
XFillRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0, screen_y0,
		outer_width, outer_height);

/* Draw the border, using the main window foreground color: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
		guiSP->main_winS.fg_colorID);
XDrawRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0, screen_y0,
		outer_width, outer_height);

/* Draw allowed regions. */

/* Prepare the first blue color (light): */
ParseColor_ (&rgbS, &colorID, guiSP, "RGB:5A5A/D5D5/FEFE", "white");
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], colorID);

/* Prepare the second blue color (dark): */
ParseColor_ (&rgbS, &colorID, guiSP, "RGB:2222/B8B8/EEEE", "white");
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], colorID);

/* Allowed regions for glycine: */
if (strcmp (residue_nameP, "GLY") == 0)
	{
	/* The XPoint structures for the first filled polygon: */
	for (pointI = 0; pointI < gly1_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly1_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly1_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the first filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, gly1_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the second filled polygon: */
	for (pointI = 0; pointI < gly2_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly2_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly2_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the second filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, gly2_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the third filled polygon: */
	for (pointI = 0; pointI < gly3_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly3_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly3_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the third filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, gly3_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fourth filled polygon: */
	for (pointI = 0; pointI < gly4_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly4_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly4_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fourth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, gly4_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fifth filled polygon: */
	for (pointI = 0; pointI < gly5_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly5_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly5_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fifth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, gly5_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the sixth filled polygon: */
	for (pointI = 0; pointI < gly6_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * gly6_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * gly6_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the sixth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, gly6_pointsN,
		      Nonconvex, CoordModeOrigin);
	}

/* Allowed regions for proline: */
else if (strcmp (residue_nameP, "PRO") == 0)
	{
	/* The XPoint structures for the first filled polygon: */
	for (pointI = 0; pointI < pro1_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * pro1_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * pro1_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the first filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, pro1_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the second filled polygon: */
	for (pointI = 0; pointI < pro2_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * pro2_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * pro2_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the second filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, pro2_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the third filled polygon: */
	for (pointI = 0; pointI < pro3_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * pro3_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * pro3_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the third filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, pro3_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fourth filled polygon: */
	for (pointI = 0; pointI < pro4_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * pro4_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * pro4_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fourth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, pro4_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fifth filled polygon: */
	for (pointI = 0; pointI < pro5_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * pro5_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * pro5_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fifth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, pro5_pointsN,
		      Nonconvex, CoordModeOrigin);
	}

/* Allowed regions for residues preceding proline: */
else if (strcmp (next_residue_nameP, "PRO") == 0)
	{
	/* The XPoint structures for the first filled polygon: */
	for (pointI = 0; pointI < prepro1_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro1_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro1_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the first filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, prepro1_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the second filled polygon: */
	for (pointI = 0; pointI < prepro2_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro2_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro2_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the second filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, prepro2_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the third filled polygon: */
	for (pointI = 0; pointI < prepro3_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro3_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro3_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the third filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, prepro3_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fourth filled polygon: */
	for (pointI = 0; pointI < prepro4_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro4_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro4_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fourth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, prepro4_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fifth filled polygon: */
	for (pointI = 0; pointI < prepro5_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro5_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro5_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fifth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, prepro5_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the sixth filled polygon: */
	for (pointI = 0; pointI < prepro6_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * prepro6_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * prepro6_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the sixth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, prepro6_pointsN,
		      Nonconvex, CoordModeOrigin);
	}

/* Allowed regions for all other residues: */
else
	{
	/* The XPoint structures for the first filled polygon: */
	for (pointI = 0; pointI < other1_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * other1_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * other1_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the first filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, other1_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the second filled polygon: */
	for (pointI = 0; pointI < other2_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * other2_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * other2_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the second filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, other2_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the third filled polygon: */
	for (pointI = 0; pointI < other3_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * other3_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * other3_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the third filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[0],
		      pointSA, other3_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fourth filled polygon: */
	for (pointI = 0; pointI < other4_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * other4_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * other4_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fourth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, other4_pointsN,
		      Nonconvex, CoordModeOrigin);

	/* The XPoint structures for the fifth filled polygon: */
	for (pointI = 0; pointI < other5_pointsN; pointI++)
		{
		d = guiSP->main_win_free_area_width  - outer_width  + 2 +
		    inner_width  * other5_xA[pointI];
		pointSA[pointI].x = (short) d;
		d = guiSP->main_win_free_area_height - outer_height + 2 +
		    inner_height * other5_yA[pointI];
		pointSA[pointI].y = (short) d;
		}

	/* Draw the fifth filled polygon: */
	XFillPolygon (guiSP->displaySP,
		      guiSP->main_hidden_pixmapID,
		      guiSP->theGCA[1],
		      pointSA, other5_pointsN,
		      Nonconvex, CoordModeOrigin);
	}

/* Draw small blue squares at the positions of alpha helix and beta sheet. */

/* Prepare the blue color: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->blue_colorID);

/* Draw square at the position of alpha helix: */
d = 0.342 * (double) inner_width;
screen_x0 = guiSP->main_win_free_area_width  - outer_width  + 2 + (int) d;
d = 0.631 * (double) inner_height;
screen_y0 = guiSP->main_win_free_area_height - outer_height + 2 + (int) d;
XFillRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0 - 4, screen_y0 - 4, 9, 9);

/* Draw square at the position of beta sheet: */
d = 0.114 * (double) inner_width;
screen_x0 = guiSP->main_win_free_area_width  - outer_width  + 2 + (int) d;
d = 0.124 * (double) inner_height;
screen_y0 = guiSP->main_win_free_area_height - outer_height + 2 + (int) d;
XFillRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0 - 4, screen_y0 - 4, 9, 9);

/* Prepare black color for grid: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->black_colorID);

/* Draw vertical grid using the spacing of 90 degrees: */
screen_x0 = guiSP->main_win_free_area_width  - outer_width  + 2;
screen_y0 = guiSP->main_win_free_area_height - outer_height + 2;
screen_y1 = screen_y0 + inner_height;
for (phiI = 0; phiI <= 5; phiI++)
	{
	d = (double) inner_width * ((double) phiI * 0.25) + 0.5;
	screen_x1 = screen_x0 + (int) d;
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[0],
		   screen_x1, screen_y0,
		   screen_x1, screen_y1);
	}

/* Draw horizontal grid, using the spacing of 90 degrees: */
screen_x0 = guiSP->main_win_free_area_width  - outer_width  + 2;
screen_x1 = screen_x0 + inner_width;
screen_y0 = guiSP->main_win_free_area_height - outer_height + 2;
for (psiI = 0; psiI <= 5; psiI++)
	{
	d = (double) inner_height * ((double) psiI * 0.25) + 0.5;
	screen_y1 = screen_y0 + (int) d;
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[0],
		   screen_x0, screen_y1,
		   screen_x1, screen_y1);
	}

/* Draw the symbol at the position defined */
/* by phi and psi for the current residue. */

/* Prepare the symbol position: */
d = (double) inner_width  * (residueSP->phi + 3.1415927) * 0.15915494;
screen_x0 = guiSP->main_win_free_area_width  - outer_width  + 2 + (int) d;
d = (double) inner_height * (residueSP->psi + 3.1415927) * 0.15915494;
screen_y0 = guiSP->main_win_free_area_height - 6 - (int) d;

/* Draw the outer part of the symbol (red): */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->red_colorID);
XDrawRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0 - 3, screen_y0 - 3, 6, 6);

/* Draw the inner part of the symbol (yellow): */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->yellow_colorID);
XFillRectangle (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		screen_x0 - 2, screen_y0 - 2, 5, 5);

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

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


