#ifndef LIBS_H
#define LIBS_H

#include <cstdlib>
#include <iostream>
#include "library/maxsearch.hpp"
#include "library/summation.hpp"
#include "library/enumerator.hpp"
#include "library/seqinfileenumerator.hpp"

struct Hallgato
{
    std::string neptun;
    int jegy;
    double atlag;
    friend std::istream& operator>>(std::istream &f, Hallgato &df)
    {
        f >>df.neptun>>df.jegy;
        return f;
    }
    friend std::ostream& operator<<(std::ostream &s, Hallgato &akt)
    {
        s<<akt.neptun<<" "<<akt.atlag;
        return s;
    }
};

class Osszegzes : public Summation<Hallgato,double>
{
private:
    const std::string neptun;
    int db;
    double osszeg;

protected:
    void init()
    {
        db=0;
        osszeg=0;
    }
    void first() {}
    bool WhileCond(const Hallgato &e) const
    {
        return e.neptun==neptun;
    }
    void add(const Hallgato &e)
    {
        osszeg+=e.jegy;
        db+=1;
        *_result=osszeg/db;
        //3ICE: Ez a kód hibás. Proof:
        std::cout<<"3ICE - nep:"<<e.neptun<<" jegy:"<<e.jegy<<" sum:"<<osszeg<<" db:"<<db<<" _result:"<<*_result<<std::endl;
    }

public:
    Osszegzes(std::string neptun): Summation<Hallgato,double> (), neptun(neptun) {}
};

class Maxker : public MaxSearch<Hallgato,double>
{
protected:
    double func(const Hallgato& e) const
    {
        return e.atlag;
    }
};

class Felsorolo: public Enumerator<Hallgato>
{
protected:
    SeqInFileEnumerator<Hallgato> *f;
    Hallgato cur;
    bool _end;
public:
    Felsorolo(const std::string &filename)
    {
        try
        {
            f=new SeqInFileEnumerator<Hallgato>(filename);
        }
        catch(SeqInFileEnumerator<Hallgato>::Exceptions ex )
        {
            std::cout<<"Nincs meg a file!\n";
            exit(1);
        }
    }
    void first()
    {
        f->first();
        next();
    }
    void next();
    bool end() const
    {
        return _end;
    }
    Hallgato current() const
    {
        return cur;
    }
};
#endif // LIBS_H
