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

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

				draw_plots.c

Purpose:
	Draw hydrophobicity plots.  This function is used if the main win.
	drawing mode is equal to four. The sequence stored to the sequence
	buffer is used to calculate requested functions. More plots may be
	drawn simultaneosly. The following functions are available:
	- average hydrophobicity;
	- weighted hydrophobicity;
	- hydrophobic moment;
	- two sided hydrophobicity profiles (larger and smaller);
	- hydrophobicity function F1.
	- hydrophobicity function F2.
	- hydrophobicity function F3.
	- hydrophobicity function F4.
	- hydrophobicity function F5.

Input:
	(1) Pointer to RuntimeS structure, with some runtime data.
	(2) Pointer to GUIS structure, with GUI data.
	(3) Pointer to NearestAtomS structure,  with information about the
	    atom occupying the given pixel.
	(4) The number of pixels in the main window free area.
	(5) The refreshI,  used to check the  NearestAtomS associated with
	    a given pixel. It is currently unused in this function.

Output:
	(1) Hydrophobicity plots should be drawn to the main window.
	(2) Return value.

Return value:
	(1) The number of residues used in calculation, on success.
	(2) Zero on failure.

Notes:
	(1) The initial drawing destination is the hidden pixmap,  and the
	    content of this pixmap is copied later to the main window.

	(2) The residue index is stored as the atomic index.  The function
	    value  (average  hydrophobicity,  hydrophobic moment etc.)  is
	    stored as z coordinate.

	(3) Both sided hydrophobicity values  (larger one and smaller one)
	    are normalized  (divided)  by the sliding  window width.  This
	    ensures  that the sum  of two values  is equal to  the average
	    hydrophobicity value.

	(4) Red color is used to draw both  the average hydrophobicity and
	    the function F6.  Blue color is used to draw both the hydroph.
	    moment and the function F7.

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

#include <stdio.h>

#include <string.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		RefreshPixmap_ (Display *, Pixmap, GC,
				unsigned int, unsigned int, unsigned long);
int		ParseColor_ (RGBS *, unsigned long *, GUIS *, char *, char *);
int		AverageHydrophobicity_ (double *, double *, RuntimeS *);
int		WeightedHydrophobicity_ (double *, double *, RuntimeS *);
int		HyphobFunction1_ (double *, double *, RuntimeS *);
int		HyphobFunction2_ (double *, double *, RuntimeS *);
int		HyphobFunction3_ (double *, double *, RuntimeS *);
int		HyphobFunction4_ (double *, double *, RuntimeS *);
int		HyphobFunction5_ (double *, double *, RuntimeS *);
int		HyphobFunction6_ (double *, double *, RuntimeS *);
int		HyphobFunction7_ (double *, double *, RuntimeS *);

/*======draw hydrophobicity plots:===========================================*/

