#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <map>
#include <fstream>
#include<sstream>
#include<iostream>

#include "hlavicka.h"

/* Use random() and srandom() if you have them (Unix-like systems do). */
#define RANDOM random
#define SRANDOM srandom
/* Otherwise, use rand() and srand() from the standard C library. */
/* rand() is not very random, but will do for the demonstration here. */
/* #define RANDOM rand */
/* #define SRANDOM srand */

/* Do not change these to rand and srand, they are declared in stdlib.h. */
/* If the system declares these in a header, these two lines can be removed. */
long random ();
void srandom (unsigned);

//#define NUMLOOPS 100
#define ADAPT 1
//#define FILE1 "ff"
//#define FILE2 "bar"
//#define MASK1 ((0x1<<3) - 1)
//#define MASK2 ((0x1<<5) - 1)
#define NSYM1 (4)
//#define NSYM2 (MASK2 + 1)

int main (int argc,char** argv)
//prvy param je Model, 
//druhy kodovana sekvencia
//treti je nozov suboru s komprimovanymi datami
{
  
 /* string file;
  istringstream stm;
  stm.str(argv[3]);
  stm >> file;*/
  const char* FILE1(argv[3]);
 // FILE1= new char[file.length()];
 // for(int i=0;i<file.length;i++) FILE1[i]=file[i];
  ac_encoder ace1;
//  ac_encoder ace2;
  ac_decoder acd1;
//  ac_decoder acd2;
  ac_model acm1;
//  ac_model acm2;
  int sym, i;
  

  ac_encoder_init (&ace1, FILE1);
 // ac_encoder_init (&ace2, FILE2);
 
 // ac_model_init (&acm2, NSYM2, NULL, ADAPT);
// std::cout << argv[1] << std::endl;
 std::ifstream subor(argv[2], std::ifstream::in);
 ifstream* subor2=new ifstream(argv[1], ifstream::in);
  
  Model M(subor2); //nacita model zo suboru kt. meno dostane ako parameter  
  subor2->close();
     cerr << "OK1" << endl;
   ac_model_init (&acm1, NSYM1, NULL, ADAPT, &M);
cerr << "asdfa"<< endl;
 // SRANDOM (0);
 char c;
 std::map<char,int> abeceda;
 abeceda.insert(std::make_pair('a',0));
 abeceda.insert(std::make_pair('c',1));
 abeceda.insert(std::make_pair('g',2));
 abeceda.insert(std::make_pair('t',3));
 abeceda.insert(std::make_pair('A',0));
 abeceda.insert(std::make_pair('C',1));
 abeceda.insert(std::make_pair('G',2));
 abeceda.insert(std::make_pair('T',3));
 std::map<int,char> debeceda;
 debeceda.insert(std::make_pair(0,'a'));
 debeceda.insert(std::make_pair(1,'c'));
 debeceda.insert(std::make_pair(2,'g'));
 debeceda.insert(std::make_pair(3,'t'));
 //int ano=0;
  while((subor >> c)/*&&(ano<2)*/) {
    std::cerr << c << " ";
    sym = abeceda[c];
   // cerr << "ahoj: " << endl;
    ac_encode_symbol (&ace1, &acm1, sym, &M);
   // ano++;
  }
  subor.close();
  cerr << "fajn" << endl;

  ac_encoder_done (&ace1);
  
  ac_model_done (&acm1);
  

//  printf ("bits for encoder 1: %d\n", (int) ac_encoder_bits (&ace1));

  ac_decoder_init (&acd1, FILE1);
  //ac_decoder_init (&acd2, FILE2);
  ac_model_init (&acm1, NSYM1, NULL, ADAPT, &M);
 // ac_model_init (&acm2, NSYM2, NULL, ADAPT);

  //SRANDOM (0);
  for (;;)  {
    sym = ac_decode_symbol (&acd1, &acm1, &M);
std::cout << debeceda[sym];    
   /* if (sym != (RANDOM() & MASK1))  {
      printf ("decoding error\n");
      exit (1);
    }
    sym = ac_decode_symbol (&acd1, &acm2);
    if (sym != (RANDOM() & MASK2))  {
      printf ("decoding error\n");
      exit (1);
    }
std::cout << sym;   
    sym = ac_decode_symbol (&acd2, &acm1);
    if (sym != (RANDOM() & MASK1))  {
      printf ("decoding error\n");
      exit (1);
    }
std::cout << sym;   
    sym = ac_decode_symbol (&acd2, &acm2);
    if (sym != (RANDOM() & MASK2))  {
      printf ("decoding error\n");
      exit (1);
    }*/
  }

  ac_decoder_done (&acd1);
  //ac_decoder_done (&acd2);
  ac_model_done (&acm1);
 // ac_model_done (&acm2);
  return 0;
}
