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

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

				quick_select.c

Purpose:
	Execute select command  (the quick version):  try to interpret the
	selection string as short selection string. Three selections modes
	are available:  0 = overwrite,  1 = restrict,  2 = expand previous
	selection.

Input:
	(1) Pointer to MolComplexS structure, with macromol. complexes.
	(2) Number of macromolecular complexes.
	(3) The selection string.
	(4) Selection mode index  (0 = overwr., 1 = restrict, 2 = expand).

Output:
	(1) The flag selectedF will be equal to one for selected atoms and
	    equal to zero for all other atoms.
	(2) Return value.

Return value:
	(1) The number of  selected atoms,  if selection  is done  in this
	    function.
	(2) Negative value on failure.

Notes:
	(1) This function  will try  to interpret  the selection string as
	    the set of residue ranges or as the set of residue names.  The
	    decision will be based on the string content: if it appears to
	    consist of printable characters which are  not alphabetic,  it
	    will be interpreted as  the set of residue ranges.  Otherwise,
	    it will be  interpreted as  the set  of residue names.  If the
	    string contains keyword EXCEPT (EXC), it may be interpreted as
	    a set of residue ranges  though it contains  alphabetic chars.

	(2) There is  no way to specify  the chain identifiers  and atomic
	    names using the "quick" selection syntax.  Only residue ranges
	    and residue names may be specified.

	(3) The return value  -1  has no special meaning,  except that the
	    selection job was not done properly.

========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 "typedefs.h"

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

int		Include_ (SelectS *, char *);
int		Exclude_ (SelectS *, char *);
long		ApplySelection_ (MolComplexS *, int,
				 SelectS *, SelectS *, int);

/*======execute select command (quick selection string):=====================*/

long QuickSelect_ (MolComplexS *mol_complexSP, int mol_complexesN,
		   char *stringP, int selection_modeI)
{
long		selected_atomsN;
char		copyA[STRINGSIZE];
int		rangesF;
char		*P;
int		n;
char		full_stringA[STRINGSIZE];
SelectS		include_selectS, exclude_selectS;

/* The short (quick) selection string should not contain any slashes: */
if (strstr (stringP, "/") != NULL) return (long) -1;

/* Make a copy of the string, to allow some modifications before check: */
strncpy (copyA, stringP, STRINGSIZE - 1);
copyA[STRINGSIZE - 1] = '\0';

/* If keyword  EXC  is present,  replace  all */
/* alphabetic characters after E with blanks: */
if ((P = strstr (copyA, "EXC")) != NULL)
	{
	while ((n = *P++) != '\0')
		{
		if (!isalpha (n)) break;
		else *(P - 1) = ' ';
		}
	}

/* Try to recognize the string type. The rangesF will be */
/* equal to one  if the specifyed string  was recognized */
/* as the set of residue ranges  and to  zero otherwise. */
rangesF = 1;
P = copyA;
while ((n = *P++) != '\0')
	{
	if (isalpha (n))
		{
		rangesF = 0;
		break;
		}
	}

/* Prepare the full selection string: */

/** If string was recognized as the set of residue ranges: **/
if (rangesF) sprintf (full_stringA, "*/%s/*/*", stringP);

/** If string was not recognized as the set of residue ranges, **/
/** assume it can be interpreted as  the set of residue names: **/
else sprintf (full_stringA, "*/*/%s/*", stringP);

/* Identify chains,  residue ranges,  residue */
/* names and atoms which have to be included: */
if (Include_ (&include_selectS, full_stringA) < 0) return (long) -2;

/* Identify chains,  residue ranges,  residue */
/* names and atoms which have to be excluded: */
if (Exclude_ (&exclude_selectS, full_stringA) < 0) return (long) -3;

/* Do the selection: */
selected_atomsN = ApplySelection_ (mol_complexSP, mol_complexesN,
				   &include_selectS, &exclude_selectS,
				   selection_modeI);

/* Return the number of selected atoms: */
return selected_atomsN;
}

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


