//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
const cvf::StructGridInterface* RimCellRangeFilterCollection::gridByIndex(int gridIndex) const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        RigGridBase* grid = NULL;

        grid = mnGrid->gridByIndex(gridIndex);

        CVF_ASSERT(grid);

        return grid;
    }
    else if (femPartColl)
    {
        if (gridIndex < femPartColl->partCount())
            return femPartColl->part(gridIndex)->structGrid();
        else 
            return NULL;
    }
    
    return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<size_t> RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(const RimEclipseCase* eclipseCase,
                                                                              const RimFracture*    fracture)
{
    std::set<size_t> cellsOpenForFlow;

    if (eclipseCase && fracture)
    {
        auto eclipseCaseData = eclipseCase->eclipseCaseData();
        if (eclipseCaseData)
        {
            auto mainGrid = eclipseCaseData->mainGrid();

            if (mainGrid)
            {
                std::set<size_t> cellsIntersectingFracturePlane = getCellsIntersectingFracturePlane(mainGrid, fracture);

                // Negative faultThrow disables test on faultThrow
                double maximumFaultThrow = -1.0;
                if (fracture->fractureTemplate() && fracture->fractureTemplate()->fractureContainment())
                {
                    maximumFaultThrow = fracture->fractureTemplate()->fractureContainment()->minimumFaultThrow();
                }

                if (maximumFaultThrow > -1.0)
                {
                    size_t anchorCellGlobalIndex = mainGrid->findReservoirCellIndexFromPoint(fracture->anchorPosition());
                    appendNeighborCells(cellsIntersectingFracturePlane,
                                        mainGrid,
                                        anchorCellGlobalIndex,
                                        cellsOpenForFlow,
                                        maximumFaultThrow);
                }
                else
                {
                    cellsOpenForFlow = cellsIntersectingFracturePlane;
                }
            }

            /*
            NB : Please do not delete this code, used to create input to cell based range filter to see the computed fracture
            cells

                        qDebug() << "FracturedCells - Truncated";
                        qDebug() << RigReservoirGridTools::globalCellIndicesToOneBasedIJKText(
                            fracturedCellsContainedByFaults.begin(), fracturedCellsContainedByFaults.end(), mainGrid);
            */
        }
    }

    return cellsOpenForFlow;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
QString RimCellRangeFilterCollection::gridName(int gridIndex) const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        return mnGrid->gridByIndex(gridIndex)->gridName().c_str();
    }
    else if (femPartColl)
    {
        return QString::number(gridIndex);
    }

    return "";
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
int RimCellRangeFilterCollection::gridCount() const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        return (int)mnGrid->gridCount();
    }
    else if (femPartColl)
    {
        return femPartColl->partCount();
    }

    return 0;
}
/*
 * main()
 * 
 * runs the program in a specific order.
 * 
 */
int main(int argc, char** argv) {
    //Grid mainGrid(100, 50, 0.1, 0.2); // create a custom sized grid to print
    Grid mainGrid(50, 0.2); // create a square grid
    mainGrid.printGrid(); // print blank grid
    
    Robot mainRobot; // initiate the robot object
    mainRobot.getData("poses.txt", "ranges.txt");
    
    // get data and move robot as many times as there are lines in poses.txt and print grid at each stage
    for(int i = 0; i < mainRobot.getPoses().size(); i++) {
        mainRobot.moveRobot(&mainGrid); // moves the robot to the next position
        //mainRobot.addRobotPositionToGrid(&mainGrid); // adds the robots position to the grid
        mainRobot.detect(&mainGrid); // detects obstacles around the robot by reading all the sensors
        mainGrid.printGrid(); // print grid for each move for animated grid
    }
    
    //mainGrid.printGrid(); // print the full grid after all obstacles have been detected
    
    return 0;
}