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

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

				plot_mouse.c

Purpose:
	Handle MotionNotify events if the main window contains hydrophobicity
	plot(s).

Input:
	(1) Pointer to RuntimeS structure, with runtime data.
	(2) Pointer to GUIS structure, with GUI data.
	(3) Pointer to NearestAtomS structure.
	(4) The number of pixels in the main window free area.
	(5) Pointer to refreshI.
	(6) Pointer to XMotionEvent structure.

Output:
	(1) The information about residue covered by mouse pointer written to
	    the output window.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Zero if event is ignored.
	(3) Negative on failure.

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

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

/*======handle MotionNotify events for hydrophobicity plots:=================*/

int PlotMouse_ (RuntimeS *runtimeSP, GUIS *guiSP,
		NearestAtomS *nearest_atomSP, size_t pixelsN,
		unsigned int refreshI,
		XMotionEvent *motion_eventSP)
{
int			residue_name_length;
int			space_width, space_half_width;
size_t			pixelI;
NearestAtomS		*pixelSP;
int			central_residueI, first_residueI, last_residueI;
int			residueI;
char			*residue_nameP;
char			residue_nameA[RESNAMESIZE];
int			residue_sequenceI;
double			value;
static char		stringA[STRINGSIZE];
int			string_length;
int			line_height;
int			screen_x0, screen_y0;
int			text_width;
int			line_x0 = 0, line_x1 = 0;
int			width, height;

/* Residue name length: */
residue_name_length = RESNAMESIZE - 1;

/* Space half-width: */
space_width = XTextWidth (guiSP->main_winS.fontSP, " ", 1);
space_half_width = space_width / 2;

/* If the event came from child window, return zero: */
if (motion_eventSP->subwindow != None) return 0;

/* Pixel index: */
pixelI = guiSP->main_win_free_area_width * motion_eventSP->y +
	 motion_eventSP->x;

/* Check the pixel index: */
if (pixelI >= pixelsN) return -1;

/* Pointer to NearestAtomS structure assigned with this pixel: */
pixelSP = nearest_atomSP + pixelI;

/* Check the refreshI associated with this pixel: */
if (pixelSP->last_refreshI != refreshI) return 0;

/* Refresh the output window: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
		guiSP->output_winS.bg_colorID);
XFillRectangle (guiSP->displaySP, guiSP->output_winS.ID, guiSP->theGCA[0],
		0, 0, guiSP->output_winS.width, guiSP->output_winS.height);

/* The central residue index: */
central_residueI = pixelSP->atomI;

/* Space half-width: */
space_width = XTextWidth (guiSP->main_winS.fontSP, " ", 1);
	      space_half_width = space_width / 2;

/* Prepare the residue name: */
residue_nameP = runtimeSP->sequenceP + central_residueI * residue_name_length;
strncpy (residue_nameA, residue_nameP, residue_name_length);
residue_nameA[residue_name_length] = '\0';

/* Prepare the residue sequence number: */
residue_sequenceI = *(runtimeSP->serialIP + central_residueI);

/* Prepare  the function value  (average */
/* hydrophob., hydrophobic moment etc.): */
value = pixelSP->z;

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

/* Text line height: */
line_height = guiSP->output_winS.text_line_height;

/* The initial drawing position: */
screen_x0 = TEXTMARGIN;
screen_y0 = guiSP->output_winS.font_height + 5;

/* Draw residue name and residue sequence number: */
sprintf (stringA, "%s %d", residue_nameA, residue_sequenceI);
stringA[SHORTSTRINGSIZE - 1] = '\0';
XDrawString (guiSP->displaySP, guiSP->output_winS.ID, guiSP->theGCA[0],
	     screen_x0, screen_y0, stringA, strlen (stringA));

/* Draw the function value: */
screen_y0 += line_height;
strcpy (stringA, "value:");
XDrawString (guiSP->displaySP, guiSP->output_winS.ID, guiSP->theGCA[0],
	     screen_x0, screen_y0, stringA, strlen (stringA));
screen_y0 += line_height;
sprintf (stringA, "%.3f", value);
XDrawString (guiSP->displaySP, guiSP->output_winS.ID, guiSP->theGCA[0],
	     screen_x0, screen_y0, stringA, strlen (stringA));

/* Now it's time to draw the sequence neighborhood of the central residue. */

/* Indices of the first and the last residue in the neighbourhood: */
first_residueI = central_residueI - NEIGH_HALF_WIDTH;
if (first_residueI < 0) first_residueI = 0;
last_residueI = central_residueI + NEIGH_HALF_WIDTH;
if (last_residueI > (int) runtimeSP->residuesN)
	{
	last_residueI = runtimeSP->residuesN;
	}

/* Prepare the string with the left part of the neighborhood: */
stringA[0] = '\0';
strcat (stringA, " ");
for (residueI = first_residueI; residueI <= last_residueI; residueI++)
	{
	/* The string width, without the central residue: */
	if (residueI == central_residueI)
		{
		string_length = strlen (stringA);
		line_x0 = XTextWidth (guiSP->main_winS.fontSP,
				      stringA, string_length) -
				      space_half_width;
		}

	/* Pointer to residue name: */
	residue_nameP = runtimeSP->sequenceP + residueI * residue_name_length;

	/* Add the residue name to the output string: */
	strncpy (residue_nameA, residue_nameP, residue_name_length);
	residue_nameA[residue_name_length] = '\0';
	strcat (stringA, residue_nameA);
	strcat (stringA, " ");

	/* The string width, including the central residue: */
	if (residueI == central_residueI)
		{
		string_length = strlen (stringA);
		line_x1 = XTextWidth (guiSP->main_winS.fontSP,
				      stringA, string_length) -
				      space_half_width;
		}
	}

/* String length: */
string_length = strlen (stringA);

/* Text width: */
text_width = XTextWidth (guiSP->main_winS.fontSP, stringA, string_length);

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

/* Refresh the string background: */
screen_x0 = 1;
screen_y0 = 1;
width = guiSP->control_winS.x0 - guiSP->main_winS.border_width - 2;
if (width < 0) width = 0;
height = guiSP->main_winS.font_height + 4;
XFillRectangle (guiSP->displaySP, guiSP->main_winS.ID, guiSP->theGCA[0],
		screen_x0, screen_y0,
		(unsigned int) width, (unsigned int) height);

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

/* Draw the bounding rectangle: */
XDrawRectangle (guiSP->displaySP, guiSP->main_winS.ID,
		guiSP->theGCA[0],
		screen_x0, screen_y0,
		(unsigned int) width, (unsigned int) height);

/* Draw the string which contains sequence neighborhood: */
screen_x0 = guiSP->control_winS.x0 / 2 - text_width / 2;
screen_y0 = guiSP->main_winS.font_height + 1;
XDrawString (guiSP->displaySP, guiSP->main_winS.ID, guiSP->theGCA[0],
	     screen_x0, screen_y0, stringA, string_length);

/* Draw rectangle bounding the central residue: */
line_x0 += guiSP->control_winS.x0 / 2 - text_width / 2;
line_x1 += guiSP->control_winS.x0 / 2 - text_width / 2;
width = line_x1 - line_x0 + 1;
if (width < 0) width = 0;
height = guiSP->main_winS.font_height - 1;
if (height < 0) height = 0;
screen_y0 = height;
XDrawRectangle (guiSP->displaySP, guiSP->main_winS.ID,
		guiSP->theGCA[0],
		line_x0, 4,
		(unsigned int) width, (unsigned int) height);

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

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


