#include <iostream>
#include <string>
#include "Rozdelenie.h"

int stavov = 0;
int abeceda = 0;
bool NKAminimal = false;
bool DKAminimal = false;
bool cNKA = false;
bool all = false;
int ntestov = 0;
double pravdepodobnost_prechodu = -1;
double pravdepodobnost_prechodu_pre0 = -1;
double pravdepodobnost_akcstavu = -1;
int ohranicenie_delty =-1;
bool vypis = false;
int hladaneNKA = -1;

int main(int argc,char *argv[])
{
    int argument = 1;
    while (argument < argc)
    {
        std::string arg = argv[argument];
        if (arg == "-h")
        {
            std::cout << "ARGUMENTY:" << std::endl;
            std::cout << "  -n [cislo]    pocet stavov" << std::endl;
            std::cout << "  -a [cislo]    velkost abecedy" << std::endl;
            std::cout << "  -minNKA    take only minimal NKA" << std::endl;
            std::cout << "  -cNKA    take only NKA with cycle" << std::endl;
            std::cout << "  -minDKA    transform DKA to minimal DKA" << std::endl;
            std::cout << "  -pp    pravdepodobnost, ze zo stavu do druheho stavu existuje prechod" << std::endl;
            std::cout << "  -pmax [cislo]   ohranicuje velkost prechodovej funkcie: |delta(stav,pismeno)| < cislo" << std::endl;
            std::cout << "  -pc    pravdepodobnost, ze existuje prechod na pismeno 0 okrem cyklu cez vsetky stavy" << std::endl;
            std::cout << "  -pa    pravdepodobnost, ze stav je akceptacny" << std::endl;
            std::cout << "  -v      vypis parametrov vypoctov" << std::endl;
            std::cout << "  -k [all,cislo]    kolko roznych NKA pocita: vsetky/cislo" << std::endl;
            std::cout << "  -r      randomize" << std::endl;
            std::cout << "  -l [cislo] hlada NKA,ktoreho velkost minimalneho automatu = cislo" << std::endl;
            std::cout << "VYSTUP:" << std::endl;
            std::cout << "  Pre kazde cislo i z (n,2^n) pocet DKA, prisluchajuce n-stavovemu NKA." << std::endl;
            std::cout << "  s parametrom -l vypise hladane NKA" << std::endl;
            exit(0);
        }
        else if (arg == "-n")
        {
            argument++;
            stavov = atoi(argv[argument]);
        }
        else if (arg == "-a")
        {
            argument++;
            abeceda = atoi(argv[argument]);
        }
        else if (arg == "-minNKA")
        {
            NKAminimal = true;
        }
        else if (arg == "-cNKA")
        {
            cNKA = true;
        }
        else if (arg == "-minDKA")
        {
            DKAminimal = true;
        }
        else if (arg == "-r")
        {
            srand(time(NULL));
        }
        else if (arg == "-pp")
        {
            argument++;
            pravdepodobnost_prechodu = atof(argv[argument]);
        }
        else if (arg == "-pmax")
        {
            argument++;
            arg = argv[argument];
            ohranicenie_delty = atoi(argv[argument]);
        }
        else if (arg == "-pc")
        {
            argument++;
            pravdepodobnost_prechodu_pre0 = atof(argv[argument]);
        }
        else if (arg == "-pa")
        {
            argument++;
            pravdepodobnost_akcstavu = atof(argv[argument]);
        }
        else if (arg == "-l")
        {
            argument++;
            hladaneNKA = atof(argv[argument]);
        }
        else if (arg == "-v")
        {
            vypis = true;
        }
        else if (arg == "-k")
        {
            argument++;
            arg = argv[argument];
            if (arg == "all") all = true;
            else ntestov = atoi(argv[argument]);
        }
        else
        {
            std::cout << "Neznamy argument!" << std::endl;

        }
        argument++;
    }
    if (vypis)
    {
        std::cout << std::boolalpha;
        std::cout << "#  pocet stavov: " << stavov << std::endl;
        std::cout << "#  velkost abecedy: " << abeceda << std::endl;
        std::cout << "#  take only minimal NKA: " << NKAminimal << std::endl;
        std::cout << "#  take only NKA with cycle: " << cNKA << std::endl;
        std::cout << "#  transform DKA to minimal DKA: " << DKAminimal << std::endl;
        std::cout << "#  pravdepodobnost, ze zo stavu do druheho stavu existuje prechod: " << pravdepodobnost_prechodu << std::endl;
        std::cout << "#  pravdepodobnost, ze zo stavu do druheho stavu existuje prechod na pismeno 0 (okrem cyklu cez vsetky stavy): " << pravdepodobnost_prechodu_pre0 << std::endl;
        std::cout << "#  pravdepodobnost, ze stav je akceptacny: " << pravdepodobnost_akcstavu << std::endl;
        std::cout << "#  ohranicenie prechodovej funkcie: " << ohranicenie_delty << std::endl;
        std::cout << "#  hladane NKA: " << hladaneNKA << std::endl;
        if (all) std::cout << "# Pocet NKA: all" << std::endl;
        else std::cout << "# Pocet NKA: " << ntestov << std::endl;
        std::cout << std::noboolalpha;
    }
    Rozdelenie * vypocet = new Rozdelenie(stavov,abeceda);
    if (hladaneNKA == -1)
    {
        if (all) vypocet->GenerujVsetky(NKAminimal, cNKA,DKAminimal);
        else
        {
            if (ohranicenie_delty != -1)
                vypocet->GenerujNahodne(NKAminimal,DKAminimal, ntestov, ohranicenie_delty, pravdepodobnost_akcstavu);
            else if(pravdepodobnost_prechodu_pre0 != -1)
                vypocet->GenerujNahodne(NKAminimal,DKAminimal, ntestov, pravdepodobnost_prechodu, pravdepodobnost_prechodu_pre0, pravdepodobnost_akcstavu);
            else vypocet->GenerujNahodne(NKAminimal,DKAminimal, ntestov, pravdepodobnost_prechodu, pravdepodobnost_akcstavu);
        }
        vypocet->vypis();
    }
    else
    {
        if (all) vypocet->HladajVsetky(NKAminimal,DKAminimal,hladaneNKA);
        else
        {
            if (ohranicenie_delty != -1)
                vypocet->HladajNahodne(NKAminimal,DKAminimal, ntestov, ohranicenie_delty, pravdepodobnost_akcstavu,hladaneNKA);
            else if(pravdepodobnost_prechodu_pre0 != -1)
                vypocet->HladajNahodne(NKAminimal,DKAminimal, ntestov, pravdepodobnost_prechodu, pravdepodobnost_prechodu_pre0, pravdepodobnost_akcstavu,hladaneNKA);
            else vypocet->HladajNahodne(NKAminimal,DKAminimal, ntestov, pravdepodobnost_prechodu, pravdepodobnost_akcstavu,hladaneNKA);
        }
    }
    delete vypocet;
    return 0;
}
