/**********************************************************************
 * displayList - displays a linked list, starting with the head argument.
 ***********************************************************************/
void displayList(GNode* &aHead)
{
    GNode* ptr = aHead;

    while (ptr != NULL)
    {
        if (ptr->getFName() != "")
            cout << ptr->getFName();
        if (ptr->getLName() != "" && ptr->getFName() != "")
            cout << " " << ptr->getLName();
        else
            cout << ptr->getLName();

        if (ptr->getDay() != "" || ptr->getMonth() != "" || ptr->getYear() != "")
            cout<< ", b. ";
        if (ptr->getDay() != "")
            cout << ptr->getDay() << " ";
        if (ptr->getMonth() != "")
            cout << ptr->getMonth() << " ";
        if (ptr->getYear() != "")
            cout << ptr->getYear();
        cout << endl;
        ptr = ptr->getNext();
    }
}
/**********************************************************************
 * 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;
        }
    }
}
/**********************************************************************
 * insert - a sorted insertion
 ***********************************************************************/
void insert(GNode* &listHead, GNode* &aPtr)
{
    //aPtr not rdy to be inserted. Occurs on first individual in parseFile()
    if(aPtr == NULL)
        return;
    //first insertion
    if(listHead == NULL)
    {
        listHead = aPtr;
        return;
    }

    string tempLName = aPtr->getLName();
    string ptrLName;

    for (int i = 0; i < tempLName.length(); i++)
        ptrLName += toupper(tempLName[i]);

    tempLName = listHead->getLName();
    string headLName;
    for (int i = 0; i < tempLName.length(); i++)
        headLName += toupper(tempLName[i]);

    // head insert
    if (ptrLName < headLName)
    {
        aPtr->setNext(listHead);
        listHead = aPtr;
        return;
    }
    else if (ptrLName == headLName && aPtr->getFName() < listHead->getFName())
    {
        aPtr->setNext(listHead);
        listHead = aPtr;
        return;
    }

    GNode* p = listHead;
    GNode* c = listHead->getNext();
    string cLName;

    //traverse, comparing last names,then first Name, then date
    while (c != NULL)
    {
        tempLName = c->getLName();
        cLName.clear();
        for (int i = 0; i < tempLName.length(); i++)
            cLName += toupper(tempLName[i]);

        if (ptrLName > cLName)
        {
            p = c;
            c = c->getNext();
        }
        else if (ptrLName == cLName && aPtr->getFName() > c->getFName())
        {
            p = c;
            c = c->getNext();
        }
        else if (ptrLName == cLName && aPtr->getFName() == c->getFName()
                 && aPtr->getYear() > c->getYear())
        {
            p = c;
            c = c->getNext();
        }
        else
            break;
    }
    p->setNext(aPtr);
    aPtr->setNext(c);
}