#ifndef INCLUDED_PROBGROUP_
#define INCLUDED_PROBGROUP_

#include <iosfwd>
#include <vector>
#include <cstdint>

#include "../typedefs/typedefs.h"
#include "../group/group.h"
#include "../enums/enums.h"
#include "../globals/globals.h"

// This class used to be 'Density', but with the introduction of lung cancer
// simulations cumulative probabilites are also used by 'Survival'.


//
// config. params using probabilities:
// BreastDensities: (RANGE)
//     #                bi-rad:  a      b      c      d
//     ageGroup:    0  - 40:    .05    .30    .48    .17

// Table S3 probabilities (SINGLE)
//     prob:      20:       .703    .197      .055        .045       # T1b
//     prob:       *:       .187    .347      .256        .210       # T4


class ProbGroup
{
    friend std::istream &operator>>(std::istream &in, ProbGroup &probgroup);
    friend std::ostream &operator<<(std::ostream &out,
                                    ProbGroup const &probgroup);

    enum
    {
        N_PROBCATS = 4,   // # of probability categories
    };

    // d_group contains the age group (begin() and end()
    // d_prob the probabilities, d_cumProbs the cumulative probabilities

                                            // cf Group::extract(). begin() 
    Group   d_group;                        // not used, end() is inclusive

    std::vector<double> d_prob;
    std::vector<double> d_cumProbs;
                                            // false: lung cancer sim.,
    bool d_breastCancer;                    // true: breast cancer sim.

    static char const *s_labels[][2];

    public:
        using Vector = std::vector<ProbGroup>;  // ensure sorted by group-end
                                                // and that the full range is
                                                // covered
        ProbGroup(Series series);

        double  begin() const;                                          // .f
        double  end() const;                                            // .f

        Group const &group() const;                                     // .f

        std::vector<double> const &prob() const;    // was: birad       // .f
        double    prob(size_t idx) const;           // was: birad       // .f

        bool sumOne() const;

        static RowCol probIndexOf(Vector const &vect,
                                    double value, double prob);

    private:
        bool contains(double value) const;                              // .f

        std::istream &extract(std::istream &in);
        std::ostream &insert(std::ostream &out) const;

                                                // string::npos: 'value' not
                                                // in the ProbGroup's.
        uint16_t indexOf(double value) const;

};

#include "probgroup.f"

#endif
