#include "Rozdelenie.h"

Rozdelenie::Rozdelenie(int stav, int abeceda)
{
    nstav = stav;
    nabeceda = abeceda;
    int max = (1 << nstav) + 1;
    pocty = new int[max];
    for(int i=0;i<max;i++)
        pocty[i] = 0;
}

Rozdelenie::~Rozdelenie()
{
    delete [] pocty;
}

void Rozdelenie::GenerujVsetky(bool NKAminimal, bool cNKA, bool DKAminimal)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    do
    {
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if((!NKAminimal || nka->is_minimal(dka)) && (!cNKA || nka->have_cycle()))
            pocty[dka->getsize()]++;
        delete dka;
    } while(nka->generateNextNKA() == 0);
    delete nka;
}

void Rozdelenie::GenerujNahodne(bool NKAminimal, bool DKAminimal, int ntestov, double pravdepodobnost_prechodu, double pravdepodobnost_akcstavu)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(pravdepodobnost_prechodu,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if(!NKAminimal || nka->is_minimal(dka))
            pocty[dka->getsize()]++;
        delete dka;
    }
    delete nka;
}

void Rozdelenie::GenerujNahodne(bool NKAminimal, bool DKAminimal, int ntestov, double pravdepodobnost_prechodu, double pravdepodobnost_prechodu_pre0, double pravdepodobnost_akcstavu)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(pravdepodobnost_prechodu,pravdepodobnost_prechodu_pre0,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if(!NKAminimal || nka->is_minimal(dka))
            pocty[dka->getsize()]++;
        delete dka;
    }
    delete nka;
}

void Rozdelenie::GenerujNahodne(bool NKAminimal, bool DKAminimal, int ntestov, int ohranicenie_delty, double pravdepodobnost_akcstavu)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(ohranicenie_delty,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if(!NKAminimal || nka->is_minimal(dka))
            pocty[dka->getsize()]++;
        delete dka;
    }
    delete nka;
}

void Rozdelenie::HladajVsetky(bool NKAminimal, bool DKAminimal, int hlad_stavov)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    do
    {
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if((!NKAminimal || nka->is_minimal(dka)) && (dka->getsize() == hlad_stavov))
            nka->vypis();
        delete dka;
    } while(nka->generateNextNKA() == 0);
    delete nka;
}

void Rozdelenie::HladajNahodne(bool NKAminimal, bool DKAminimal, int ntestov, double pravdepodobnost_prechodu, double pravdepodobnost_akcstavu, int hlad_stavov)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(pravdepodobnost_prechodu,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if((!NKAminimal || nka->is_minimal(dka)) && (dka->getsize() == hlad_stavov))
            nka->vypis();
        delete dka;
    }
    delete nka;
}

void Rozdelenie::HladajNahodne(bool NKAminimal, bool DKAminimal, int ntestov, double pravdepodobnost_prechodu, double pravdepodobnost_prechodu_pre0, double pravdepodobnost_akcstavu, int hlad_stavov)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(pravdepodobnost_prechodu,pravdepodobnost_prechodu_pre0,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if((!NKAminimal || nka->is_minimal(dka)) && (dka->getsize() == hlad_stavov))
            nka->vypis();
        delete dka;
    }
    delete nka;
}

void Rozdelenie::HladajNahodne(bool NKAminimal, bool DKAminimal, int ntestov, int ohranicenie_delty, double pravdepodobnost_akcstavu, int hlad_stavov)
{
    NKA * nka = new NKA(nstav,nabeceda);
    DKA * dka;
    for(int i = 0;i<ntestov;i++)
    {
        nka->generateNextNKA(ohranicenie_delty,pravdepodobnost_akcstavu);
        if(DKAminimal) dka = nka->convert2minDKA();
        else dka = nka->convert2DKA();
        if((!NKAminimal || nka->is_minimal(dka)) && (dka->getsize() == hlad_stavov))
            nka->vypis();
        delete dka;
    }
    delete nka;
}

void Rozdelenie::vypis()
{
    for(int i = 0; i < ((1 << nstav) + 1);i++)
        std::cout << i << ' ' << pocty[i] << std::endl;
}
