#include <iostream>             // cin és cout parancsok
#include <fstream>              // fájlkezelés
#include <map>                  // szótár adattípushoz
#include <set>                  // halmaz adattípushoz
#include <vector>               // vector adattípushoz
#include <cstring>              // strcpy parancs

using namespace std;

struct mozgas                   // vendégek mozgása
{
    int reszleg;                // adott részleg
    int ki_be;                  // ki- vagy bemenetel
    int o, p, mp;               // mikor: óra perc másodperc
};

void F1(map<int,vector<mozgas>> &m)
{
    ifstream fbe;
    fbe.open("furdoadat.txt");
    mozgas temp;                        // ebbe olvassuk be a fájl sorait ideiglenesen
    int id;                             // ez lesz a szótárunk kulcsa: a vendég azonosítója
    while(fbe>>id&&fbe>>temp.reszleg&&fbe>>temp.ki_be&&fbe>>temp.o&&fbe>>temp.p&&fbe>>temp.mp)
    {
        m[id].push_back(temp);          // szótár feltöltése: a szótár "bejegyzése" egy vector, az adott vendég mozgásaiból áll
    }
    fbe.close();
    /*
    for(auto elem:m)
    {
        cout << elem.first << ":" << endl;
        for(auto e:elem.second)
        {
            cout << e.reszleg << " " << e.ki_be << " " << e.o << " " << e.p << " " << e.mp << endl;
        }
        cout << "----------------------" << endl;
    }
    */
}

void F2_3(map<int,vector<mozgas>> m)
{
    cout << "2. feladat" << endl;
    int min_ora=24,min_perc,min_mp, max_ora=0,max_perc,max_mp;      // maximum- és minimumkeresés lesz
    mozgas temp;
    int db=0;               // számláló ---> 3. feladathoz
    for(auto elem:m)        // szótár "kiolvasása", bejárása
    {
        if(elem.second.size()==4) db++;         // ha egy szótárbejegyzés csak 4 elemű, akkor csak egy részlegen járt a vendég
        temp=elem.second[0];                    // a szótárbejegyzés vektorának első eleme tartalmazza az öltözőből kilépést a fürdőbe
        if(temp.o<min_ora)                      // minimum óra keresése
        {
            min_ora=temp.o;
            min_perc=temp.p;
            min_mp=temp.mp;
        }
        if(temp.o>max_ora)                      // maximum óra keresése
        {
            max_ora=temp.o;
            max_perc=temp.p;
            max_mp=temp.mp;
        }
    }
    printf("Az első vendég %d:%d:%d-kor lépett ki az öltözőből.\n",min_ora,min_perc,min_mp);
    printf("Az utolsó vendég %d:%d:%d-kor lépett ki az öltözőből.\n",max_ora,max_perc,max_mp);
    cout << "3. feladat" << endl;
    printf("A fürdőben %d vendég járt csak egy részlegen.\n",db);
}

int szamol(mozgas k, mozgas v)
{
    return (v.o*3600+v.p*60+v.mp)-(k.o*3600+k.p*60+k.mp);       // két óra:perc:mp közötti különbség másodpercekben
}
void F4(map<int,vector<mozgas>> m)
{
    cout << "4. feladat" << endl;
    int vendeg,ido,max_ido=0;               // itt is lesz egy maximumkeresés
    mozgas kezd,vege;
    for(auto elem:m)                        // szótár "kiolvasása", bejárása
    {
        kezd=elem.second.front();           // minden vendég (kulcs) esetén az első vektorbeli elem
        vege=elem.second.back();            // és az utolsó vektorbeli elem kell
        ido=szamol(kezd,vege);              // másodpercekben a két időpont különbsége (szamol fv.)
        if(ido>max_ido)                     // maximumvizsgálat
        {
            vendeg=elem.first;              // szótár kulcsa (first) és
            max_ido=ido;                    // az eltöltött idő "memorizálása"
        }
    }
    cout << "A legtöbb időt eltöltő vendég:" << endl;
    printf("%d. vendég %d:%d:%d\n",vendeg,max_ido/3600,max_ido%3600/60,max_ido%3600%60);       // másodperc vissza óra:perc:mp-be
}

int stat_sum(map<int,int> s,int k,int v)
{
    // 6-8, 9-15 és 16-19 intervallumok összesítése a stat szótár alapján
    int sum=0;
    for(int key=k;key<v;key++) sum+=s[key];     // megfelelő intervallumok összesítése a szótár alapján
    return sum;
}

