#ifndef ADAPTIVEHUFFMAN_HPP
#define ADAPTIVEHUFFMAN_HPP

struct HuffNode;
struct HuffBlocks;

class CAdaptiveHuffman
{
private:
   // Global stuff
   int MaxValue;
   int LogValue;
   char Compressor;
   char UseMarks;
   
   // Stuff for Huffman tree
   HuffNode **Values;
   HuffNode *Root, *Zero;
   int Count;
   HuffNode **Array;

   // Compressor stuff
   char *Buffer;
   int BufferSize; // buffer size in bits!
   int BitPos, MarkedBitPos; // bit-position in buffer
   
   // Decompressor state
   HuffNode *Walk;
   const char *BufP;
   char BufC;
   int State, BitShift;

   void Allocate();   
   void CleanUp();
   
   bool Stuff(int code, int length); // Stuff bits in buffer
      
public:
   enum {
     ValueOutOfBounds = -1,
     BufferFull = -2,
     EndOfFile = -3,
   };

   CAdaptiveHuffman(int max_value);
   ~CAdaptiveHuffman();
   
   void InitCompressor(int buffer_size, char use_marks);
   int AddValue(int v);
   void Mark();
   int GetBits() const;
   const char *GetBuffer() const;
  
   void InitDecompressor(int bits, const char *buffer);
   int GetValue();

   void PrintTree();
   void PrintAncestors();
};

#endif
