#include <iostream>         // cin, cout
#include <fstream>          // fájlkezelés
#include <ctime>            // véletlenszámok
#include <vector>           // vector adattípushoz  (kvázi lista)
#include <map>              // map adattípushoz (szótár)
#include <set>              // set adattípushoz (halmaz)
#include <algorithm>        // sort

using namespace std;

struct teszt
{
    string k;       // kérdés
    long v;         // válasz
    int p;          // pont
    string t;       // témakör
};

void F1(vector<teszt> &k)           // cím szerinti paraméterátadás
{
    printf("1. feladat - Adatok beolvasása ---------------------------\n");
    ifstream fbe;
    fbe.open("felszam.txt");
    bool kerdes_jon=true;           // figyeljük, hogy kérdés jön-e a fájlban
    string sor=" ", enter;          // a kérdés teljes sorát egyben olvassuk be; sorvégi enterre figyelni kell majd
    teszt temp;                     // ebbe az ideiglenes struktúrába helyezzük el a beolvasott adatokat
    while(sor!="")                  // addig olvassuk a fájlt, amíg üres sort nem olvasunk
    {
        if(kerdes_jon)              // ha kérdés jön, akkor...
        {
            sor="";                 // ezt üresre állítjuk, hogy ha esetleg már nincs mit olvasni, ne legyen benne "szemét"
            getline(fbe,sor);       // teljes sor beolvasása (ez egy kérdés)
            temp.k=sor;             // temp-be bekerül a kérdés
            kerdes_jon=false;       // hamisra "kapcsoljuk", mert majd nem kérdés jön...
        }
        else                        // nem kérdés olvasása
        {
            fbe >> temp.v;          // szóközök, mint szeparálók alapján olvassuk be a három további elemet
            fbe >> temp.p;
            fbe >> temp.t;
            getline(fbe,enter);     // az előző beolvasások ott hagyják a sorvégi entert, ezt el kell "tüntetni"...
            k.push_back(temp);      // mind a 4 elem együtt, mehet a vektorunkba
            kerdes_jon=true;        // és majd ismét kérdés jön (ez megy, amíg van mit olvasni a fájlból...)
        }
    }
    fbe.close();
}

int F2(vector<teszt> k)
{
    printf("\n2. feladat -----------------------------------------------\n");
    return k.size();
}

void F3(vector<teszt> k)
{
    printf("\n3. feladat -----------------------------------------------\n");
    map<int,int> mat;               // "szótár": kulcs és érték is int típusú
    for(int i=1;i<4;i++) mat[i]=0;  // a lehetséges pontszámok a kulcsok: 1, 2, 3. A kezdő érték nulla
    int db=0;                       // matematika témakörben hány kérdés van?
    for(auto elem:k)                // "bejárjuk" a vektorunkat, egyik elemét a másik után...
    {
        if(elem.t=="matematika")    // ha a témakör matek, akkor...
        {
            db++;                   // számlálót növeljük
            mat[elem.p]++;          // a "szótár" adott pontszámhoz tartozó bejegyzését növeljük, darabra számoljuk
        }
    }
    printf("Az adatfájlban %d matematika feladat van.\n", db);
    printf("1 pontot ér %d feladat, 2 pontot ér %d feladat, 3 pontot ér %d feladat.\n", mat[1], mat[2], mat[3]);
}

bool valasz(teszt i1, teszt i2)
{
    return (i1.v < i2.v);   // egy struktúra v eleme < egy másik struktúra v eleme ---> igaz / hamis
}

void F4(vector<teszt> k)
{
    printf("\n4. feladat -----------------------------------------------\n");
    // rendezzük a vektort, de mivel struktúrákból áll, meg kell mondani melyik rész szerint rendezzük
    // ezt a valasz függvény adja meg: a válaszok alapján rendezzük (ugye ez long típusú adatrész)
    sort(k.begin(),k.end(),valasz);
    printf("A válaszok számértéke %d és %d között van.\n", k[0].v, k[k.size()-1].v);

}
void F5(vector<teszt> k)
{
    printf("\n5. feladat -----------------------------------------------\n");
    set<string> temakorok;          // egy halmazba gyűjtjük a temakoroket
    for(auto kerdes:k)
    {
        temakorok.insert(kerdes.t);     // a halmaz csak egyedi elemeket tartalmazhat, ezt használjuk ki...
    }
    printf("Az adatfájlban szereplő témakörök:\n");
    for(auto temakor:temakorok)
        cout << temakor << endl;

}

void F6(vector<teszt> k)
{
    printf("\n6. feladat -----------------------------------------------\n");
    string temakor;
    long valasz;
    cout << "Milyen témakörből szeretne feladatot kapni? ";
    cin >> temakor;
    // random
    srand(time(NULL));
    int i=rand()%(k.size());
    while(k[i].t!=temakor)          // addig generálunk véletlen "indexeket", amíg megfelelő témakörűt nem ad!!!
    {
        i=rand()%(k.size());
    }
    cout << k[i].k << " ";
    cin >> valasz;
    if(valasz==k[i].v)
    {
        cout << "A válasz " << k[i].p << " pontot ér." << endl;
    }
    else
    {
        cout << "A válasz 0 pontot ér." << endl;
        cout << "A helyes válasz: " << k[i].v << endl;
    }
}

void F7(vector<teszt> k)
{
    printf("\n7. feladat - Teszt kiírása fájlba ------------------------\n");
    ofstream fki;
    fki.open("tesztfel.txt");

    int rnd;
    vector<teszt> kivalogat;        // ebbe válogatjuk a 10 különböző kérdést
    set<int> indexek;               // indexeket fogunk össze szedni, 10 db különbözőt!!! Ezért set (halmaz) a típusa!
    srand(time(NULL));              // véletlenszám-generátor inicializálása

    while(indexek.size()<10)        // addig "válogatunk véletlenszerűen, amíg meg nem lesz a 10 különböző indexünk
    {
        rnd=rand()%(k.size());      // véletlen index generálása
        indexek.insert(rnd);        // halmazba helyezés, de ugye a halmazban nincsenek ismétlődő értékek...
    }
    for(auto index:indexek)
    {
        kivalogat.push_back(k[index]);  // a kiválogatott indexű elemeket a kerdesek vektorból a kivalogat
                                        // vektorba helyezzük
    }
    int sum=0;                      // összpontszámhoz kell
    for(auto kerdes:kivalogat)
    {
        fki << kerdes.p << " " << kerdes.v << " " << kerdes.k << endl;
        sum+=kerdes.p;              // összegzés
    }
    fki << "A feladatsorra összesen " << sum << " pont adható." << endl;

    fki.close();
}

int main()
{
    setlocale(LC_ALL,"");
    vector<teszt> kerdesek;
    F1(kerdesek);
    printf("Az adatfájlban %d feladat van.\n",F2(kerdesek));
    F3(kerdesek);
    F4(kerdesek);
    F5(kerdesek);
    F6(kerdesek);
    F7(kerdesek);
    return 0;
}

