/* ===========================================================================
*
*                            PUBLIC DOMAIN NOTICE
*               National Center for Biotechnology Information
*
*  This software/database is a "United States Government Work" under the
*  terms of the United States Copyright Act.  It was written as part of
*  the author's official duties as a United States Government employee and
*  thus cannot be copyrighted.  This software/database is freely available
*  to the public for use. The National Library of Medicine and the U.S.
*  Government have not placed any restriction on its use or reproduction.
*
*  Although all reasonable efforts have been taken to ensure the accuracy
*  and reliability of the software and data, the NLM and the U.S.
*  Government do not and cannot warrant the performance or results that
*  may be obtained by using this software or data. The NLM and the U.S.
*  Government disclaim all warranties, express or implied, including
*  warranties of performance, merchantability or fitness for any particular
*  purpose.
*
*  Please cite the author in any work or product based on this material.
*
* ===========================================================================*/
#ifndef __BLAST_ALPHABET__
#define __BLAST_ALPHABET__
#ifdef __cplusplus
extern "C" {
#endif

/* Tie into the ASN.1 specification for Seq_code */
#ifndef Seq_code_iupacna
#define Seq_code_iupacna	1
#define Seq_code_iupacaa	2
#define Seq_code_ncbi2na	3
#define Seq_code_ncbi4na	4
#define Seq_code_ncbi8na	5
#define Seq_code_ncbipna	6
#define Seq_code_ncbi8aa	7
#define Seq_code_ncbieaa	8
#define Seq_code_ncbipaa	9
#define Seq_code_iupacaa3	10
#define Seq_code_ncbistdaa	11
#endif

typedef enum {
		BLAST_ALPHA_PRINT = 0 ,
		BLAST_ALPHA_IUPACna = Seq_code_iupacna ,
		BLAST_ALPHA_IUPACaa = Seq_code_iupacaa ,
		BLAST_ALPHA_NCBI2na = Seq_code_ncbi2na ,
		BLAST_ALPHA_NCBI4na = Seq_code_ncbi4na ,
		BLAST_ALPHA_NCBI8na = Seq_code_ncbi8na ,
		BLAST_ALPHA_NCBIpna = Seq_code_ncbipna ,
		BLAST_ALPHA_NCBI8aa = Seq_code_ncbi8aa ,
		BLAST_ALPHA_NCBIeaa = Seq_code_ncbieaa ,
		BLAST_ALPHA_NCBIpaa = Seq_code_ncbipaa ,
		BLAST_ALPHA_IUPACaa3 = Seq_code_iupacaa3 ,
		BLAST_ALPHA_NCBIstdaa = Seq_code_ncbistdaa ,
		BLAST_ALPHA_OLDBLASTaa = 200 ,
		BLAST_ALPHA_OLDBLASTna = 201
	} BLAST_AlphaID;


#define BLAST_ALPHAMAP_TST(amp,ch) ((amp)->maptst[(ch)])
#define BLAST_ALPHAMAP_CHR(amp,ch) ((amp)->map[(ch)])

/*
  BLAST_Letter is an alphabetic letter.
*/
typedef unsigned char	BLAST_Letter, PNTR BLAST_LetterPtr;
#define BLAST_LETTER_SIZE	1
#define BLAST_LETTER_MIN	0
#define BLAST_LETTER_MAX	UCHAR_MAX

/*
BLAST_ALPHASIZE_MAX is the maximum no. of letters permitted in an alphabet.
*/
#define BLAST_ALPHASIZE_MAX	((int)(1<<(CHAR_BIT*sizeof(BLAST_Letter))))

#define BLAST_SOFT_SENTINEL	0xfc

typedef enum {
		BLAST_ALPHATYPE_UNDEFINED = 0,
		BLAST_ALPHATYPE_AMINO_ACID = 1,
		BLAST_ALPHATYPE_NUCLEIC_ACID = 2,
		BLAST_ALPHATYPE_ANY = 3
	} BLAST_AlphaType, PNTR BLAST_AlphaTypePtr;

typedef struct _blast_alphabet {
		struct _blast_alphabet	PNTR previous, PNTR next;
		BLAST_AlphaType	alphatype;	/* Type or class of alphabet */
		CharPtr			name;	/* Case-independent name for the alphabet */
		BLAST_AlphaID	id;
		size_t			alphasize;	/* No. of letters in the alphabet */
		BLAST_LetterPtr	alist;		/* List of letters */

		BLAST_Letter	letter_min, letter_max; /* min & max letter values */
		BLAST_Letter	minval, maxval; /* min & max values, incl. sentinel */
		Nlm_Boolean		hard_sentinel; /* TRUE==>sentinel is not in alphabet */
		BLAST_Letter	sentinel;
		unsigned		bpl; /* min. no. of bits per letter */
		Nlm_Boolean		initialized;  /* non-zero ==> struct is initialized */
		struct _blast_alphamap	PNTR inmap, PNTR outmap;
		Nlm_Boolean		PNTR _membertst0, PNTR membertst;
	} BLAST_Alphabet, PNTR BLAST_AlphabetPtr;

typedef struct {
		BLAST_Letter	from, to;
	} BLAST_LetterPair, PNTR BLAST_LetterPairPtr;

typedef struct _blast_alphamap {
		struct _blast_alphamap	PNTR previous, PNTR next;
		BLAST_AlphabetPtr	from, to;
		size_t				npairs;
		BLAST_LetterPairPtr	pair; /* list of letter pairs */
		BLAST_LetterPtr		_map0, map;
		Nlm_Boolean			PNTR _maptst0, PNTR maptst;
		Nlm_Boolean			initialized;
	} BLAST_AlphaMap, PNTR BLAST_AlphaMapPtr;

BLAST_EXTERN BLAST_AlphabetPtr	blast_ncbistdaa,
								blast_blastaa,
								blast_iupacaa,
								blast_ncbi2na,
								blast_ncbi4na,
								blast_blastna,
								blast_iupacna
								;

BLAST_Error	_blast_alphabet_init PROTO((void));
BLAST_Error	BlastAlphabetInit PROTO((BLAST_AlphabetPtr));
BLAST_Error BlastAlphabetRegister PROTO((BLAST_AlphabetPtr));
BLAST_Error BlastAlphabetUnregister PROTO((BLAST_AlphabetPtr));
Nlm_Boolean BlastAlphabetIsRegistered PROTO((BLAST_AlphabetPtr));
Nlm_Boolean	BlastAlphabetTst PROTO((BLAST_AlphabetPtr,BLAST_Letter));
BLAST_AlphabetPtr BlastAlphabetFindByName PROTO((CharPtr));
BLAST_AlphabetPtr BlastAlphabetFindByID PROTO((BLAST_AlphaID));

BLAST_Error BlastAlphaMapInit PROTO((BLAST_AlphaMapPtr));
BLAST_Error BlastAlphaMapRegister PROTO((BLAST_AlphaMapPtr));
BLAST_Error BlastAlphaMapUnregister PROTO((BLAST_AlphaMapPtr));
Nlm_Boolean BlastAlphaMapIsRegistered PROTO((BLAST_AlphaMapPtr));
BLAST_AlphaMapPtr BlastAlphaMapFind PROTO((BLAST_AlphabetPtr from, BLAST_AlphabetPtr to));
BLAST_AlphaMapPtr BlastAlphaMapFindCreate PROTO((BLAST_AlphabetPtr from, BLAST_AlphabetPtr to));
BLAST_Letter	BlastAlphaMapChr PROTO((BLAST_AlphaMapPtr, BLAST_Letter));
Nlm_Boolean		BlastAlphaMapTst PROTO((BLAST_AlphaMapPtr, BLAST_Letter));


/* Datatypes */
#define Letter	BLAST_Letter
#define LetterPtr	BLAST_LetterPtr
#define AlphaType	BLAST_AlphaType
#define AlphaTypePtr	BLAST_AlphaTypePtr
#define Alphabet	BLAST_Alphabet
#define AlphaMap	BLAST_AlphaMap

/* Functions */

#define AlphabetInit	BlastAlphabetInit
#define AlphabetTst		BlastAlphabetTst
#define AlphabetRegister	BlastAlphabetRegister
#define AlphabetUnregister	BlastAlphabetUnregister
#define AlphabetIsRegistered	BlastAlphabetIsRegistered
#define AlphabetFindByName	BlastAlphabetFindByName
#define AlphabetFindByID	BlastAlphabetFindByID

#define AlphaMapInit	BlastAlphaMapInit
#define AlphaMapRegister	BlastAlphaMapRegister
#define AlphaMapUnregister	BlastAlphaMapUnregister
#define AlphaMapIsRegistered	BlastAlphaMapIsRegistered
#define AlphaMapFind	BlastAlphaMapFind
#define AlphaMapCreate	BlastAlphaMapCreate
#define AlphaMapChr	BlastAlphaMapChr
#define AlphaMapTst	BlastAlphaMapTst

#ifdef __cplusplus
}
#endif
#endif /* !_BLAST_ALPHABET_ */

