#ifndef _EMBEDHASH_H_
#define _EMBEDHASH_H_

/**
 *    WHAM - high-throughput sequence aligner
 *    Copyright (C) 2011  WHAM Group, University of Wisconsin
 *
 *    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 3 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, see <http://www.gnu.org/licenses/>.
 */

/*	$Id: hash.h 152 2012-07-22 10:52:53Z yinan $ */

#include <stdlib.h>
#include <stdio.h>
#include "lib.h"
#include "sequence.h"
#include "hitset.h"

#define COMPRESS_TABLE_SIZE	2147483648LLU

class EmbedHashTable {
private:
  bool compressedTable;

  int length; /* the length of query sequence (characters) */
  int lenSeq; /* the length of query sequence (bits) */

  int nMismatch; /* the number of allowed errors */

  uint32 numBucket; /* the number of buckets */
  uint32 numEntry; /* the number of entries */
  uint32 numOverflowEntry;/* the number of overflow entries (stored in the overflow list) */
  uint32 numCollision; /* the number of buckets with collisions */
  uint32 numEmpty; /* the number of empty buckets */

  uint32 * buckets; /* bucket array */
  uint32 * overflowPool; /* overflow pool array */

  CompactSequence * sequence; /* the reference sequence */
  unsigned char * emptyBits; /* the bitmap for empty buckets (only used in building phase) */
  unsigned char * collisionBits; /* the bitmap for collision buckets (only used in building phase) */
  unsigned char * overflowBits;

  uint32 maxScan;
  int nMaxError;
  int nMaxGap;
  int maxQual;

//	const static uint32 nHistogram = 4;
//	uint32 histogram[nHistogram];

public:
  EmbedHashTable();
  ~EmbedHashTable();
  void init(CompactSequence * seq, int len, unsigned int nBucket,
      int numMismatch, int nPartition);
  int preProcessInit();
  int preProcessEnd();
  int buildInit();

  void preProcessInsert(int64 * key); /*inline*/
  void insert(int64 * key, unsigned int offset); /*inline*/

  unsigned int lookup(int64 * orgkey, int64 * key, int keyOffset, char * quals,
      strand s, int rid, HitSet * hits, bool noGap = false);

  int sortList();
  int check(int num);
  int save(FILE * file);
  int load(FILE * file, CompactSequence * seq);
  int remove();
  unsigned int nextPrime(unsigned int num);

  void setScanThreshold(double r);

  int getMaxScan() {
    return maxScan;
  }

  void setErrorModel(int maxerr, int maxgap, int maxqual) {
    nMaxError = maxerr;
    nMaxGap = maxgap;
    maxQual = maxqual;
  }
};

#endif

