/**********************************************************************
 * displayLevel - level order traversal and display
 ***********************************************************************/
void displayLevel(GNode* &aHead)
{
    const int MAX = 150;
    GNode* queue[MAX];
    GNode* temp = aHead;
    int front = 0;
    int back = 0;
    int saveBack = 1;
    int generation = 0;
    bool showGeneration = true;

    while (temp->getINum() != "I1")
        temp = temp->getNext();

    queue[back++] = temp;
    cout << "The Ancestors of " << temp->getFName() << " " << temp->getLName() << ":" << endl;
    while (front != back)
    {
        temp = queue[front];
        if (front == saveBack)
        {
            generation++;
            saveBack = back;
            if (generation == 1)
                cout << "Parents:" << endl;
            else if (generation == 2)
                cout << "Grandparents:" << endl;
            else if (generation == 3)
                cout << "Great Grandparents:" << endl;
            else if (generation == 4)
                cout << "2nd Great Grandparents:" << endl;
            else if (generation == 5)
                cout << "3rd Great Grandparents:" << endl;
            else if (generation == 6)
                cout << "4th Great Grandparents:" << endl;
            else if (generation == 7)
                cout << "5th Great Grandparents:" << endl;
        }

        front = (front + 1) % MAX;

        if (temp != NULL)
        {
            if (front != 1)
            {
                cout << "        ";
                if (temp->getFName() != "")
                    cout << temp->getFName();
                if (temp->getLName() != "" && temp->getFName() != "")
                    cout << " " << temp->getLName();
                else
                    cout << temp->getLName();

                if (temp->getDay() != "" || temp->getMonth() != ""
                        || temp->getYear() != "")
                    cout<< ", b. ";
                if (temp->getDay() != "")
                    cout << temp->getDay() << " ";
                if (temp->getMonth() != "")
                    cout << temp->getMonth() << " ";
                if (temp->getYear() != "")
                    cout << temp->getYear();
                cout << endl;
            }

            queue[back] = temp->getFather();
            back = (back + 1) % MAX;
            queue[back] = temp->getMother();
            back = (back + 1) % MAX;
        }
    }
}
/**********************************************************************
 * parseFile -
 ***********************************************************************/
void parseFile(ifstream &inFile, GNode* &aHead)
{
    GNode* ptr = NULL; // traversal pointer

    string temp1; // assign every word in file to temp1
    string temp2; // helper string in parse logic
    int i = 0;
    while (true)
    {
        getline (inFile, temp1);

        if (temp1 == "1 DIV Y")
            break;

        temp2 = temp1.substr(0, 4); // create substring

        //We've reached a new node. Insert previous Node, then start new Node.
        if (temp2 == "0 @I")
        {
            insert(aHead, ptr);
            temp2.clear();
            temp1.erase(0, 3);
            //create INum string
            while (temp1[0] != '@')
            {
                temp2 += temp1[0];
                temp1.erase(0,1);
            }

            ptr = new GNode;
            ptr->setINum(temp2);
        }
        //parse and store first Name
        else if (temp2 == "2 GI")
        {
            temp1.erase(0,7);
            ptr->setFName(temp1);
        }
        //parse and store last Name
        else if (temp2 == "2 SU")
        {
            temp1.erase(0, 7);
            ptr->setLName(temp1);
        }
        //parse and store Birth Date
        else if (temp2 == "1 BI")
        {
            getline(inFile, temp1);
            if (temp1.find("DATE") != std::string::npos) // make sure date exists
            {
                temp1.erase(0,7);
                temp2.clear();
                if (temp1.length() != 0)
                {
                    for (int i = 0; i < temp1.length(); i++)
                    {
                        if (isalpha(temp1[i]))
                        {
                            temp2 += temp1[i];
                            temp1.erase(i, 1);
                            i--;
                        }
                    }
                    ptr->setMonth(temp2);
                    temp2.erase();
                    if (temp1[0] == ' ')
                        temp1.erase(0, 1);

                    while (temp1.length() != 0 && (isdigit(temp1[0])
                                                   || temp1[0] == '/'))
                    {
                        temp2 += temp1[0];
                        temp1.erase(0, 1);
                    }
                    if (temp2.length() > 2)
                        ptr->setYear(temp2);
                    else
                        ptr->setDay(temp2);

                    if (temp1.length() != 0)
                    {
                        temp1.erase(0, 2);
                        temp2.clear();

                        while (temp1.length() != 0)
                        {
                            temp2 += temp1[0];
                            temp1.erase(0, 1);
                        }
                        ptr->setYear(temp2);
                    }
                }
            }
        }
    }
    insert(aHead, ptr);

    // Start Algorithm to Build Binary Tree

    string fatherINum;
    string motherINum;
    string childINum;;

    ptr = aHead; // reset traversal pointer. Use to traverse children
    GNode* ptr2 = ptr; // another traversal pointer. Use to traverse to parents.
    while (true)
    {
        getline(inFile, temp1);

        if (temp1 == "1 CALN 0567673")
            break;

        temp2 = temp1.substr(0, 4); // create substring

        if (temp2 == "1 HU") // check for father
        {
            temp1.erase(0,8);
            temp2.clear();
            while (temp1[0] != '@')
            {
                temp2 += temp1[0];
                temp1.erase(0,1);
            }
            fatherINum = temp2;
        }
        else if (temp2 == "1 WI") // check for mother
        {
            temp1.erase(0,8);
            temp2.clear();
            while (temp1[0] != '@')
            {
                temp2 += temp1[0];
                temp1.erase(0,1);
            }
            motherINum = temp2;
        }
        else if (temp2 == "1 CH") // node whose mother/father need to be set
        {
            temp1.erase(0,8);
            temp2.clear();
            while (temp1[0] != '@')
            {
                temp2 += temp1[0];
                temp1.erase(0,1);
            }
            childINum = temp2;

            ptr = aHead;
            ptr2 = aHead;
            while (childINum != ptr->getINum())
                ptr = ptr->getNext();

            while (fatherINum != "" && fatherINum != ptr2->getINum())
                ptr2 = ptr2->getNext();

            if (fatherINum != "")
                ptr->setFather(ptr2);

            ptr2 = aHead;
            while (motherINum != "" && motherINum != ptr2->getINum())
                ptr2 = ptr2->getNext();

            if (motherINum != "")
                ptr->setMother(ptr2);

            fatherINum.clear();
            motherINum.clear();
        }
    }
}