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

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

				pattern.c

Purpose:
	Execute pattern command:  define the residue pattern. Residue
	pattern is relatively short, but more flexible than sequence.
	More than one residue may be specified at the given position.
	The length of pattern is fixed, i.e. deletions and insertions
	are not allowed. Asterisk may be used to allow any residue at
	the given position.  The only  keyword which  may be combined
	with the command PATTERN is  TOLERANCE.  Default tolerance is
	zero.  The command PAT TOL (long form: PATTERN TOLERANCE) may
	be used  to change  the tolerance.  When searching  the given
	structure for  some pattern,  the tolerance  defines how many
	mismatches are acceptable.

Input:
	(1) Pointer to MolComplexS structure.
	(2) The number of macromolecular complexes.
	(3) Pointer to RuntimeS structure.
	(4) Pointer to the string with command parameters.

Output:
	(1) Pattern stored to the pattern buffer.
	(2) Return value.

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

Notes:
	(1) The pattern is expected in three letters code. One letter
	    code may be missinterpreted  as valid three letters code.

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

#include <stdio.h>

#include <string.h>
#include <ctype.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "commands.h"
#include "typedefs.h"

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

int		ParsePattern_ (RuntimeS *, char *);
char		*ExtractToken_ (char *, int, char *, char *);

/*======execute pattern command:=============================================*/

int Pattern_ (MolComplexS *mol_complexSP, int mol_complexesN,
	      RuntimeS *runtimeSP, char *stringP)
{
char		string_copyA[STRINGSIZE];
char		*P;
char		*patternP;
int		n;
char		*remainderP;
char		tokenA[SHORTSTRINGSIZE];
int		tolerance;

/* Copy the original command string: */
strncpy (string_copyA, runtimeSP->curr_commandA, STRINGSIZE - 1);
string_copyA[STRINGSIZE - 1] = '\0';

/* Check is the equality sign present in the original command string: */
if ((P = strstr (string_copyA, "=")) != NULL)
        {
	/* Prepare the pointer to the pattern: */
	patternP = P + 1;

	/* Convert pattern to uppercase: */
	P = patternP;
	while ((n = *P++) != '\0') *(P - 1) = toupper (n);

	/* Parse and store the pattern: */
	n = ParsePattern_ (runtimeSP, patternP);
	if (n > 0) return COMMAND_PATTERN;
	else return ERROR_PATTERN;
	}

/* If this point  is reached,  the equality sign  was not found */
/* in the original command string. Check for keyword TOLERANCE. */

/* Take the first token; it should be present: */
remainderP = ExtractToken_ (tokenA, SHORTSTRINGSIZE, stringP, " \t\n");
if (!remainderP)
	{
	strcpy (runtimeSP->messageA, "Command parameter(s) missing!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return ERROR_PATTERN;
	}

/* If keyword TOLERANCE (short form: TOL) is present, extract tolerance: */
if (strstr (tokenA, "TOL") == tokenA)
	{
	/* Replace each non-numeric character (except */
	/* minus sign and  decimal point) with space: */
	P = stringP;
	while ((n = *P++) != '\0')
		{
		if (!isdigit (n) && (n != '-') && (n != '.')) *(P - 1) = ' ';
		}

	/* Try to extract the pattern tolerance: */
	if (sscanf (stringP, "%d", &tolerance) != 1)
		{
		strcpy (runtimeSP->messageA,
			"Failed to extract the pattern tolerance!");
		runtimeSP->message_length = strlen (runtimeSP->messageA);
		return ERROR_PATTERN;
		}

	/* Check the value; negative value is not acceptable: */
	if (tolerance < 0)
		{
		strcpy (runtimeSP->messageA,
			"Negative tolerance is not accepted!");
		runtimeSP->message_length = strlen (runtimeSP->messageA);
		return ERROR_PATTERN;
		}

	/* If this point is reached, new tolerance is good. Store it: */
	runtimeSP->pattern_tolerance = tolerance;

	/*@@*/
	return COMMAND_PATTERN;
	}


/* If keyword recognition failed: */
else
	{
	strcpy (runtimeSP->messageA, "Keyword not recognized!");
	runtimeSP->message_length = strlen (runtimeSP->messageA);
	return ERROR_PATTERN;
	}

/* Return the command code: */
return COMMAND_PATTERN;
}

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


