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

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

				exclude.c

Purpose:
	Identify chains, residue ranges, residue names and atom names
	which have to be excluded from selection.

Input:
	(1) Pointer to SelectS structure, where data will be stored.
	(2) Pointer to the selection string.

Output:
	(1) SelectS structure filled with data.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) 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"

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

char		*ExtractToken_ (char *, int, char *, char *);
char		*SkipKeyword_ (char *, char *);
int		ExtractChains_ (SelectS *, char *);
int		ExtractResidueRanges_ (SelectS *, char *);
int		ExtractResidueNames_ (SelectS *, char *);
int		ExtractAtomNames_ (SelectS *, char *);

/*======identify excluded ranges and names:==================================*/

int Exclude_ (SelectS *exclude_selectSP, char *stringP)
{
char		string_copyA[STRINGSIZE];
char		*remainderP;
char		tokenA[STRINGSIZE];
char		*exceptP, *dataP;

/* Copy the input string to preserve it: */
strncpy (string_copyA, stringP, STRINGSIZE - 1);
string_copyA[STRINGSIZE - 1] = '\0';

/* Pointer to the remainder of the string */
/* initially points to  the whole string: */
remainderP = stringP;

/* The first token should contain chain identifiers: */
remainderP = ExtractToken_ (tokenA, STRINGSIZE, remainderP, "/");
if (remainderP == NULL) return -1;

/* If keyword exc is present, skip one token and extract chain identifiers: */
if ((exceptP = strstr (tokenA, "EXC")) != NULL)
	{
	/** Skip one token: **/
	if ((dataP = SkipKeyword_ (exceptP, " \t,;")) == NULL) return -2;

	/** Extract chain identifiers: **/
	if (ExtractChains_ (exclude_selectSP, dataP) < 0) return -3;
	}

/* If keyword exc is not present, initialize flag and count: */
else
	{
	/** Initialize all_chainsF (1 = select all chains): **/
	exclude_selectSP->all_chainsF = 0;

	/** Initialize the number of chain identifiers: **/
	exclude_selectSP->chainsN = 0;
	}

/* The second token should contain residue ranges: */
remainderP = ExtractToken_ (tokenA, STRINGSIZE, remainderP, "/");
if (remainderP == NULL) return -4;

/* If keyword exc is present, skip one token and extract residue ranges: */
if ((exceptP = strstr (tokenA, "EXC")) != NULL)
	{
	/** Skip one token: **/
	if ((dataP = SkipKeyword_ (exceptP, " \t,;")) == NULL) return -5;

	/** Extract residue ranges: **/
	if (ExtractResidueRanges_ (exclude_selectSP, dataP) < 0) return -6;
	}

/* If keyword exc is not present, initialize flag and count: */
else
	{
	/* Initialize all_residue_serialF (1 = select all serial numbers): */
	exclude_selectSP->all_residue_serialF = 0;

	/* Initialize the number of ranges: */
	exclude_selectSP->residue_serial_rangesN = 0;
	}

/* The third token should contain residue names: */ 
remainderP = ExtractToken_ (tokenA, STRINGSIZE, remainderP, "/");
if (remainderP == NULL) return -7;

/* If keyword exc is present, skip one token and extract residue names: */
if ((exceptP = strstr (tokenA, "EXC")) != NULL)
	{
	/** Skip one token: **/
	if ((dataP = SkipKeyword_ (exceptP, " \t,;")) == NULL) return -8;

	/** Extract residue names: **/
	if (ExtractResidueNames_ (exclude_selectSP, dataP) < 0) return -9;
	}

/* If keyword exc is not present, initialize flag and count: */
else
	{
	/* Initialize all_residue_namesF (1 = select all residue names): */
	exclude_selectSP->all_residue_namesF = 0;

	/* Initialize the number of residue names: */
	exclude_selectSP->residue_namesN = 0;
	}

/* The fourth (the last) token should contain atom names: */ 
remainderP = ExtractToken_ (tokenA, STRINGSIZE, remainderP, "/");
if (remainderP == NULL) return -10;

/* If keyword exc is present, skip one token and extract atom names: */
if ((exceptP = strstr (tokenA, "EXC")) != NULL)
	{
	/** Skip one token: **/
	if ((dataP = SkipKeyword_ (exceptP, " \t,;")) == NULL) return -11;

	/** Extract chain identifiers: **/
	if (ExtractAtomNames_ (exclude_selectSP, dataP) < 0) return -12;
	}

/* If keyword exc is not present, initialize flag and count: */
else
	{
	/* Initialize all_atom_namesF (1 = select all atom names): */
	exclude_selectSP->all_atom_namesF = 0;

	/* Initialize the number of atom names: */
	exclude_selectSP->atom_namesN = 0;
	}

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

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