size_t DrawPlots_ (RuntimeS *runtimeSP, GUIS *guiSP,
		  NearestAtomS *nearest_atomSP, size_t pixelsN,
		  unsigned int refreshI)
{
int             residuesN, residueI;   /* Do not use size_t instead of int ! */
int		used_residuesN;
int		range_startI, range_endI, residues_in_plotN = 0;
int		visible_residueI;
int		window_width, half_window_width, windowI, combinedI;
double		angle_step, angle;
double		hydrophobicity;
static double	weighted_hydrophobicity = 0.0, average_hydrophobicity = 0;
double		min_average_hyphob, max_average_hyphob;
double		min_weighted_hyphob, max_weighted_hyphob;
double		hydrophobic_moment, abs_squared, moment_x, moment_y;
double		min_hyphob_moment, max_hyphob_moment;
double		min_sided_hyphob, max_sided_hyphob;
int		even_residuesN, odd_residuesN;
double		even_side_hyphob, odd_side_hyphob;
double		larger_side_hyphob, smaller_side_hyphob;
int		screen_width, screen_height;
int		screen_margin_x, screen_margin_top, screen_margin_bottom;
int		screen_delta_x, screen_delta_y;
int		residue_screen_width, half_residue_width;
int		residues_per_sectionN;
int		sectionsN, sectionI;
int		section_width, section_height;
int		frame_x0, frame_x1, frame_y0, frame_y1;
int		section_y0;
unsigned long	color1ID, color2ID, color3ID, color4ID;
RGBS		rgbS;
double		ordinate_min, ordinate_max, ordinate_range, ordinate_scale;
int		local_residueI;
int		screen_x0, screen_x1, screen_y0, screen_y1;
double		d;
int		residue_serialI;
char		stringA[SHORTSTRINGSIZE];
int		string_length;
int		text_height, text_ascent, text_width, half_text_width;
int		old_screen_y = 0, screen_x, screen_y;
int		draw_vertical_lineF = 0;
size_t		pixelI;
NearestAtomS	*curr_pixelSP;
int		shift = 0;
double		min_function1 = 0.0, max_function1 = 0.0, function1;
double		min_function2 = 0.0, max_function2 = 0.0, function2;
double		min_function3 = 0.0, max_function3 = 0.0, function3;
double		min_function4 = 0.0, max_function4 = 0.0, function4;
double		min_function5 = 0.0, max_function5 = 0.0, function5;
double		min_function6 = 0.0, max_function6 = 0.0, function6;
double		min_function7 = 0.0, max_function7 = 0.0, function7;

/*------prepare some parameters:---------------------------------------------*/

/* The number of residues in sequence buffer: */
residuesN = (int) runtimeSP->residuesN;
if (residuesN == 0)
	{
	strcpy (runtimeSP->messageA, "The sequence buffer is empty!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return 0;
	}

/* Paranoid check - at least one flag should be different from zero: */
if ((runtimeSP->average_hydrophobicityF  == 0) &&
    (runtimeSP->weighted_hydrophobicityF == 0) &&
    (runtimeSP->hydrophobic_momentF      == 0) &&
    (runtimeSP->sided_hydrophobicityF    == 0) &&
    (runtimeSP->function1F               == 0) &&
    (runtimeSP->function2F               == 0) &&
    (runtimeSP->function3F               == 0) &&
    (runtimeSP->function4F               == 0) &&
    (runtimeSP->function5F               == 0) &&
    (runtimeSP->function6F               == 0) &&
    (runtimeSP->function7F               == 0)) return 0;

/* The range of residue array indices: */
range_startI = runtimeSP->range_startI;
range_endI   = runtimeSP->range_endI;

/* Count the number of residues in the specified range: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Check is the residue array index inside the range: */
	if ((residueI < range_startI) || (residueI > range_endI)) continue;

	/* Increase the count of residues if current */
	/* residue  belongs to  the specified range: */
	residues_in_plotN++;
	}

/* Check the number of residues in a plot: */
if (residues_in_plotN == 0)
	{
	strcpy (runtimeSP->messageA, "The specified range is empty!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return 0;
	}

/* The sliding window width: */
window_width = runtimeSP->sliding_window_width;
half_window_width = window_width / 2;

/* The helix step angle: */
angle_step = DEG_TO_RAD * runtimeSP->helix_step_angle;

/*------refresh the hidden pixmap:-------------------------------------------*/

/* Refresh the hidden pixmap, where drawing will be done: */
RefreshPixmap_ (guiSP->displaySP,
		guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		guiSP->control_winS.x0, guiSP->input_winS.y0,
		guiSP->main_winS.bg_colorID);

/*------calculate the average hydrophobicity:--------------------------------*/

/* Initialize the extreme values: */
min_average_hyphob = +999999.0;
max_average_hyphob = -999999.0;

AverageHydrophobicity_ (&min_average_hyphob, &max_average_hyphob, runtimeSP);

/*------calculate the weighted hydrophobicity:-------------------------------*/

/* Initialize the extreme values: */
min_weighted_hyphob = +999999.0;
max_weighted_hyphob = -999999.0;

WeightedHydrophobicity_ (&min_weighted_hyphob, &max_weighted_hyphob, runtimeSP);

/*------calculate the hydrophobic moment:------------------------------------*/

/* Initialize the extreme values: */
min_hyphob_moment = +999999.0;
max_hyphob_moment = -999999.0;

/* Scan the sequence: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Reset the number of residues used for calculation: */
	used_residuesN = 0;

	/* Reset the projections: */
	moment_x = 0.0;
	moment_y = 0.0;

	/* Scan the sliding window: */
	for (windowI = 0; windowI < window_width; windowI++)
		{
		/* Prepare and check the combined index: */
		combinedI = residueI - half_window_width + windowI;
		if (combinedI < 0) continue;
		if (combinedI >= residuesN) continue;

		/* The hydrophobicity of the residue defined by combinedI: */
		hydrophobicity = *(runtimeSP->hydrophobicityP + combinedI);

		/* The angle: */
		angle = angle_step * (double) windowI;

		/* Hydrophobic moment projections: */
		moment_x += (double) hydrophobicity * cos (angle);
		moment_y += (double) hydrophobicity * sin (angle);

		/* Increase the number of residues used for calculation: */
		used_residuesN++;
		}

	/* Calculate the hydrophobic moment: */
	abs_squared = moment_x * moment_x + moment_y * moment_y;
	if (used_residuesN == window_width)
		{
		hydrophobic_moment = sqrt (abs_squared) /
				     (double) window_width;
		}
	else hydrophobic_moment = 0.0;

	/* Store the hydrophobic moment: */
	*(runtimeSP->hydrophobic_momentP + residueI) = hydrophobic_moment;

	/* Dummy values should not be used to determine extreme values: */
	if (used_residuesN != window_width) continue;

	/* Find the extreme values: */
	if (hydrophobic_moment < min_hyphob_moment)
		{
		min_hyphob_moment = hydrophobic_moment;
		}
	if (hydrophobic_moment > max_hyphob_moment)
		{
		max_hyphob_moment = hydrophobic_moment;
		}
	}

/*------calculate two sided hydrophobicity values:---------------------------*/

/* Initialize the extreme values: */
min_sided_hyphob = +999999.0;
max_sided_hyphob = -999999.0;

/* Scan the sequence: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Reset  two counts of residues  used to calculate  the side */
	/* hydrophobicity (even and odd residues counted separately): */
	even_residuesN = 0;
	odd_residuesN  = 0;

	/* Reset side hydrophobicity values for even and odd residues: */
	even_side_hyphob = 0.0;
	odd_side_hyphob  = 0.0;

	/* Scan the sliding window: */
	for (windowI = 0; windowI < window_width; windowI++)
		{
		/* Prepare and check the combined index: */
		combinedI = residueI - half_window_width + windowI;
		if (combinedI < 0) continue;
		if (combinedI >= residuesN) continue;

		/* The hydrophobicity of the residue defined by combinedI: */
		hydrophobicity =
			(double) *(runtimeSP->hydrophobicityP + combinedI);

		/* Calculate  the side  hydrophobicity  for even and odd */
		/* residues. Update the number of even and odd residues. */
		if (combinedI % 2)
			{
			odd_side_hyphob += hydrophobicity;
			odd_residuesN++;
			}
		else
			{
			even_side_hyphob += hydrophobicity;
			even_residuesN++;
			}
		}

	/* Divide both values by the sliding window width: */
	if (even_residuesN != 0) even_side_hyphob /= (double) window_width;
	else even_side_hyphob = 0.0;
	if (odd_residuesN != 0) odd_side_hyphob /= (double) window_width;
	else odd_side_hyphob = 0.0;

	/* Check the total number of even and odd residues. If it is */
	/* not equal to the sliding window width, reset both values! */
	if (even_residuesN + odd_residuesN != window_width)
		{
		even_side_hyphob = 0.0;
		odd_side_hyphob  = 0.0;
		}

	/* Store the larger value  to the buffer reserved for upper line */
	/* and the smaller value to the buffer reserver for bottom line: */
	if (even_side_hyphob >= odd_side_hyphob)
		{
		larger_side_hyphob  = even_side_hyphob;
		smaller_side_hyphob = odd_side_hyphob;
		}
	else
		{
		larger_side_hyphob  = odd_side_hyphob;
		smaller_side_hyphob = even_side_hyphob;
		}
	*(runtimeSP->larger_sided_hyphobP  + residueI) = larger_side_hyphob;
	*(runtimeSP->smaller_sided_hyphobP + residueI) = smaller_side_hyphob;

	/* Dummy values should not be used to determine extremes: */
	if (even_residuesN + odd_residuesN != window_width) continue;

	/* Find the extreme values: */
	if (smaller_side_hyphob < min_sided_hyphob)
		{
		min_sided_hyphob = smaller_side_hyphob;
		}
	if (larger_side_hyphob > max_sided_hyphob)
		{
		max_sided_hyphob = larger_side_hyphob;
		}
	}

