/* $Id: b0b6b76755d282fb6850b3f657123a9a03b6c4ff $ */
#ifndef STAGE1HR_INCLUDED
#define STAGE1HR_INCLUDED

typedef struct Stage1_T *Stage1_T;

#include "bool.h"
#include "univcoord.h"
#include "types.h"
#include "mode.h"
#include "pass.h"

#include "reader.h"
#include "genomicpos.h"
#include "indexdb.h"
#include "shortread.h"
#include "iit-read-univ.h"

#include "genome.h"
#include "transcriptome.h"
#include "genomebits.h"

#include "mergeinfo.h"
#include "splice.h"
#include "indel.h"

#include "trdiagpool.h"
#include "univdiagpool.h"
#include "uintlistpool.h"
#include "intlistpool.h"
#include "univcoord.h"
#include "listpool.h"
#include "pathpool.h"
#include "trpathpool.h"
#include "hitlistpool.h"


#define T Stage1_T
struct T {
  /* Results */
#if 0
  List_T subopt_sense_trpaths;
  List_T subopt_antisense_trpaths;
#endif
  List_T sense_trpaths;
  List_T antisense_trpaths;

  List_T unsolved_sense_paths_gplus;
  List_T unsolved_sense_paths_gminus;
  List_T unsolved_antisense_paths_gplus;
  List_T unsolved_antisense_paths_gminus;

  List_T unextended_sense_paths_gplus;
  List_T unextended_sense_paths_gminus;
  List_T unextended_antisense_paths_gplus;
  List_T unextended_antisense_paths_gminus;

  List_T extended_sense_paths_gplus;
  List_T extended_sense_paths_gminus;
  List_T extended_antisense_paths_gplus;
  List_T extended_antisense_paths_gminus;

  List_T sense_paths_gplus;
  List_T sense_paths_gminus;
  List_T antisense_paths_gplus;
  List_T antisense_paths_gminus;


  Reader_T reader;
  Reader_T tr_reader;

  /* Initialized by Stage1_fill_all_positions */
  bool *validp;			/* Need only one, since we allocate
				   forward_oligos[querypos] and
				   revcomp_oligos[querypos] at same
				   time */
  bool *tr_validp;

  bool all_oligos_gen_filledp;
  bool all_positions_gen_filledp;

  Oligospace_T *forward_oligos;
  Oligospace_T *revcomp_oligos;
  Oligospace_T *tr_forward_oligos;
  Oligospace_T *tr_revcomp_oligos;

  /* Need plus_retrievedp and minus_retrievedp because
     Extension_search and Tr_extension_search can retrieve either plus
     or minus */
  bool *retrievedp_allocated;
  bool *plus_retrievedp;	       /* points to above[index1interval-1] */
  bool *minus_retrievedp;	       /* points to above[index1interval-1] */

  bool *tr_retrievedp_allocated;
  bool *tr_plus_retrievedp;
  bool *tr_minus_retrievedp;

#ifdef LARGE_GENOMES
  unsigned char **positions_high_allocated;
  unsigned char **plus_positions_high; /* points to above[index1interval-1] */
  unsigned char **minus_positions_high; /* points to above[index1interval-1] */
#endif

  /* plus positions are the alignments to the plus genome strand of
     the forward oligo, and also the alignments to the minus genome
     strand of the revcomp oligo */
  UINT4 **positions_allocated;
  UINT4 **plus_positions; /* points to above[index1interval-1] */
  UINT4 **minus_positions; /* points to above[index1interval-1] */

  UINT4 **tr_positions_allocated;
  UINT4 **tr_plus_positions;
  UINT4 **tr_minus_positions;

  int *npositions_allocated;
  int *plus_npositions;		/* points to above[index1interval-1] */
  int *minus_npositions;	/* points to above[index1interval-1] */

  int *tr_npositions_allocated;
  int *tr_plus_npositions;
  int *tr_minus_npositions;
  
  /* Memory allocated for mismatch_positions in Substring_new (Genome_mismatches_{left,right}),
     and for Distant_rna_solve */
  /* int *mismatch_positions_alloc; */
  int *positions_alloc;

  /* Memory allocated for indelinfo */
  Indelinfo_T indelinfo;

  /* Memory allocated for spliceinfo in kmer-search.c and
     path-solve.c, used by Splice_resolve_sense and
     Splice_resolve_antisense */
  Spliceinfo_T spliceinfo;

  Mergeinfo_uint4_T mergeinfo_tr;
#ifdef LARGE_GENOMES
  Mergeinfo_uint8_T mergeinfo;
#else
  Mergeinfo_uint4_T mergeinfo;
#endif

  /* Memory allocated for Segment_identify in segment-search.c, and
     Merge_diagonals in kmer-search.c (which needs four sets of
     arrays) */
#ifdef LARGE_GENOMES
  unsigned char **stream_high_alloc, **gplus_stream_high_array_5, **gminus_stream_high_array_5, **gplus_stream_high_array_3, **gminus_stream_high_array_3;
  UINT4 **stream_low_alloc, **gplus_stream_low_array_5, **gminus_stream_low_array_5, **gplus_stream_low_array_3, **gminus_stream_low_array_3;
#endif

