#ifndef _ABSTRACT_H_
#define _ABSTRACT_H_

#include "bit_code.h"
#include "phrase.h"

#define VALID_BYTE 1
#define VALID_PHRASE 2
#define VALID_RLE_BYTE 3
#define VALID_RLE_PHRASE 4
#define VALID_ENCODED_BYTE 5
#define VALID_ENCODED_PHRASE 6
#define VALID_ENCODED_RLE_BYTE 7
#define VALID_ENCODED_RLE_PHRASE 8

#define INVALID 0
#define VALID 1
#define ENCODED 2
#define RLE 4
#define RLE_ENCODED 6

struct abstract_data
{
  int type; // types, see above
  int bit_length_ENCODED; // bit length of current code
  int ENCODED_code; // current bit code for this 'data'
  int bit_length_RLE; // bit length of current code
  long RLE_code; // current bit code for this 'data'
  int count; // repeated how many times?
  int length_in_abstract_data_elements_of_single_element;
  int original_data;
  int phrase_used; // if phrase is used, here is a pointer to it
};

struct abstract_buffer
{
  abstract_data *data;
  int len;
  phrase *phrases;              // phrases used in this abstract
  int phrase_count;             // number of phrases used...
  int *codes_used_array;
  int *map;
  _code_ *code;
  int different_codes_used;
  int kind;
};

int get_bits_used_from_abstract(abstract_buffer *buffer);
int get_bits_used_from_abstract_complete(abstract_buffer *buffer);
void abstract_RLE(abstract_buffer *buffer);
void abstract_Huffman(abstract_buffer *buffer);
void abstract_Shannon(abstract_buffer *buffer);
abstract_buffer *abstract_clone(abstract_buffer *abuffer);
abstract_buffer *build_abstract(unsigned char *buffer, int len);
void delete_abstract(abstract_buffer *buffer);
void abstract_out(abstract_buffer *abuffer);
phrase abstract_get_best_phrase_used_more_than_once(abstract_buffer *abuffer, int phrase_len);
void abstract_apply_phrase(abstract_buffer *abuffer, phrase aphrase);
phrase abstract_get_best_single_phrase(abstract_buffer *abuffer);
void abstract_search_insert_phrases(abstract_buffer *abuffer);
void abstract_search_insert_phrases_optimal(abstract_buffer *abuffer);
void print_abstract(abstract_buffer *abuffer);

#endif