#include <iostream>         // cin cout
#include <fstream>          // fájlkezelés
#include <sstream>          // stringstream F1 string darabolás
#include <vector>           // vector adattípusokhoz
#include <string>           // stringekhez stoi
#include <set>              // set adattípusokhoz (halmazok --> utca és tulaj)

using namespace std;

// string szavakra "hasogatása" egy vectorba
vector<string> split(string sor)
{
    stringstream line(sor);         // ez olyasmi, mint az (i/o)fstream, ahol a sor a fájltartalom
    vector<string> split_sor;
    string temp;
    while(line>>temp)
    {
        split_sor.push_back(temp);
    }
    return split_sor;
}

void F1(vector<int> &es, vector<vector<string>> &t)
{
    ifstream fbe;
    fbe.open("utca.txt");

    string sav,sor;             // fájl első sora és a többi sor
    getline(fbe,sav);           // első sor beolvasása ("800 600 100")
    stringstream savok(sav);    // 3 szóra bontáshoz kell ez az előkészítés...

    int szam;
    while(savok>>szam)          // ...itt, és itt már egész számokként (es) kerülnek vectorba
        es.push_back(szam);     // {800, 600, 100}
    // for(auto e:es) cout << e << endl;

    string elvalaszto = " ";    // fájl soraiban a szavakat elválasztó karakter
    vector<string> v;           // ebbe a vectorba kerül a soronkénti 5 szó
    while(getline(fbe,sor))
    {
        v=split(sor);
        t.push_back(v);
    }
    /*
    for(auto i=0;i<t.size();i++)
    {
        for(auto j=0;j<5;j++)
            cout << t[i][j] << " ";
        cout << endl;
    }
    */

    fbe.close();
}

int F2(vector<vector<string>> t)
{
    return t.size();            // a "mátrix" mérete
}

void F3(vector<vector<string>> t)
{
    string adoszam;
    cout << "3. feladat. Egy tulajdonos adószáma: ";   //68396
    cin >> adoszam;
    for(auto i=0;i<t.size();i++)
    {
        if(t[i][0]==adoszam) cout << t[i][1] << " utca " << t[i][2] << endl;
    }
}

int ado(vector<int> ABC, string as, int nm)    // + az előíráshoz képest az ABC vector (800,600,100)
{                                              // as - adósáv pl.: "A", nm - négyzetméter
    int fizet;
    if(as=="A") fizet=ABC[0]*nm;
    if(as=="B") fizet=ABC[1]*nm;
    if(as=="C") fizet=ABC[2]*nm;
    if(fizet<10000) return 0; else return fizet;
}

void F5(vector<int> ABC, vector<vector<string>> t)
{
    int ABC_db[3]={0,0,0};                      // minden adósávnak egy-egy nulla kezdőérték
    int ABC_ado[3]={0,0,0};                     // sávonkénti összegzéshez kezdőértékek
    int nm;                                     // nm- négyzetméter
    for(auto adat:t)                            // t vector "bejárása"
    {
        nm=stoi(adat[4]);                       // stringből int (stoi)
        if(adat[3]=="A")
        {
            ABC_db[0]++;
            ABC_ado[0]+=ado(ABC,"A",nm);
        }
        if(adat[3]=="B")
        {
            ABC_db[1]++;
            ABC_ado[1]+=ado(ABC,"B",nm);
        }
        if(adat[3]=="C")
        {
            ABC_db[2]++;
            ABC_ado[2]+=ado(ABC,"C",nm);
        }
    }
    cout << "5. feladat" << endl;
    string abc[3]={"A","B","C"};                   // csak a kiírás miatt, hogy egy sorral el lehessen intézni
    for(auto i=0;i<3;i++)
    {
        cout <<  abc[i] << " sávba " << ABC_db[i] << " telek esik, az adó " << ABC_ado[i] << " Ft." << endl;
    }
}

void F6(vector<vector<string>> t)
{
    cout << "6. feladat. A több sávba sorolt utcák:" << endl;
    set<string> utca;        // halmaz az utcaneveknek, csak egyedi értékek lehetnek benne, ez az előnye
    for(auto i=0;i<t.size();i++)
    {
        utca.insert(t[i][1]);   // halmaz "feltöltése" - egy utcanév, ugye, csak egyszer lesz benne...
    }
    set<string> savos;          // halmaz az "A" vagy "B" vagy "C" sávoknak
    for(auto u:utca)            // utcanevek "végignézése"
    {
        savos.clear();          // sávok halmaz legyen üres
        for(auto j=0;j<t.size();j++)    // telkek pörgetése
        {
            if(t[j][1]==u)              // adott utca van soron...
            {
                savos.insert(t[j][3]);  // ...akkor az "A" vagy "B" vagy "C" megy a halmazba
            }
        }
        if(savos.size()>1)              // ha egy adott utcánál két vagy több sáv is a halmazba került,...
        {
            cout << u << endl;          // ...akkor azt kiírjuk
        }
    }
}

void F7(vector<int> ABC, vector<vector<string>> t)
{
    set<string> tulaj;                  // halmaz a tulajdonosok adószámának
    for(auto i=0;i<t.size();i++)
    {
        tulaj.insert(t[i][0]);          // halmaz "töltése"
    }
    ofstream fki;
    fki.open("fizetendo.txt");
    int adoFt;
    for(auto tu:tulaj)                  // tulajdonosok, azaz adószámok "bejárása"
    {
        adoFt=0;
        for(auto i=0;i<t.size();i++)    // telkek "böngészése"
        {
            if(t[i][0]==tu)             // ha éppen az adott tulaj jön...
            {
                adoFt+=ado(ABC,t[i][3],stoi(t[i][4]));  // ...akkor számoljuk, összegezzük az adóját
            }
        }
        fki << tu << " " << adoFt << endl;
    }
    fki.close();
}

int main()
{
    setlocale(LC_ALL,"hun");

    vector<int> ABC;                    // adósávok forintjai (800, 600, 100)
    vector<vector<string>> telkek;      // telkek adatai 5 elemű vectorok vectora (listák listája --> Python)

    F1(ABC, telkek);

    // csak, hogy legyen egy nem void-os függvény is
    cout << "2. feladat. A mintában " << F2(telkek) << " telek szerepel." << endl;

    F3(telkek);
    F5(ABC,telkek);
    F6(telkek);
    F7(ABC,telkek);

    return 0;
}