/*------calculate hydrophobicity functions, in reverse order.----------------*/

/* Note: some functions with higher number may call functions with */
/* lower number - that explains why reverse order  should be used! */

/*------calculate the hydrophobicity function F7:----------------------------*/

if (runtimeSP->function7F)
	HyphobFunction7_ (&min_function7, &max_function7, runtimeSP);

/*------calculate the hydrophobicity function F6:----------------------------*/

if (runtimeSP->function6F)
	HyphobFunction6_ (&min_function6, &max_function6, runtimeSP);

/*------calculate the hydrophobicity function F5:----------------------------*/

if (runtimeSP->function5F)
	HyphobFunction5_ (&min_function5, &max_function5, runtimeSP);

/*------calculate the hydrophobicity function F4:----------------------------*/

if (runtimeSP->function4F)
	HyphobFunction4_ (&min_function4, &max_function4, runtimeSP);

/*------calculate the hydrophobicity function F3:----------------------------*/

if (runtimeSP->function3F)
	HyphobFunction3_ (&min_function3, &max_function3, runtimeSP);

/*------calculate the hydrophobicity function F2:----------------------------*/

if (runtimeSP->function2F)
	HyphobFunction2_ (&min_function2, &max_function2, runtimeSP);

/*------calculate the hydrophobicity function F1:----------------------------*/