void F5(map<int,vector<mozgas>> m)
{
    cout << "5. feladat" << endl;
    map<int,int> stat;                  // újabb szótár: 6-19 közötti kulcsokkal,
    for(int key=6;key<20;key++)         // és nulla kezdőértékekkel
    {
        stat[key]=0;
    }
    for(auto elem:m)                    // szótár "kiolvasása", bejárása
    {
        stat[elem.second.front().o]++;  // stat szótár megfelelő kulcsú elemének növelése
    }
    printf("6-9 óra között %d vendég\n",stat_sum(stat,6,9));
    printf("9-16 óra között %d vendég\n",stat_sum(stat,9,16));
    printf("16-20 óra között %d vendég\n",stat_sum(stat,16,20));
}

void F6(map<int,vector<mozgas>> m)
{
    cout << "6. feladat" << endl;
    // Fájlkezelés egy újabb "technikája", csak hogy használhassuk az fprintf parancsot is!
    FILE *fki;
    fki=fopen("szauna.txt","w");
    int ido;
    mozgas kezd,vege;
    for(auto elem:m)        // szótár "kiolvasása", bejárása
    {
        ido=0;              // szaunában (2) eltöltött ideje egy adott vendégnek, ha járt ott
        for(int i=0;i<elem.second.size()-1;i++)     // -1, mert i és i+1 indexeket nézünk...
        {
            if(elem.second[i].reszleg==2&&elem.second[i].ki_be==0)  // ha szauna és éppen bement oda...
            {
                kezd=elem.second[i];                                // ... ebben az időben és
                vege=elem.second[i+1];                              // ekkor jött onnan ki
                ido+=szamol(kezd,vege);                             // a 4. feladatban már használt szamol fv.
            }
        }
        if(ido>0)
        {
            // printf("%d %d:%d:%d\n",elem.first,ido/3600,ido%3600/60,ido%3600%60);         // másodpercek vissza ó:p:mp-be
            fprintf(fki,"%d %d:%d:%d\n",elem.first,ido/3600,ido%3600/60,ido%3600%60);       // fprintf fájlbaírás
        }
    }
    fclose(fki);
}

void F7(map<int,vector<mozgas>> m)
{
    cout << "7. feladat" << endl;
    // részlegek: 1,2,3,4
    map<int,int> reszlegek={{1,0},{2,0},{3,0},{4,0}};       // részlegek látogatottsági összegzése egy újabb szótárba
    map<int,string> nev={{1,"Uszoda"},{2,"Szaunák"},{3,"Gyógyvizes medencék"},{4,"Strand"}};    // részlegek megnevezése szótárban
    // Ha az adott részleget valaki többször felkereste, akkor is csak egy esetnek számít, ezért kell az alábbi szótár is!
    map<int,bool> megnemszamoltam={{1,true},{2,true},{3,true},{4,true}};    // Még nem számoltam az adott részleg meglátogatását
    for(auto elem:m)                // szótár "kiolvasása", bejárása
    {
        for(auto e:elem.second)     // az adott "kulcshoz", vendéghez tartozó vektor bejárása
        {
            if(megnemszamoltam[e.reszleg])  // megnemszamoltam szótár kulcsa maga a részleg (1,2,3,4), ha igaz akkor
            {
                reszlegek[e.reszleg]++;     // számolunk vele (reszlegek szótár kulcsa is maga a részleg (1,2,3,4)
                megnemszamoltam[e.reszleg]=false;       // megfelelő kulcsú részt hamisra állítjuk
            }
        }
        megnemszamoltam={{1,true},{2,true},{3,true},{4,true}};      // ha egy vendéggel végeztünk, mindent alaphelyzetbe állítunk
    }
    char str[20];                   // printf miatt kell
    for(int key=1;key<5;key++)
    {
        strcpy(str, nev[key].c_str());              // string másolása char tömbbe
        printf("%s: %d\n",str,reszlegek[key]);      // %s csak char tömbökkel működik
    }
    // VAGY - SZÓTÁR ÉS HALMAZZAL KOMBINÁCIÓVAL OLDHATJUK MEG
    cout << "------------------ SZÓTÁR ÉS HALMAZ KOMBÓ -------------------" << endl;
    map<int,set<int>> reszlegek2;
    for(auto elem:m)                // szótár "kiolvasása", bejárása
    {
        for(auto e:elem.second)     // az adott "kulcshoz", vendéghez tartozó vektor bejárása
        {
            reszlegek2[e.reszleg].insert(elem.first);
        }
    }
    for(int key=1;key<5;key++)
    {
        strcpy(str, nev[key].c_str());                      // string másolása char tömbbe
        printf("%s: %d\n",str,reszlegek2[key].size());      // %s csak char tömbökkel működik
    }
}

int main()
{
    setlocale(LC_ALL,"");
    map<int,vector<mozgas>> mozgasok;
    F1(mozgasok);
    F2_3(mozgasok);
    F4(mozgasok);
    F5(mozgasok);
    F6(mozgasok);
    F7(mozgasok);
    return 0;
}
