// $Id: phenotypes.h,v 1.6 2018/01/03 21:32:58 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Lucian Smith, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


#ifndef PHENOTYPES_H
#define PHENOTYPES_H

#include <string>
#include <vector>
#include <set>
#include <map>

#include "haplotypes.h"

class Phenotypes
{
  private:
    Phenotypes(); //undefined
    //The parent.  Needed to give to the haplotypes to make DLCells.
    long m_regionnum;
    string m_locusname;

    // m_phenomap is a map of a set of alleles (as strings) to a vector of
    //  phenotype names and a vector of phenotype penetrances.  This is stored
    //  as a pair of vectors instead of a vector of pairs so that we can take
    //  the vector of penetrances and scale it to sum to one before using it
    //  to create actual haplotypes.
    //
    // So, to sum up:  map<alleles, pair<NameVector, PenetranceVector> >
    std::map<std::multiset<std::string>, std::pair<std::vector<std::string>, std::vector<double> > > m_phenomap;

    // m_hapsmap is a map of phenotype names to a Haplotypes object.  When we
    // find out that an individual has a particular phenotype, we give it
    // the Haplotypes object (this will normally happen due to simulation)
    std::map<std::string, Haplotypes> m_hapsmap;

    //Private function to convert the m_phenomap into m_hapsmap.
    void MakeHaplotypes();
    std::multiset<std::string> VecToSet(StringVec1d vec);

  public:
    Phenotypes(long regionnum, string lname);
    Phenotypes(string lname); //A blank copy.
    ~Phenotypes() {};
    //We accept the default for:
    //Phenotypes& operator=(const Phenotypes& src);
    //Phenotypes(const Phenotypes& src);

    void AddPhenotype(const StringVec1d& alleles, string name, double penetrance);
    Haplotypes ChooseHaplotypes(const StringVec1d& alleles);
    Haplotypes GetHaplotypes(string phenotypeName);
    StringVec1d GetPhenotypesXML(long nspaces) const;
    bool AnyDefinedPhenotypes() const {return (m_phenomap.size()>0);};
};

#endif // PHENOTYPES_H

//____________________________________________________________________________________