if (runtimeSP->function1F)
	HyphobFunction1_ (&min_function1, &max_function1, runtimeSP);

/*------prepare geometric parameters:----------------------------------------*/

/* Width, height and margins (margins will be updated later): */
screen_width  = guiSP->main_win_free_area_width;
screen_height = guiSP->main_win_free_area_height;
screen_margin_x = screen_width / 40;
if (screen_margin_x < 4) screen_margin_x = 4;
screen_margin_bottom = screen_height / 40;
if (screen_margin_bottom < 4) screen_margin_bottom = 4;
screen_margin_top = 2 * screen_margin_bottom + guiSP->main_winS.font_height;
screen_delta_x = screen_width  - 2 * screen_margin_x;
if (screen_delta_x < 10) screen_delta_x = 10;
screen_delta_y = screen_height - screen_margin_top - screen_margin_bottom;
if (screen_delta_y < 10) screen_delta_y = 10;

/* Break the entire sequence range  into more */
/* parts, if the number of residues is large: */
residue_screen_width = RESIDUE_WIDTH;
half_residue_width = residue_screen_width / 2;
if (residue_screen_width <= 0) return 0;
residues_per_sectionN = screen_delta_x / residue_screen_width;
if (residues_per_sectionN == 0)
	{
	sectionsN = 1;
	}
else
	{
	sectionsN = (residues_in_plotN + residues_per_sectionN - 1) /
		     residues_per_sectionN;
	}

/* The screen height should be divided into equal portions: */
if (sectionsN == 0) section_height = screen_delta_y;
else section_height = screen_delta_y / sectionsN;

/* Avoid ugly proportions: */
if (section_height / residue_screen_width > 80)
	{
	section_height = 80 * residue_screen_width;
	}

/* Update plot width, height and margins: */
if (residues_in_plotN > residues_per_sectionN)
	{
	screen_delta_x = residues_per_sectionN  * residue_screen_width;
	}
else
	{
	screen_delta_x = residues_in_plotN * residue_screen_width;
	}
screen_margin_x = (screen_width - screen_delta_x) / 2;
screen_margin_bottom = (screen_height -
			section_height * sectionsN -
			guiSP->main_winS.font_height) / 3;
if (screen_margin_bottom < 4) screen_margin_bottom = 4;
screen_margin_top = 2 * screen_margin_bottom + guiSP->main_winS.font_height;

/* Set the section width: */
section_width = screen_delta_x;

/*------draw frames:---------------------------------------------------------*/

/* Frame left and right edge: */
frame_x0 = screen_margin_x;
frame_x1 = frame_x0 + section_width;

/* Frame top and bottom edge: */
frame_y0 = screen_margin_top;
frame_y1 = screen_margin_top + sectionsN * section_height;

/* Prepare colors: */
ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:3333/3333/3333", "black");
ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:6666/6666/6666", "black");
ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:AAAA/AAAA/AAAA", "white");
ParseColor_ (&rgbS, &color4ID, guiSP, "RGB:EEEE/EEEE/EEEE", "white");
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[4], color4ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[5], color3ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[6], color2ID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[7], color1ID);

/* Draw vertical lines: */
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[1],
	   frame_x0 - 3, frame_y0 - 3, frame_x0 - 3, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[2],
           frame_x0 - 2, frame_y0 - 3, frame_x0 - 2, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[3],
           frame_x0 - 1, frame_y0 - 3, frame_x0 - 1, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[4],
           frame_x0 - 0, frame_y0 - 3, frame_x0 - 0, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[5],
           frame_x0 + 1, frame_y0 - 3, frame_x0 + 1, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[6],
           frame_x0 + 2, frame_y0 - 3, frame_x0 + 2, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[7],
           frame_x0 + 3, frame_y0 - 3, frame_x0 + 3, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[1],
           frame_x1 - 3, frame_y0 - 3, frame_x1 - 3, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[2],
           frame_x1 - 2, frame_y0 - 3, frame_x1 - 2, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[3],
           frame_x1 - 1, frame_y0 - 3, frame_x1 - 1, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[4],
           frame_x1 - 0, frame_y0 - 3, frame_x1 - 0, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[5],
           frame_x1 + 1, frame_y0 - 3, frame_x1 + 1, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[6],
           frame_x1 + 2, frame_y0 - 3, frame_x1 + 2, frame_y1 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[7],
           frame_x1 + 3, frame_y0 - 3, frame_x1 + 3, frame_y1 + 3);

