/*
 * Written by Bastien Chevreux (BaCh)
 *
 * Copyright (C) 1997-2000 by the German Cancer Research Center (Deutsches
 *   Krebsforschungszentrum, DKFZ Heidelberg) and Bastien Chevreux
 * Copyright (C) 2000 and later by Bastien Chevreux
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */


/*
 * Dynamic programming routines
 *
 * Given two sequences, this object computes the dynamic programming
 *  matrix for them. The default values make the score to an edit
 *  distance without terminal gap penalties.
 *
 * One will probably not want to use it as standalone! For the time
 *  being, it is inherited by the class Align.
 *
 * Can do:
 *   - compute dyn. matrix with and without terminal gap penalties
 *   - does not care about upper-lower case sequences; - aliases N
 *   - once acquired, the sequences are kept locally. So the source
 *      sequences do not need to be kept.
 *   - instance reusable, giving it new sequences will trash the
 *      old values.
 * TODO:
 *   - see .C
 */

#ifndef _dynamic_h_
#define _dynamic_h_

#include <stdinc/defines.H>

#include <ctype.h>
#include <limits.h>
#include <strings.h>            // C-strings

#include <iostream>

#include <algorithm>                        // STL max template

#include <errorhandling/errorhandling.H>
#include <mira/parameters.H>
#include <util/dptools.H>

#define DYN_MATSIZE 128
#define DYN_BANDLIMIT 1<<30

class Dynamic
{
public:

  static uint64 DYN_alloccount;

  int32 DYN_maxscore;          // Max score within simmatrix
  int32 DYN_lastrc_maxscore;   /* Max score within last row and column
				 of simmatrix */


protected:
  MIRAParameters * DYN_miraparams;

  uint8    DYN_valid;

  static int32 DYN_match_matrix[DYN_MATSIZE][DYN_MATSIZE];
  static int16 DYN_matvalid;

  char   * DYN_sequence1;         // sequence 1
  char   * DYN_sequence2;         // sequence 2

  int32    DYN_s1size;            // size of seq1 array
  int32    DYN_s2size;            // size of seq2 array

  int32    DYN_len_seq1;          //  and its length are the ROWS
  int32    DYN_len_seq2;          //  and its length are the COLUMNS

  int32    DYN_knowngaps;         /* number of gaps that need to be additionally
				     accounted for as these were seen in the
				     sequences */

  int32  * DYN_simmatrix;        /* Similarity matrix, always
				    (ROWS+1)*(COLUMNS+1) big */
  int32    DYN_smsize;           // size of the matrix;

  // for bug tracking in coutWhatWasGiven()
  bool   DYN_calcwithoffset;
  int32  DYN_eoffset;

private:
  void foolCompiler();

  int32 sequenceCopy(char * to, const char * from, uint32 len);
  void zeroVars();
  void matinit(char a, char b, int32 score);
  void init();

public:
  Dynamic(MIRAParameters * params);
  Dynamic(MIRAParameters * params,
	  const char * seq1,
	  uint32 len1,
	  const char * seq2,
	  uint32 len2,
	  bool calcwithoffset=true,
	  int32 expectedoffset=0);
  virtual ~Dynamic();

  void discard();
  void setSequences(const char * seq1,
		    uint32 len1,
		    const char * seq2,
		    uint32 len2,
		    bool calcwithoffset=true,
		    int32 expectedoffset=0);
  void dump();
  void computeSimMatrix();
  void computeBSimMatrix();
  void computeBSimMatrix(int32 eoffset);

  void coutWhatWasGiven();
};


#endif
