/*
 For every female aged 2 or older and not radioactive, give birth to a new bunny of the same color
 and place it at the end of the list
 */
void BunnyWorld::giveBirth()
{
    Bunny* tracker = m_first->m_next;
    //find last bunny in list.
    Bunny* findEnd = tracker;
    while (findEnd->m_next != nullptr){
        findEnd = findEnd->m_next;
    }
    //go through whole list
    while (tracker != nullptr){
        if (tracker->getSex() == bny::female && tracker->getAge() >=2 && !tracker->getRadioactive()){
            int color = tracker->getColor();
            Bunny* newBunny = new Bunny(color);
            //put new bunny at end of list
            newBunny->m_next = nullptr;
            findEnd->m_next = newBunny;
            findEnd = newBunny;
            m_population++;
            if (newBunny->getRadioactive()){
                m_radioactivePopulation++;
            }
        }
        tracker = tracker->m_next;
    }
}
//Constructor
BunnyWorld::BunnyWorld():
m_population(0),
m_radioactivePopulation(0),
m_first(new Bunny)
{
    //clears output.txt when world created.
    std::ofstream outputFile("output.txt");
    outputFile.close();
    std::ofstream populationFile("population.txt");
    populationFile.close();
    //Set up an empty first bunny to start the program
    m_first->m_next = nullptr;
    Bunny* tracker = m_first;

    //create first 5 bunnies
    for (int i = 0; i < 5; i++)
    {
        int color = getRandomColor();
        Bunny* newBunny = new Bunny(color);
        newBunny->m_next = nullptr;
        tracker->m_next = newBunny;
        tracker = newBunny;
        m_population++;
        if (newBunny->getRadioactive()){
            m_radioactivePopulation++;
        }
    }
    printBunnies();

}
//goes through list of bunnies and kills those over 10 and not radioactive or over 50 if radioactive
void BunnyWorld::killOldBunnies()
{
    //point tracker to first 'dummy' bunny
    Bunny* tracker = m_first;
    //point next bunny to first 'real' bunny
    Bunny* nextBunny = tracker->m_next;
    /*
     The program keeps bunnies in age order so only goes through the bunnies that are aged
     10 or over to decide whether to kill it or not
    */
    while (nextBunny->getAge() >= 10)
    {
        //if bunny is 50, always dies. If not radioactive, is 10 by the while condition so kill
        if (nextBunny->getAge() == 50 || !nextBunny->getRadioactive()){
            tracker->m_next = nextBunny->m_next;
            killBunny(nextBunny);
        }
        else
            tracker = tracker->m_next;
        
        nextBunny = tracker->m_next;
        
        /*
         if we've reached the end of the list (no bunnies under 10) break out of while loop.
         It's implemented like this because the while loop requires a getAge call which doesn't
         work for the nullptr pointer.
         */
        if (nextBunny==nullptr){
            break;
        }
    }
}
//Check to see if there is a Bunny with age >=2 and not radioactive in the population
bool BunnyWorld::isEligibleMale() const
{
    Bunny* tracker = m_first->m_next;
    while(tracker!=nullptr){
        if (tracker->getAge() >= 2 && tracker->getSex() == bny::male && !tracker->getRadioactive()){
            return true;
        }
        tracker = tracker->m_next;
    }
    return false;
}
/*
 Converts x new bunnies to be radioactive mutant vampire bunnies at randomwhere x is the current number of
 radioactive mutant vampire bunnies.
*/
void BunnyWorld::infectBunnies()
{
    //sets the number of bunnies to infect
    int numberToInfect = m_radioactivePopulation;
    Bunny* tracker = m_first->m_next;
    //if every bunny is radioactive, break out of the while loop
    while (numberToInfect > 0 && m_radioactivePopulation != m_population){
        //if you've reached the end of the list, go back to the start
        if(tracker == nullptr){
            tracker = m_first->m_next;
        }
        /*if the bunny isn't already radioactive, decide whether it should be infected
        at random with a probability equal to radioactivepopulation/totalpopulation
        */
        if (!tracker->getRadioactive() && shouldInfect()){
            tracker->setRadioactive(true);
            m_radioactivePopulation++;
            numberToInfect --;
        }
        tracker = tracker->m_next;
    }
    
}