/* Draw horizontal lines: */
for (sectionI = 0; sectionI <= sectionsN; sectionI++)
	{
	section_y0 = screen_margin_top + sectionI * section_height;
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[1],
		   frame_x0 + 3, section_y0 - 3,
		   frame_x1 - 3, section_y0 - 3);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[2],
		   frame_x0 + 2, section_y0 - 2,
		   frame_x1 - 2, section_y0 - 2);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[3],
		   frame_x0 + 1, section_y0 - 1,
		   frame_x1 - 1, section_y0 - 1);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[4],
		   frame_x0 + 0, section_y0 - 0,
		   frame_x1 - 0, section_y0 - 0);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[5],
		   frame_x0 + 1, section_y0 + 1,
		   frame_x1 - 1, section_y0 + 1);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[6],
		   frame_x0 + 2, section_y0 + 2,
		   frame_x1 - 2, section_y0 + 2);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[7],
		   frame_x0 + 3, section_y0 + 3,
		   frame_x1 - 3, section_y0 + 3);
	}

/* Fix top and bottom of the frame: */
section_y0 = screen_margin_top;
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[1],
	   frame_x0 - 3, section_y0 - 3, frame_x1 + 3, section_y0 - 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[2],
	   frame_x0 - 2, section_y0 - 2, frame_x1 + 2, section_y0 - 2);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[3],
	   frame_x0 - 1, section_y0 - 1, frame_x1 + 1, section_y0 - 1);
section_y0 = screen_margin_top + sectionsN * section_height;
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[1],
	   frame_x0 - 3, section_y0 + 3, frame_x1 + 3, section_y0 + 3);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[2],
	   frame_x0 - 2, section_y0 + 2, frame_x1 + 2, section_y0 + 2);
XDrawLine (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[3],
	   frame_x0 - 1, section_y0 + 1, frame_x1 + 1, section_y0 + 1);

/*------prepare ordinate extreme values and scale factor:--------------------*/

/* Prepare extreme values for the ordinate axis: */
ordinate_min = +999999.0;
ordinate_max = -999999.0;
if (runtimeSP->average_hydrophobicityF)
	{
	if (min_average_hyphob < ordinate_min)
		{
		ordinate_min = min_average_hyphob;
		}
	if (max_average_hyphob > ordinate_max)
		{
		ordinate_max = max_average_hyphob;
		}
	}

if (runtimeSP->weighted_hydrophobicityF)
	{
	if (min_weighted_hyphob < ordinate_min)
		{
		ordinate_min = min_weighted_hyphob;
		}
	if (max_weighted_hyphob > ordinate_max)
		{
		ordinate_max = max_weighted_hyphob;
		}
	}

if (runtimeSP->hydrophobic_momentF)
	{
	if (min_hyphob_moment < ordinate_min)
		{
		ordinate_min = min_hyphob_moment;
		}
	if (max_hyphob_moment > ordinate_max)
		{
		ordinate_max = max_hyphob_moment;
		}
	}

if (runtimeSP->sided_hydrophobicityF)
	{
	if (min_sided_hyphob < ordinate_min)
		{
		ordinate_min = min_sided_hyphob;
		}
	if (max_sided_hyphob > ordinate_max)
		{
		ordinate_max = max_sided_hyphob;
		}
	}

if (runtimeSP->function1F)
	{
	if (min_function1 < ordinate_min)
		{
		ordinate_min = min_function1;
		}
	if (max_function1 > ordinate_max)
		{
		ordinate_max = max_function1;
		}
	}

if (runtimeSP->function2F)
	{
	if (min_function2 < ordinate_min)
		{
		ordinate_min = min_function2;
		}
	if (max_function2 > ordinate_max)
		{
		ordinate_max = max_function2;
		}
	}

if (runtimeSP->function3F)
	{
	if (min_function3 < ordinate_min)
		{
		ordinate_min = min_function3;
		}
	if (max_function3 > ordinate_max)
		{
		ordinate_max = max_function3;
		}
	}

if (runtimeSP->function4F)
	{
	if (min_function4 < ordinate_min)
		{
		ordinate_min = min_function4;
		}
	if (max_function4 > ordinate_max)
		{
		ordinate_max = max_function4;
		}
	}

if (runtimeSP->function5F)
	{
	if (min_function5 < ordinate_min)
		{
		ordinate_min = min_function5;
		}
	if (max_function5 > ordinate_max)
		{
		ordinate_max = max_function5;
		}
	}

if (runtimeSP->function6F)
	{
	if (min_function6 < ordinate_min)
		{
		ordinate_min = min_function6;
		}
	if (max_function6 > ordinate_max)
		{
		ordinate_max = max_function6;
		}
	}

