#ifndef INCLUDED_INCIDENCE_
#define INCLUDED_INCIDENCE_

//  Incidence:
//      Normal:
//          prob:   1
//          #                   value   spread  distr.                    
//          lifetimeRisk:         .226  .0053   Normal  
//          meanAge:            72.9    .552    Normal 
//          stdDev:             21.1
//
//      BRCA1:
//          prob:   0
//          #                   value   spread  distr.                    
//          lifetimeRisk:         .96
//          meanAge:            53.9
//          stdDev:             16.51
//
//      BRCA2:
//          prob:   0
//          #                   value   spread  distr.                    
//          lifetimeRisk:         .96
//          meanAge:            53.9
//          stdDev:             16.51

//  as in the original sources: with 0 probabilities the specified values
//  are set to 0


#include <vector>
#include <string>

#include "../vsd/vsd.h"

struct Incidence
{
    class Params
    {
        friend class Incidence;

        unsigned d_idx;

        double   d_prob = 0;
        double  d_stdDev = 0;
                                                
        VSD     d_vsd[2] = { VSD{ VARY_PROB },      // lifetimeRisk
                             VSD{ VARY_NONNEG } };     // meanAge   
        public:
            Params(unsigned idx);
            void vary(std::ostream &out);

            double   prob() const;
            VSD const &risk() const;           // lifeTimeRisk
            VSD const &mean() const;
            double stdDev() const;
    };

    private:
        std::vector<Params> d_params;
        DoubleVect d_cumProb;
        DoubleVect2 d_tumorRisk;
        static StringVect s_carrier;    

    public:
        Incidence();

        void vary(std::ostream &out);            // vary d_vsd's values

        std::vector<Params> const &params() const;  
        uint16_t carrier() const;               // randomly selected carrier
                                                // index

        DoubleVect2 const &tumorRisk() const;
        DoubleVect const &tumorRisk(size_t idx) const;

        void writeParameters(std::ostream &out) const;

    private:
        void setCarrier(size_t idx);            // sets d_params
        bool carrierProb(StringVect const &base, Params &params);
        static bool lifetimeRisk(StringVect &base, VSD &vsd);
        static bool meanAge(StringVect &base, VSD &vsd);
        static bool stdDev(StringVect &base, double &sd);

        double sumProbs();

        void cptTumorRisk();            // assign values to d_tumorRisk    1
        void cptTumorRisk(DoubleVect &ageValues,                        // 2
                          Params const &params);

        static void writeCarrier(std::ostream &out, size_t idx, 
                                 char type, double value);

        static bool valid(double sumProb);
};
        
inline std::vector<Incidence::Params> const &Incidence::params() const
{
    return d_params;
}

inline Incidence::Params::Params(unsigned idx)
:
    d_idx(idx)
{}

inline double Incidence::Params::prob() const
{
    return d_prob;
}

inline VSD  const &Incidence::Params::risk() const
{
    return d_vsd[0];
}

inline VSD const &Incidence::Params::mean() const
{
    return d_vsd[1];
}

inline double Incidence::Params::stdDev() const
{
    return d_stdDev;
}

inline DoubleVect2 const &Incidence::tumorRisk() const
{
    return d_tumorRisk;
}

inline DoubleVect const &Incidence::tumorRisk(size_t idx) const
{
    return d_tumorRisk[idx];
}

#endif
