#include <iostream>
#include <ctime>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <string>

using namespace std;

struct Date{
    Date():
        month(0),
        day(0),
        mday(0),
        year(0),
        time(0)
    {}
    int month;
    int day;
    int mday;
    int year;
    int time;
};

void _getCurrentDate(Date &date);
int _getTime(string sentence);
int _getYear(string sentence);
int _getMday(string sentence);
int _getDay(string sentence);
int _getMonth(string sentence);
bool _getDayIndex(string a_day, int &index);
bool _getMonthIndex(string aMonth, int &index);
void _changeToLower(string &str);
bool _containsAlpha(string &str);
void _split(string sentence, vector<string>& toSplit);

void getDateFromSentence(string sentence, Date &date);
bool getTense(Date &givenDate);
void processDateless(string sentence);

enum States{CheckYear, CheckMonth, CheckMDay, CheckDay, CheckTime};
#define MAX_INPUT 1000

int main()
{
    Date a_date;
    char str[MAX_INPUT];
    string a_string;

    cout << "Please input the text you want to process" << endl;
    cin.getline(str, MAX_INPUT -1);

    a_string.append(str);
    getDateFromSentence(a_string, a_date);
    if(!getTense(a_date))
        processDateless(a_string);

    return 0;
}

void _getCurrentDate(Date &date)
{
    time_t t = time(0);
    tm *now = localtime(&t);

    date.year = (now->tm_year + 1900);
    date.day = now->tm_wday;
    date.month = now->tm_mon;
    date.mday = now->tm_mday;
    date.time = now->tm_hour;
}

void getDateFromSentence(string sentence, Date &date)
{
    if(_getYear(sentence))
        date.year = (_getYear(sentence));

    date.day = _getDay(sentence);
    date.month = _getMonth(sentence);
    date.mday = _getMday(sentence);
    date.time = _getTime(sentence);
}

bool getTense(Date &givenDate)
{
    States state = CheckYear;
    Date currentDate;
    bool checked = true;

    _getCurrentDate(currentDate);

    switch(state)
    {
    case CheckYear:
        if(givenDate.year)
        {
            if(currentDate.year > givenDate.year)
            {
                cout << "Past" << endl;
                break;
            }
            if(currentDate.year < givenDate.year)
            {
                cout << "Future" << endl;
                break;
            }
        }
    case CheckMonth:
        if(givenDate.month)
        {
            if(currentDate.month > (givenDate.month - 1))
            {
                cout << "Past" << endl;
                break;
            }
            if(currentDate.month < (givenDate.month - 1))
            {
                cout << "Future" << endl;
                break;
            }
        }
    case CheckMDay:
        if(givenDate.mday)
        {
            if(currentDate.mday > givenDate.mday)
            {
                cout << "Past" << endl;
                break;
            }
            if(currentDate.mday < givenDate.mday)
            {
                cout << "Future" << endl;
                break;
            }
        }
    case CheckDay:
        if(givenDate.day)
        {
            if(currentDate.day > (givenDate.day - 1))
            {
                cout << "Past" << endl;
                break;
            }
            if(currentDate.day < (givenDate.day - 1))
            {
                cout << "Future" << endl;
                break;
            }
        }
    case CheckTime:
        if(givenDate.time)
        {
            if(currentDate.time > givenDate.time)
            {
                cout << "Past" << endl;
                break;
            }
            if(currentDate.time < givenDate.time)
            {
                cout << "Future" << endl;
                break;
            }
        }
    default:
        checked = false;
    }

    return checked;
}

#define AUX_VERB "will"
void processDateless(string sentence)
{
    if(sentence.find(AUX_VERB) != string::npos)
        cout << "Future" << endl;
    else
        cout << "Could not determine the tense" << endl;
}

int _getTime(string sentence)
{
    int time = 0;
    string temp;
    vector<string> stringList;

    _split(sentence, stringList);

    for(unsigned int i = 0; i < stringList.size(); i++)
    {
        temp = stringList[i];
        time = atoi(temp.c_str());
        if(time)
        {
            if(temp.find("am") != string::npos)
                return time;
            if(temp.find("pm") != string::npos)
                return (time + 12);
        }
    }

    return 0;
}

void _split(string sentence, vector<string> &toSplit)
{
    stringstream stream(sentence);
    string temp;

    while(stream)
    {
        stream >> temp;
        toSplit.push_back(temp);
        temp.clear();
    }
}

int _getMday(string sentence)
{
    int mday = 0;
    vector<string> stringList;
    string temp;

    _split(sentence, stringList);

    for(unsigned int i = 0; i < stringList.size(); i++)
    {
        temp = stringList[i];
        mday = atoi(temp.c_str());

        if(mday)
        {
            if(temp.find("th") != string::npos)
                return mday;
        }
    }

    return 0;
}

int _getMonth(string sentence)
{
    int month = 0;
    string temp;
    vector<string> stringList;

    _split(sentence, stringList);

    for(unsigned int i =0; i< stringList.size(); i++)
    {
        temp = stringList[i];
        if(_getMonthIndex(temp, month))
            return (month + 1);
    }

    return 0;
}

#define MONTH_NUM 12
bool _getMonthIndex(string aMonth, int &index)
{

    string months[MONTH_NUM] = {"january", "february", "march", "april", "may", "june", "july", "august", "september",
                         "october", "november", "december"};

    _changeToLower(aMonth);
    for(int i = 0; i < MONTH_NUM; i++)
    {
        if(aMonth == months[i])
        {
            index = i;
            return true;
        }
    }
    return false;
}

int _getYear(string sentence)
{
    int year = 0;
    vector<string> stringList;

    _split(sentence, stringList);

    for(unsigned int i = 0; i< stringList.size(); i++)
    {
        istringstream stream(stringList[i]);
        stream >> year;

        if(year)
        {
            if(!_containsAlpha(stringList[i]))
                return year;
        }
    }

    return 0;
}

int _getDay(string sentence)
{
    int day = 0;
    vector<string> stringList;

    _split(sentence, stringList);

    for(unsigned int i =0; i< stringList.size(); i++)
    {
        if(_getDayIndex(stringList[i], day))
            return (day + 1);
    }

    return 0;
}

#define DAY_SIZE 7
bool _getDayIndex(string a_day, int &index)
{
    string days[DAY_SIZE] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};

    _changeToLower(a_day);
    for(int i = 0; i < DAY_SIZE; i++)
    {
        if(a_day == days[i])
        {
            index = i;
            return true;
        }
    }

    return false;
}

void _changeToLower(string& str)
{
    string temp;
    for(unsigned int i = 0; i < str.size(); i++)
    {
        if(::isupper(str.at(i)))
              temp.append(sizeof(char), ::tolower(str.at(i)));
              else
              temp.append(sizeof(char), str.at(i));

    }
    str.clear();
    str = temp;
}

bool _containsAlpha(string &str)
{
    for(unsigned int i = 0; i< str.size(); i++)
    {
        if(::isalpha(str.at(i)))
            return true;
    }
    return false;
}
