#include "group_index.h"


/* Generates a group index:
 * Contains global min max for the value.
 * Stores direct access to begin/end iterator of each
 * idividual index for this key / secies.
 */
group_index::group_index(landscape &myMap, species * pSpe, string key)
{
    id = key;
    unsigned int nCells = myMap.max_size();
    indexMap.clear();

    // A //  Gather individual indexes from map
    cell * currCell = NULL;

    cellNumber = nCells;

    population * currPop = NULL;

    //Iterate on cells to gather all individual index pointers
    vector<bool> isEmpty =  myMap.isPopEmptyInSpe(pSpe);
    for(unsigned int pos = 0; pos < nCells; pos++)
    {
        if (!isEmpty[pos])
        {
            currCell = myMap.get_cell(pos);
            if(currCell == NULL) fail("group_index::group_index, pCell == NULL");
            currPop = currCell->get_pop(pSpe);
            if(currPop == NULL) fail("group_index::group_index, pPop == NULL");
            indexMap[pos] = currPop->get_index(key);
        }
    }

    if (indexMap.size() > 0)
    {
        // B // Determines global min max
        //I globMax = index.front()->get_min(); //Any actual value will do  SEGFAULT WHEN POP IS EMPTY
        bool isMax = false;
        for (auto p: indexMap)
        {
            if (p.second != 0)
            {
                globMax = p.second->get_min(); //Any actual value will do SEGFAULT WHEN POP IS EMPTY
                isMax = true;
                break;
            }
        }
        if (!isMax)
        {
            cout << "global max null since no pop, set 0 as max" << endl;
        }
        globMin = globMax; //Any actual value will do
        double locMin, locMax;

        for (auto pII: indexMap)
        {
            // Get min max over all individual indexes
            locMin = pII.second->get_min();
            locMax = pII.second->get_max();
            if(locMin < globMin) globMin = locMin;
            if(locMax > globMax) globMax = locMax;
        }
    }
    else
    {
        cout << "indexMap empty :/" << endl;
        globMin = 0;
        globMax = 0;
    }
}


group_index::~group_index()
{
    //dtor
}


/* Counts number of individuals for each pop in the range of tolerance
 *
 */
vector<double> group_index::count_ind_range(double min, double max)
{
    vector<double> rv(cellNumber, 0.0);

    for(auto i: indexMap)
    {
        rv[i.first] = ( i.second->get_upper_bound(max) - i.second->get_lower_bound(min) );
    }

    return rv;
}
