#include <iostream>
#include <cstring>
#include "semigroup.hpp"

void init_full_N(Semigroup &m){
  epi8 block ={1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8};
  for(auto i=0; i<NBLOCKS; i++){
    m.blocks[i] = block;
    block = block + 8;
  }
  m.genus = 0;
  m.conductor = 1;
  m.min = 1;
  m.left=1;
  m.left_primitive=0;
  m.e=1;
  m.wilf=0;
}

void init(Semigroup& S,char c,char g,char m,char* d){
  S.conductor=c;
  S.genus=g;
  S.min=m;
  memcpy((void*)S.decs,(void*)d,(3*MAX_GENUS+1));
  S.left=0;
  S.left_primitive=0;
  S.e=0;
  for(ind_t i=0;i<S.conductor;++i){
    if(d[i]>0){
      ++S.left;
      if(d[i]==1){
	++S.e;
	++S.left_primitive;
      }
    }
  }
  for(ind_t i=S.conductor;i<S.conductor+S.min;++i){
    if(d[i]==1){
      ++S.e;
    }
  }
  S.wilf=S.left*S.e-S.conductor;
}

void init_ordinary(Semigroup &O,int m){
  O.decs[0]=1;
  for(auto i=1;i<2*m;++i){
    O.decs[i]=i/m;
  }
  for(auto i=0;i<SIZE-2*m;++i){
    O.decs[2*m+i]=2+i/2;
  }
			     
  O.genus = m-1;
  O.conductor = m;
  O.min = m;
  O.left=1;
  O.left_primitive=0;
  O.e=m;
  O.wilf=0;
}

void print_Semigroup(const Semigroup &m)
{
  unsigned int i;
  std::cout<<"min = "<<m.min<<", cond = "<<m.conductor<<", genus = "<<m.genus<<", decs = ";
  for (i=0; i<SIZE; i++) std::cout<<((int) m.decs[i])<<' ';
  std::cout<<std::endl;
}

void print_Semigroup_gen(const Semigroup &m)
{
  unsigned int i;
  std::cout<<"m = "<<m.min<<", c = "<<m.conductor<<", g = "<<m.genus<<" w = "<<m.wilf<<" ";
  std::cout<<"< ";
  for (i=1; i<SIZE; i++){
    if(m.decs[i]==1){
      std::cout<<i<<' ';
    }
  }
  std::cout<<'>'<<std::endl;
}

#include <cmath>


void output(const Semigroup& m,fstream& f){
  int q=ceil(float(m.conductor)/float(m.min));
  int rho=q*m.min-m.conductor;
  f<<"c = "<<m.conductor<<", g = "<<m.genus<<", r = "<<rho<<", w = "<<m.wilf<<" : ["<<m.min;
  for (auto i=m.min+1; i<SIZE; i++){
    if(m.decs[i]==1){
      f<<','<<i;
    }
  }
  f<<']'<<endl;
}

void record(const Semigroup& S,fstream& f){
  char c,g,m;
  c=S.conductor;
  g=S.genus;
  m=S.min;
  f.write(&c,1);
  f.write(&g,1);
  f.write(&m,1);
  f.write((char*)(&S.decs),3*MAX_GENUS+1);
}

void print_epi8(epi8 bl)
{
  unsigned int i;
  for (i=0; i<16; i++) std::cout<<((uint8_t*)&bl)[i]<<' ';
  std::cout<<std::endl;
}
