//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigReservoirCellResults::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max )
{
    min = HUGE_VAL;
    max = -HUGE_VAL;
	
    CVF_ASSERT(scalarResultIndex < resultCount());

    // Extend array and cache vars

    if (scalarResultIndex >= m_maxMinValues.size() )
    {
        m_maxMinValues.resize(scalarResultIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL));
    }

    if (m_maxMinValues[scalarResultIndex].first != HUGE_VAL)
    {
        min = m_maxMinValues[scalarResultIndex].first;
        max = m_maxMinValues[scalarResultIndex].second;

        return;
    }

    size_t i;
    for (i = 0; i < timeStepCount(scalarResultIndex); i++)
    {
        double tsmin, tsmax;
        minMaxCellScalarValues(scalarResultIndex, i, tsmin, tsmax);
        if (tsmin < min) min = tsmin;
        if (tsmax > max) max = tsmax;
    }

    m_maxMinValues[scalarResultIndex].first = min;
    m_maxMinValues[scalarResultIndex].second= max;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg)
{
    pos = HUGE_VAL;
    neg = -HUGE_VAL;

    CVF_ASSERT(scalarResultIndex < resultCount());

    // Extend array and cache vars

    if (scalarResultIndex >= m_posNegClosestToZero.size() )
    {
        m_posNegClosestToZero.resize(scalarResultIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL));
    }

    if (m_posNegClosestToZero[scalarResultIndex].first != HUGE_VAL)
    {
        pos = m_posNegClosestToZero[scalarResultIndex].first;
        neg = m_posNegClosestToZero[scalarResultIndex].second;

        return;
    }

    size_t i;
    for (i = 0; i < timeStepCount(scalarResultIndex); i++)
    {
        double tsNeg, tsPos;
        posNegClosestToZero(scalarResultIndex, i, tsPos, tsNeg);
        if (tsNeg > neg && tsNeg < 0) neg = tsNeg;
        if (tsPos < pos && tsPos > 0) pos = tsPos;
    }

    m_posNegClosestToZero[scalarResultIndex].first = pos;
    m_posNegClosestToZero[scalarResultIndex].second= neg;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseSummary::values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values)
{
    assert(ecl_sum != NULL);

    int variableIndex = indexFromAddress(resultAddress);

    if ( variableIndex < 0 ) return false;

    values->clear();
    int tsCount = timeStepCount();
    values->reserve(timeStepCount());


    const smspec_node_type * ertSumVarNode = ecl_smspec_iget_node(eclSmSpec, variableIndex);
    int paramsIndex = smspec_node_get_params_index(ertSumVarNode);

    for(int time_index = 0; time_index < tsCount; time_index++)
    {
        double value = ecl_sum_iget(ecl_sum, time_index, paramsIndex);
        values->push_back(value);
    }

    return true;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseSummary::open(const std::string& headerFileName, const std::vector<std::string>& dataFileNames)
{
    assert(ecl_sum == NULL); 
    
    if (headerFileName.empty() || dataFileNames.size() == 0) return false;

    assert(!headerFileName.empty());
    assert(dataFileNames.size() > 0);

    stringlist_type* dataFiles = stringlist_alloc_new();
    for (size_t i = 0; i < dataFileNames.size(); i++)
    {
        stringlist_append_copy(dataFiles, dataFileNames[i].data());
    }

    std::string itemSeparatorInVariableNames = ":";
    ecl_sum = ecl_sum_fread_alloc(headerFileName.data(), dataFiles, itemSeparatorInVariableNames.data());

    stringlist_free(dataFiles);

    if (ecl_sum)
    {
        eclSmSpec = ecl_sum_get_smspec(ecl_sum);
        assert(eclSmSpec != NULL);

        assert(ecl_sum != NULL);

        for ( int time_index = 0; time_index < timeStepCount(); time_index++ )
        {
            time_t sim_time = ecl_sum_iget_sim_time(ecl_sum, time_index);
            m_timeSteps.push_back(sim_time);
        }

        return true;
    }

    return false;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, double& meanValue)
{
    CVF_ASSERT(scalarResultIndex < resultCount());

    // Extend array and cache vars

    if (scalarResultIndex >= m_meanValues.size() )
    {
        m_meanValues.resize(scalarResultIndex+1, HUGE_VAL);
    }

    if (m_meanValues[scalarResultIndex] != HUGE_VAL)
    {
        meanValue = m_meanValues[scalarResultIndex];
        return;
    }

    double valueSum = 0.0;
    size_t count = 0;

    if (scalarResultIndex == m_combinedTransmissibilityResultIndex)
    {
        size_t tranX, tranY, tranZ;
        if (findTransmissibilityResults(tranX, tranY, tranZ))
        {
            for (size_t tIdx = 0; tIdx < timeStepCount(tranX); tIdx++)
            {
                {
                    std::vector<double>& values = m_cellScalarResults[tranX][tIdx];
                    for (size_t cIdx = 0; cIdx < values.size(); ++cIdx)
                    {
                        valueSum += values[cIdx];
                    }
                    count += values.size();
                }
                {
                    std::vector<double>& values = m_cellScalarResults[tranY][tIdx];
                    for (size_t cIdx = 0; cIdx < values.size(); ++cIdx)
                    {
                        valueSum += values[cIdx];
                    }
                    count += values.size();
                }
                {
                    std::vector<double>& values = m_cellScalarResults[tranZ][tIdx];
                    for (size_t cIdx = 0; cIdx < values.size(); ++cIdx)
                    {
                        valueSum += values[cIdx];
                    }
                    count += values.size();
                }
            }
        }
    }
    else
    {
        for (size_t tIdx = 0; tIdx < timeStepCount(scalarResultIndex); tIdx++)
        {
            std::vector<double>& values = m_cellScalarResults[scalarResultIndex][tIdx];
            for (size_t cIdx = 0; cIdx < values.size(); ++cIdx)
            {
                valueSum += values[cIdx];
            }
            count += values.size();
        }
    }

    m_meanValues[scalarResultIndex] = valueSum/count;
    meanValue = m_meanValues[scalarResultIndex];
}