#include <stdlib.h>
#include <stdio.h>

#include "bit_out.h"
#include "main.h"

int get_bits_for_counter(int counter)
{
 if (counter < 8)
   return 3;
 if (counter < 16)
   return 4;
 if (counter < 32)
   return 5;
 if (counter < 64)
   return 6;
 if (counter < 128)
   return 7;
 if (counter < 256)
   return 8;
 if (counter < 512)
   return 9;
 if (counter < 1024)
   return 10;
 if (counter < 2048)
   return 11;
 if (counter < 4096)
   return 12;
 if (counter < 8192)
   return 13;
 if (counter < 16384)
   return 14;
 if (counter < 32768)
   return 15;
 if (counter < 65536)
   return 16;
 return -1;
}

long get_RLE_code(int counter)
{
 long ret = 0;
 int bits_for_counter = get_bits_for_counter(counter);
 int i;
 int ander = 1;
 for (i=0; i<bits_for_counter-2; i++)
 {
  ret<<=1;
  ret++;
 }
 ret<<=1;

 for (i=0; i<bits_for_counter; i++)
 {
  ret<<=1;
  if (counter&(ander))
   ret++;
  ander<<=1;
 }
 return ret;
}

static unsigned char current_out;
static unsigned char current_out_bit;
static unsigned char current_out_bit_counter;
static FILE *dbOutFile = NULL;
static FILE *binOutFile = NULL;

FILE* get_dbOutFile(void)
{
 return dbOutFile;
}

FILE* get_binOutFile(void)
{
 return binOutFile;
}

void deinit_bit_out(void)
{
 if (dbOutFile != NULL)
  fclose(dbOutFile);
 if (binOutFile != NULL)
  fclose(binOutFile);
 dbOutFile = NULL;
 binOutFile = NULL;
}

void init_bit_out(FILE *outFile, FILE *outFile2)
{
 dbOutFile = outFile;
 binOutFile = outFile2;
 current_out = 0;
 current_out_bit = 0;
 current_out_bit_counter = 0;
}

int byte_out_counter = 0;

void byte_out(unsigned char byte)
{
 byte_out_counter = 0;
 if (dbOutFile)
 {
  if (COUT_PUT==1)
  {
   fprintf(dbOutFile," .byte 0H%02X\n", byte);
  }
  else
  {
   fprintf(dbOutFile," DB $%02X\n", byte);
  }
 }
 if (binOutFile)
 {
  fwrite(((unsigned char *)(&byte)),1,1,binOutFile);
 }
 current_out_bit_counter+=8;
 current_out_bit=0;
 current_out=0;
}

void bit_out(int abit)
{
// printf(" \n current_bit_counter $%02X \n", current_out_bit);
 current_out<<=1;
 current_out += ( (abit != 0) ?1:0);
 current_out_bit++;
 current_out_bit_counter++;
// printf(" current_out $%02X \n", current_out);
 if (current_out_bit == 8)
 {
  if (dbOutFile)
  {
   if (byte_out_counter == 0)
   {
    if (COUT_PUT==1)
    {
     fprintf(dbOutFile," .byte 0H%02X", current_out);
    }
    else
    {
     fprintf(dbOutFile," DB $%02X", current_out);
    }
   }
   else
   {
    if (COUT_PUT==1)
    {
     fprintf(dbOutFile,", 0H%02X", current_out);
    }
    else
    {
     fprintf(dbOutFile,", $%02X", current_out);
    }
   }
   byte_out_counter++;
   if (byte_out_counter == 10)
   {
    byte_out_counter=0;
    fprintf(dbOutFile," \n");
   }
  }
  if (binOutFile)
  {
   fwrite(((unsigned char *)(&current_out)),1,1,binOutFile);
  }
  current_out_bit=0;
  current_out=0;
 }
}

void bit_flush(void)
{
 while (current_out_bit!=0)
 {
  bit_out(0);
 }
 fprintf(dbOutFile," ; flushed\n", current_out);
 byte_out_counter = 0;
}

void bits_out_bit_code(int bit_len, int code)
{
 int cb = bit_len;
 while (cb)
 {
   cb--;
   bit_out(code&(1<<cb));
//printf("BIT_OUT(%02X) \n",(code&(1<<cb)));
 }
}


