/* ===========================================================================
*
*                            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_SCORE__
#define __BLAST_SCORE__
#ifdef __cplusplus
extern "C" {
#endif

/* BLAST_Score must be a signed datatype */
typedef long	BLAST_Score, PNTR BLAST_ScorePtr;

/*
SCORE_MIN is (-2**31 + 1)/2 because it has been observed more than once that
a compiler did not properly calculate the quantity (-2**31)/2.  The list
of compilers which failed this operation have at least at some time included:
NeXT and a version of AIX/370's MetaWare High C R2.1r.
For this reason, SCORE_MIN is not simply defined to be LONG_MIN/2.
*/
#define BLAST_SCORE_MIN	(-2147483647/2)
#define BLAST_SCORE_MAX	( 2147483647/2)


#if defined(OS_DOS) || defined(OS_MAC)
#define BLAST_SCORE_1MIN (-100)
#define BLAST_SCORE_1MAX ( 100)
#else
#define BLAST_SCORE_1MIN (-10000)
#define BLAST_SCORE_1MAX ( 1000)
#endif
#define BLAST_SCORE_RANGE_MAX	(BLAST_SCORE_1MAX - BLAST_SCORE_1MIN)

/*
For best performance, BLAST_SCOREMAT_INDEX_MAX should have a value
that is (2**N - 1), for some N > 1.  This ensures that each dimension
of a BLAST_ScoreMat array is a power of 2.  BLAST_SCOREMAT_INDEX_MAX
must be >= the maximum letter value in the employed alphabet.
*/
#define BLAST_SCOREMAT_INDEX_MAX	31

typedef BLAST_Score BLAST_ScoreVec[BLAST_SCOREMAT_INDEX_MAX+1];
typedef BLAST_ScoreVec	PNTR BLAST_ScoreMat;
typedef BLAST_ScoreMat	PNTR BLAST_ScoreMatPtr;

typedef BLAST_Letter	BLAST_LetterVec[BLAST_ALPHASIZE_MAX];
typedef BLAST_LetterVec	PNTR BLAST_LetterMat;


typedef struct _blast_scoreblk {
		/* Substitution matrix */
		BLAST_ScoreMat	matrix, _matrix0;

		/* Max. substitution cost for each letter */
		BLAST_Score	maxcost[BLAST_SCOREMAT_INDEX_MAX+1];

		/* Ordered list of letters with highest-to-lowest substitution costs */
		BLAST_LetterMat	_order0, order;

		BLAST_Score	loscore, hiscore;	/* Min. & max. substitution scores */

		BLAST_AlphabetPtr	a1, a2;	/* alphabets for interpretation */
		BLAST_AlphaMapPtr	amp12, amp21;

		CharPtr		name;
		ValNodePtr	comments;
		ValNode		id; /* matrix or scoring system identifier */
		ValNode		user; /* user defined */

	} PNTR BLAST_ScoreBlkPtr; /* No such animal as a BLAST_ScoreBlk */

typedef struct {
		BLAST_Score	score_min, score_max;
		BLAST_Score	obs_min, obs_max;
		double	score_avg;
		double	PNTR _sprob0, PNTR sprob;
	} PNTR BLAST_ScoreFreqPtr; /* No such animal as a BLAST_ScoreFreq */


BLAST_ScoreBlkPtr	BlastScoreBlkNew PROTO((BLAST_AlphabetPtr, BLAST_AlphabetPtr));
void	BlastScoreBlkDestruct PROTO((BLAST_ScoreBlkPtr));
BLAST_Error	BlastScoreBlkMatRead PROTO((BLAST_ScoreBlkPtr, FILE *));
BLAST_Error BlastScoreBlkMatchWeights PROTO((BLAST_ScoreBlkPtr sbp, BLAST_Score reward, BLAST_Score penalty, BLAST_DegenMapPtr dmp1, BLAST_DegenMapPtr dmp2, BLAST_ResFreqPtr rfp1, BLAST_ResFreqPtr rfp2));
BLAST_Error	BlastScoreBlkSort PROTO((BLAST_ScoreBlkPtr));
BLAST_Error	BlastScoreChk PROTO((BLAST_Score lo, BLAST_Score hi));
BLAST_Score	BlastScoreMaxAchievable PROTO((BLAST_ScoreBlkPtr, BLAST_StrPtr, BLAST_Coord start, BLAST_Coord len));

BLAST_ScoreFreqPtr BlastScoreFreqNew PROTO((BLAST_Score score_min, BLAST_Score score_max));
void BlastScoreFreqDestruct PROTO((BLAST_ScoreFreqPtr));
BLAST_Error	BlastScoreFreqCalc PROTO((BLAST_ScoreFreqPtr, BLAST_ScoreBlkPtr, BLAST_ResFreqPtr, BLAST_ResFreqPtr));

/* Datatypes */
#define Score	BLAST_Score
#define ScoreFreqPtr	BLAST_ScoreFreqPtr
#define ScoreBlkPtr	BLAST_ScoreBlkPtr

/* Functions */
#define ScoreBlkNew	BlastScoreBlkNew
#define ScoreBlkDestruct	BlastScoreBlkDestruct
#define ScoreBlkMatRead	BlastScoreBlkMatRead
#define ScoreBlkSort	BlastScoreBlkSort
#define ScoreRangeChk	BlastScoreRangeChk
#define ScoreMaxAchievable	BlastScoreMaxAchievable

#define ScoreFreqNew	BlastScoreFreqNew
#define ScoreFreqDestruct	BlastScoreFreqDestruct
#define ScoreFreqCalc	BlastScoreFreqCalc

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