if (runtimeSP->function7F)
	{
	if (min_function7 < ordinate_min)
		{
		ordinate_min = min_function7;
		}
	if (max_function7 > ordinate_max)
		{
		ordinate_max = max_function7;
		}
	}

/* Shift both values slightly for esthetic reasons: */
ordinate_range = ordinate_max - ordinate_min;
ordinate_min -= 0.15 * ordinate_range; 
ordinate_max += 0.15 * ordinate_range;

/* Prepare the ordinate scale factor: */
ordinate_range = ordinate_max - ordinate_min;
if (ordinate_range != 0.0)
	{
	ordinate_scale = (double) section_height / ordinate_range;
	}
else ordinate_scale = 0.0;

/*------draw vertical grid (every 10 residues):------------------------------*/

/* Initialize the visible residue index: */
visible_residueI = 0;

/* Scan the sequence: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Check is the residue array index inside the range: */
	if ((residueI < range_startI) || (residueI > range_endI))
		{
		continue;
		}

	/* Draw line at the following positions: 10, 20, 30, ... */
	if (((visible_residueI + 1) % 10) != 0)
		{
		visible_residueI++;
		continue;
		}

	/* Prepare the position: */
	sectionI = visible_residueI / residues_per_sectionN;
	local_residueI = visible_residueI % residues_per_sectionN;
	screen_x = screen_margin_x + local_residueI * residue_screen_width;
	if ((screen_x >= frame_x1 - 3) || (screen_x <= frame_x0 + 3))
		{
		visible_residueI++;
		continue;
		}

	/* Top and bottom of the vertical line: */
	screen_y0 = screen_margin_top + (sectionI + 1) * section_height - 4;
	screen_y1 = screen_margin_top + sectionI * section_height + 4;

	/* Draw line: */
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[2],
		   screen_x, screen_y0, screen_x, screen_y1);
	XDrawLine (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID,
		   guiSP->theGCA[4],
		   screen_x + 1, screen_y0, screen_x + 1, screen_y1);

	/* Update the counter of visible residues: */
	visible_residueI++;
	}

/*------draw abscisa:--------------------------------------------------------*/

/* Left and right extent of the abscisa axis: */
screen_x0 = frame_x0 + 4;
screen_x1 = frame_x1 - 4;

/* Draw abscisa in each section: */
if ((ordinate_min < 0.0) && (ordinate_max > 0.0))
	{
	for (sectionI = 0; sectionI < sectionsN; sectionI++)
		{
		d = -ordinate_min * ordinate_scale;
		screen_y0 = screen_margin_top +
			    (sectionI + 1) * section_height -
			    (int) d;
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y0 + 1, screen_x1, screen_y0 + 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y0, screen_x1, screen_y0);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[4],
			   screen_x0, screen_y0 - 1, screen_x1, screen_y0 - 1);
		}
	}

/*------draw labels:---------------------------------------------------------*/

/* Text height and ascent for the main window font: */
text_height = guiSP->main_winS.font_height;
text_ascent = guiSP->main_winS.fontSP->ascent;

/* Prepare the text color: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
		guiSP->main_winS.fg_colorID);

/* Reset the visible residue index: */
visible_residueI = 0;

/* Scan the sequence: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Check is the residue array index inside the range: */
	if ((residueI < range_startI) || (residueI > range_endI))
		{
		continue;
		}

	/* Write label at the following positions: 10, 20, 30, ... */
	if (((visible_residueI + 1) % 10) != 0)
		{
		visible_residueI++;
		continue;
		}

	/* Use the stored sequence index: */
	residue_serialI = *(runtimeSP->serialIP + residueI);

	/* Prepare section index and local residue index: */
	sectionI = visible_residueI / residues_per_sectionN;
	local_residueI = visible_residueI % residues_per_sectionN;

	/* Prepare the label: */
	sprintf (stringA, "%d", residue_serialI);
	string_length = strlen (stringA);
	text_width = XTextWidth (guiSP->main_winS.fontSP,
				 stringA, strlen (stringA));
	half_text_width = text_width / 2;

	/* Prepare the position where the label should be drawn: */
	screen_x = screen_margin_x +
		   local_residueI * residue_screen_width -
		   half_text_width;
	if ((screen_x >= frame_x1 - text_width - 3) ||
	    (screen_x <= frame_x0 + 3))
		{
		visible_residueI++;
		continue;
		}
	d = -ordinate_min * ordinate_scale;
	screen_y = screen_margin_top + (sectionI + 1) * section_height - 5;

	/* Draw the label: */
	XDrawString (guiSP->displaySP,
		     guiSP->main_hidden_pixmapID,
		     guiSP->theGCA[0],
		     screen_x, screen_y,
		     stringA, strlen (stringA));

	/* Update the local residue index: */
	visible_residueI++;
	}

