#include <eutils/emain.h>
#include <eutils/efile.h>

#define IKMERSIZE 8ul
#define IKMERBITS (IKMERSIZE*2ul)
#define IKMERMAX (1ul<<IKMERBITS)
#define IKMERMASK (IKMERMAX-1ul)

void writeSeqIdent(const estr& file)
{
  unsigned char seqident_match[IKMERMAX];

  for (uint32_t i=0; i<IKMERMAX; ++i){
    for (uint32_t j=0; j<IKMERMAX; ++j){
      seqident_match[i^j]=0u;
      uint32_t ti=i; uint32_t tj=j;
      unsigned char firstmiss=IKMERSIZE;
      for (int k=0; k<IKMERSIZE; ++k,tj>>=2u,ti>>=2u){
        if ((0x03u&ti)==(0x03u&tj))
          ++seqident_match[i^j];
        else if (firstmiss==IKMERSIZE) firstmiss=k;
      }
      seqident_match[i^j]|=(firstmiss<<4u);
    }
  }
  efile f(file,"w");
  for (uint32_t i=0; i<IKMERMAX; ++i)
    f.write(seqident_match[i]);
  f.close();
}

/*
void writeATGCCount(const estr& file)
{
  uint32_t seqatgc_count[1u<<16u];

  uint32_t ti;
  uint32_t a=0u,t=0u,g=0u,c=0u;
  for (uint32_t i=0; i<(1u<<16u); ++i){
    a=0u; t=0u; g=0u; c=0u;
    ti=i;
    for (int k=0; k<8u; ++k,ti>>=2u,a>>=1u,t>>=1u,g>>=1u,c>>=1u){
      switch (0x03u&ti) {
        case 0x0u: a|=0x80u; break;
        case 0x1u: t|=0x80u; break;
        case 0x2u: g|=0x80u; break;
        case 0x3u: c|=0x80u; break;
      }
    }
    seqatgc_count[i]=(a<<24u)|(t<<16u)|(g<<8u)|c;
  }
  uint64_t seqatgc_conv[1u<<8u];
  uint64_t r;
  for (uint32_t i=0; i<(1u<<8u); ++i){
    ti=i;
    r=0u;
    for (int k=0; k<8u; ++k,ti>>=1u,r>>=8u){
      r|=(ti&0x1u?0x01000000u:0u);
    }
    seqatgc_conv[i]=r;
  }

  efile f(file,"w");
  for (uint32_t i=0; i<(1u<<16u); ++i)
    f.write(seqatgc_count[i]);
  for (uint32_t i=0; i<(1u<<8u); ++i)
    f.write(seqatgc_conv[i]);
  f.close();
}
*/

int emain()
{
  eparseArgs();
  writeSeqIdent("seqident.lt");
  return(0);
}

