#include <string>
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <list>

class Student
{

public:
    Student();
    ~Student();

    void setName(const std::string& p_name)     { _name = p_name; }
    void setArrivalTime(const int p_arr_t)      { _arrivalTime = p_arr_t; }

    const std::string& getName() const         { return _name; }
    const int getArrivalTime() const           { return _arrivalTime; }

private:
    std::string _name;
    int _arrivalTime;

};

struct CompareStudByArrivaltime
{
    const bool operator()(const Student* s1, const Student* s2) const;
};


Student::Student()
{}

Student::~Student()
{}

const bool CompareStudByArrivaltime::operator()(const Student* s1, const Student* s2) const
{
    if (s1->getName() == s2->getName())
    {
        return false;
    }
    return (s1->getArrivalTime() < s2->getArrivalTime());
}

typedef std::list<Student> StudentsPool;
typedef std::set<Student*, CompareStudByArrivaltime> Students;
typedef std::map<std::string, Students> SchoolStudentsMap;

SchoolStudentsMap g_school_studs;
StudentsPool g_stud_pool;

Student* getStud(const std::string& n)
{
    for (StudentsPool::iterator itr = g_stud_pool.begin(); itr != g_stud_pool.end(); ++itr)
    {
        if (itr->getName() == n)
        {
            return &(*itr);
        }
    }

    return NULL;
}

void initObj()
{
    /** School 1 Record */
    std::string school_name = "school1";

    char c1[] = { 's', 't', 'u', 'd', '1', '\0' };
    std::string n1(c1);
    //Student* s1 = new Student();
    Student s1;
    s1.setName(n1);
    s1.setArrivalTime(10);
    g_stud_pool.push_back(s1);

    Student* tmp = NULL;

    tmp = getStud("stud1");
    g_school_studs[school_name].insert(tmp);

    char c2[] = { 's', 't', 'u', 'd', '2', '\0' };
    std::string n2(c2);
    Student s2;
    s2.setName(n2);
    s2.setArrivalTime(2);
    g_stud_pool.push_back(s2);

    tmp = getStud("stud2");
    g_school_studs[school_name].insert(tmp);

    char c3[] = { 's', 't', 'u', 'd', '3', '\0' };
    std::string n3(c3);
    Student s3;
    s3.setName(n3);
    s3.setArrivalTime(5);
    g_stud_pool.push_back(s3);

    tmp = getStud("stud3");
    g_school_studs[school_name].insert(tmp);
}

void processObj()
{
    for (SchoolStudentsMap::iterator itr = g_school_studs.begin(); itr != g_school_studs.end(); ++itr)
    {
        Students& studs = itr->second;

        for (Students::iterator sitr = studs.begin(); sitr != studs.end(); ++sitr)
        {
            Student* s = (*sitr);
            std::cerr << "Name: " << s->getName() << ", Arr Time: " << s->getArrivalTime() << std::endl;
        }
    }

}

int main(int argc, const char * argv[])
{

    initObj();
    processObj();

    return 0;
}