/*------draw average hydrophobicity (red line):------------------------------*/

if (runtimeSP->average_hydrophobicityF)
	{
	/* Prepare three colors for average hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/8888/8888", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:FFFF/0000/0000", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:8888/0000/0000", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the average hydrophobicity: */
		average_hydrophobicity =
			(double) *(runtimeSP->average_hydrophobicityP +
				   residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (average_hydrophobicity - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = average_hydrophobicity;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw weighted hydrophobicity (pink line):----------------------------*/

if (runtimeSP->weighted_hydrophobicityF)
	{
	/* Prepare three colors for weighted hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/8888/BBBB", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:FFFF/0000/BBBB", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:9999/0000/5555", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the weighted hydrophobicity: */
		weighted_hydrophobicity =
			(double) *(runtimeSP->weighted_hydrophobicityP +
				   residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (weighted_hydrophobicity - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = weighted_hydrophobicity;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}


/*------draw hydrophobic moment (blue line):---------------------------------*/

if (runtimeSP->hydrophobic_momentF)
	{
	/* Prepare three colors for hydrophobic moment: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:8888/DDDD/FFFF", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:0000/8888/FFFF", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:0000/4444/8888", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the hydrophobic moment: */
		hydrophobic_moment =
			(double) *(runtimeSP->hydrophobic_momentP +
				   residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (hydrophobic_moment - ordinate_min) * ordinate_scale;

		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y0) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = hydrophobic_moment;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw sided hydrophobicities (two lines, two tones of magenta):-------*/

if (runtimeSP->sided_hydrophobicityF)
	{

	/*------draw upper line:---------------------------------------------*/

	/* Prepare three colors for larger side hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/8888/DDDD", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:FFFF/0000/BBBB", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:9999/0000/5555", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the larger side hydrophobicity: */
		larger_side_hyphob  =
			(double) *(runtimeSP->larger_sided_hyphobP + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (larger_side_hyphob - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = larger_side_hyphob;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}

	/*------draw bottom line:--------------------------------------------*/

	/* Prepare three colors for smaller side hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:DDDD/8888/FFFF", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:BBBB/0000/FFFF", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:5555/0000/9999", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the smaller sided hydrophobicity: */
		smaller_side_hyphob =
			(double) *(runtimeSP->smaller_sided_hyphobP +
			residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (smaller_side_hyphob - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = smaller_side_hyphob;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}

	/*-------------------------------------------------------------------*/

	}

/*------draw hydrophobicity function F1 (orange line):-----------------------*/

if (runtimeSP->function1F)
	{
	/* Prepare three colors for function F1: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/AAAA/5555", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:FFFF/8888/0000", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:8888/4444/0000", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function1 = (double) *(runtimeSP->function1P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function1 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function1;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F2 (green line):------------------------*/

if (runtimeSP->function2F)
	{
	/* Prepare three colors for function F2: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:9999/FFFF/7777", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:2222/FFFF/0000", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:1111/8888/0000", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function2 = (double) *(runtimeSP->function2P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function2 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function2;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F3 (yellow line):-----------------------*/

if (runtimeSP->function3F)
	{
	/* Prepare three colors for function F3: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/FFFF/0000", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:DDDD/DDDD/0000", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:8888/8888/0000", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function3 = (double) *(runtimeSP->function3P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function3 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function3;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F4 (cyan line):-------------------------*/

if (runtimeSP->function4F)
	{
	/* Prepare three colors for function F4: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:0000/FFFF/FFFF", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:0000/DDDD/DDDD", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:0000/8888/8888", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function4 = (double) *(runtimeSP->function4P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function4 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function4;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F5 (dark blue line):--------------------*/

if (runtimeSP->function5F)
	{
	/* Prepare three colors for function F5: */
        ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:0000/0000/FFFF", "white");
        ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:0000/0000/BBBB", "white");
        ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:0000/0000/7777", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function5 = (double) *(runtimeSP->function5P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function5 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function5;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F6 (again red line):--------------------*/

if (runtimeSP->function6F)
	{
	/* Prepare three colors for function F6: */
        /* Prepare three colors for average hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:FFFF/8888/8888", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:FFFF/0000/0000", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:8888/0000/0000", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function6 = (double) *(runtimeSP->function6P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function6 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function6;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------draw hydrophobicity function F7 (again blue line):-------------------*/

if (runtimeSP->function7F)
	{
	/* Prepare three colors for function F7: */
        /* Prepare three colors for average hydrophobicity: */
	ParseColor_ (&rgbS, &color1ID, guiSP, "RGB:8888/DDDD/FFFF", "white");
	ParseColor_ (&rgbS, &color2ID, guiSP, "RGB:0000/8888/FFFF", "white");
	ParseColor_ (&rgbS, &color3ID, guiSP, "RGB:0000/4444/8888", "black");
	XSetForeground (guiSP->displaySP, guiSP->theGCA[1], color1ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[2], color2ID);
	XSetForeground (guiSP->displaySP, guiSP->theGCA[3], color3ID);

	/* Reset the counter of visible residues: */
	visible_residueI = 0;

	/* Scan the sequence: */
	for (residueI = 0; residueI < residuesN; residueI++)
		{
		/* Check is the residue array index inside the range: */
		if ((residueI < range_startI) || (residueI > range_endI))
			{
			continue;
			}

		/* Copy the function value: */
		function7 = (double) *(runtimeSP->function7P + residueI);

		/* Prepare the section index: */
		sectionI = visible_residueI / residues_per_sectionN;

		/* Prepare the local residue index: */
		local_residueI = visible_residueI % residues_per_sectionN;

		/* Prepare screen coordinates: */
		screen_x0 = screen_margin_x +
			    local_residueI * residue_screen_width -
			    half_residue_width - 1;
		screen_x1 = screen_x0 + residue_screen_width + 2;
		d = (function7 - ordinate_min) * ordinate_scale;
		screen_y0 = screen_margin_top + sectionI * section_height;
		screen_y1 = screen_y0 + section_height;
		screen_y  = screen_y1 - (int) d;

		/* Draw triple line: */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[1],
			   screen_x0, screen_y - 1,
			   screen_x1, screen_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_x0, screen_y,
			   screen_x1, screen_y);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[3],
			   screen_x0, screen_y + 1,
			   screen_x1, screen_y + 1);

		/* Initialize  the flag  which says is */
		/* it necessary to draw vertical line: */
		draw_vertical_lineF = 1;

		/* For  the first residue in  the current */
		/* section do not draw the vertical line: */
		if (local_residueI == 0)
			{
			old_screen_y = screen_y0;
			draw_vertical_lineF = 0;
			}

		/* For the first residue, do not draw the vertical line: */
		if (residueI == range_startI)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Check is it necessary to draw vertical line: */
		if (old_screen_y == screen_y)
			{
			old_screen_y = screen_y;
			draw_vertical_lineF = 0;
			}

		/* Prepare the shift which is required to draw corners; take */
		/* the next res. if there is no need to draw vertical lines: */
		if (old_screen_y < screen_y) shift = -1;
		else shift = +1;

		/* Draw three vertical lines: */
		if (draw_vertical_lineF)
			{
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[1],
				   screen_x0, old_screen_y - shift,
				   screen_x0, screen_y - shift);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[2],
				   screen_x0 + 1, old_screen_y,
				   screen_x0 + 1, screen_y);
			XDrawLine (guiSP->displaySP,
				   guiSP->main_hidden_pixmapID,
				   guiSP->theGCA[3],
				   screen_x0 + 2, old_screen_y + shift,
				   screen_x0 + 2, screen_y + shift);
			}

		/* Copy the y coordinate for later use: */
		old_screen_y = screen_y;

		/* Fill NearestAtomS array: */
		for (screen_x  = screen_x0 + 2;
		     screen_x <= screen_x1 - 1;
		     screen_x++)
			{
			for (screen_y  = screen_y0;
			     screen_y <= screen_y1;
			     screen_y++)
				{
				/* Prepare index  to the array */
				/* of NearestAtomS structures: */
				pixelI = guiSP->main_win_free_area_width *
					 screen_y + screen_x;

				/* Check the pixel index: */
				if (pixelI >= pixelsN) continue;

				/* Pointer to  NearestAtomS struct. */
				/* assigned to current coordinates: */
				curr_pixelSP = nearest_atomSP + pixelI;

				/* Refresh NearestAtomS associated with */
				/* this pixel;  residue index is stored */
				/* to location reserved for atom index. */
				curr_pixelSP->last_refreshI = refreshI;
				curr_pixelSP->atomI = residueI;
				curr_pixelSP->z = function7;
				}
			}

		/* Update the counter of visible residues: */
		visible_residueI++;
		}
	}

/*------copy the prepared image to the main window:--------------------------*/

/* Copy hidden pixmap to the main window: */
XCopyArea (guiSP->displaySP,
	   guiSP->main_hidden_pixmapID, guiSP->main_winS.ID,
	   guiSP->theGCA[0],
	   0, 0,
	   guiSP->main_win_free_area_width, guiSP->main_win_free_area_height,
	   0, 0);

return (size_t) residuesN;
}

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