  int streamspace_max_alloc;	/* Entries in streamspace_alloc */
  Univcoord_T *streamspace_alloc;
  Univcoord_T **streamptr_alloc, **gplus_stream_array_5, **gminus_stream_array_5, **gplus_stream_array_3, **gminus_stream_array_3;
  Trcoord_T **tplus_stream_array, **tminus_stream_array;

  int *streamsize_alloc, *tplus_streamsize_array, *tminus_streamsize_array,
    *gplus_streamsize_array_5, *gminus_streamsize_array_5, *gplus_streamsize_array_3, *gminus_streamsize_array_3;
  int *querypos_diagterm_alloc, *tplus_diagterm_array, *tminus_diagterm_array,
    *gplus_diagterm_array_5, *gminus_diagterm_array_5, *gplus_diagterm_array_3, *gminus_diagterm_array_3;


  /* Pointers needed for Kmer_search_exact, which needs positions only
     for the ends, and then re-used by Kmer_search_approx.  Simplifies
     the issues relating to mod 3 calculations, since the genome is
     indexed every 3 bp.  */
#ifdef LARGE_GENOMES
  unsigned char *plus_positions_high_end5[6];
  unsigned char *minus_positions_high_end5[6];
  unsigned char *plus_positions_high_end3[6];
  unsigned char *minus_positions_high_end3[6];
#endif
  UINT4 *plus_positions_end5[6];
  UINT4 *minus_positions_end5[6];
  UINT4 *plus_positions_end3[6];
  UINT4 *minus_positions_end3[6];

  int plus_npositions_end5[6];
  int minus_npositions_end5[6];
  int plus_npositions_end3[6];
  int minus_npositions_end3[6];

  int plus_diagterms_end5[6];
  int minus_diagterms_end5[6];
  int plus_diagterms_end3[6];
  int minus_diagterms_end3[6];


  /* Returned from Extension_search and used for distant splicing */
  List_T queryfwd_plus_set;
  List_T queryfwd_minus_set;
  List_T queryrev_plus_set;
  List_T queryrev_minus_set;

  /* Returned from Tr_extension_search */
  List_T tr_queryfwd_plus_set;
  List_T tr_queryfwd_minus_set;
  List_T tr_queryrev_plus_set;
  List_T tr_queryrev_minus_set;

#if 0
  /* Intermediate calculations for transcriptome */
  /* Returned from Transcriptome_search_ends and used for Transcriptome_search_complete */
  Trcoord_T *tplus_positions_5, *tminus_positions_5, *tplus_positions_3, *tminus_positions_3;
  int n_tplus_positions_5, n_tminus_positions_5, n_tplus_positions_3, n_tminus_positions_3;
  int tplus_diagterm_5, tminus_diagterm_5, tplus_diagterm_3, tminus_diagterm_3;
#endif
};


extern void
Stage1_list_paths (T this);

extern void
Stage1_free (T *old, Trdiagpool_T trdiagpool, Univdiagpool_T univdiagpool,
	     Intlistpool_T intlistpool, Uintlistpool_T uintlistpool,
	     Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
	     Pathpool_T pathpool, Trpathpool_T trpathpool,
	     Transcriptpool_T transcriptpool, Hitlistpool_T hitlistpool, bool free_paths_p);

extern T
Stage1_new (char *queryuc_ptr, int querylength);

extern void
Stage1_dump (T this, int querylength);
extern void
Stage1_dump_tr (T this, int querylength);

extern void
Stage1_init_end_gen (T this, int querylength, int genestrand);
extern void
Stage1_init_end_oligos_tr (T this, int querylength);
extern void
Stage1_init_end_positions_tr (T this, int querylength);

extern void
Stage1_fill_all_oligos_gen (T this, int querylength, int genestrand);
extern void
Stage1_fill_all_oligos_tr (T this, int querylength);

extern void
Stage1_fill_all_positions_gen (T this, int querylength, int genestrand);


extern void
Stage1_solve_unsolved_paths (int *found_score, T this, 
			     int max_insertionlen, int max_deletionlen,
			     Compress_T query_compress_fwd, Compress_T query_compress_rev,
			     Shortread_T queryseq, int querylength, Knownsplicing_T knownsplicing,
			     Uintlistpool_T uintlistpool, Intlistpool_T intlistpool,
			     Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
			     Pathpool_T pathpool, Transcriptpool_T transcriptpool, Hitlistpool_T hitlistpool);

extern void
Stage1_consolidate_paths (T this, Shortread_T queryseq,
			  Compress_T query_compress_fwd, Compress_T query_compress_rev,
			  Uintlistpool_T uintlistpool, Intlistpool_T intlistpool,
			  Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
			  Pathpool_T pathpool, Transcriptpool_T transcriptpool,
			  Hitlistpool_T hitlistpool);

extern void
Stage1hr_setup (Indexdb_T indexdb_fwd_in, Indexdb_T indexdb_rev_in, Indexdb_T indexdb_tr_in,
		int index1part_in, int index1interval_in, int index1part_tr_in, int index1interval_tr_in, 
		Chrpos_T shortsplicedist_novelend_in, Transcriptome_T transcriptome_in);

#undef T
#endif

