// $Id: gc_individual.cpp,v 1.19 2018/01/03 21:32:55 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: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#include <cassert>

#include "gc_errhandling.h"
#include "gc_individual.h"
#include "gc_individual_err.h"
#include "gc_locus.h"
#include "gc_parse_sample.h"
#include "gc_phase.h"
#include "gc_region.h"
#include "gc_sequential_data.h"
#include "gc_strings.h"
#include "wx/log.h"

//------------------------------------------------------------------------------------

gcSample::gcSample(wxString label)
    :
    m_label(label)
{
}

gcSample::~gcSample()
{
}

void
gcSample::AddLocusData(const gcLocus * locusP, const GCSequentialData * dataP)
{
    assert(locusP != NULL);
    std::map<const gcLocus*,const GCSequentialData *>::iterator iter;
    iter = m_data.find(locusP);
    if(iter != m_data.end())
    {
        throw gc_sample_locus_repeat(m_label,locusP->GetName());
    }
    m_data[locusP] = dataP;
}

const GCSequentialData &
gcSample::GetData(const gcLocus * locusP) const
{
    std::map<const gcLocus*,const GCSequentialData *>::const_iterator iter;
    iter = m_data.find(locusP);
    if(iter == m_data.end())
    {

        throw gc_sample_missing_locus_data(GetLabel(),locusP->GetName());
    }
    return *((*iter).second);
}

wxString
gcSample::GetLabel() const
{
    return m_label;
}

//------------------------------------------------------------------------------------

GCIndividual::GCIndividual( wxString                name,
                            const gcRegion &        regionRef)
    :
    m_name(name),
    m_regionRef(regionRef)
{
}

GCIndividual::~GCIndividual()
{
    for(std::vector<gcSample*>::iterator i=m_samples.begin(); i!=m_samples.end(); i++)
    {
        delete *i;
    }
}

void
GCIndividual::AddPhenotype(const gcPhenotype & pheno)
{
    m_phenotypeIds.insert(pheno.GetId());
}

const gcIdSet &
GCIndividual::GetPhenotypeIds() const
{
    return m_phenotypeIds;
}

void
GCIndividual::AddPhase(const gcLocus & locusRef, const gcUnphasedMarkers & phaseInfo)
{
    std::map<const gcLocus*,gcUnphasedMarkers>::iterator iter = m_phaseInfo.find(&locusRef);
    if(iter == m_phaseInfo.end())
    {
        m_phaseInfo[&locusRef] = phaseInfo;
    }
    else
    {
        gcUnphasedMarkers & markers = (*iter).second;
        markers.Merge(phaseInfo);
    }
}

void
GCIndividual::AddSample(wxString label, const gcLocus& locus, const GCSequentialData * data)
{

    assert(locus.GetRegionId() == m_regionRef.GetId());
    gcSample * thisSample = GetSample(label);
    if(thisSample == NULL)
    {
        thisSample = new gcSample(label);
        m_samples.push_back(thisSample);
    }

    assert(thisSample != NULL);
    thisSample->AddLocusData(&locus,data);
}

#if 0  // EWFIX.REMOVE
const gcTraitSet &
GCIndividual::GetGenotypeResolutions() const
{
    return m_traits;
}
#endif

wxString
GCIndividual::GetName() const
{
    return m_name;
}

const gcRegion &
GCIndividual::GetRegion() const
{
    return m_regionRef;
}

size_t
GCIndividual::GetNumSamples() const
{
    return m_samples.size();
}

const gcUnphasedMarkers *
GCIndividual::GetUnphased(const gcLocus & locusRef) const
{
    std::map<const gcLocus*,gcUnphasedMarkers>::const_iterator iter = m_phaseInfo.find(&locusRef);

    if(iter == m_phaseInfo.end())
    {
        return NULL;
    }
    return &((*iter).second);
}

gcSample *
GCIndividual::GetSample(wxString label)
{
    for(std::vector<gcSample*>::iterator i = m_samples.begin(); i != m_samples.end(); i++)
    {
        gcSample * sample = *i;
        if(sample->GetLabel() == label)
        {
            return sample;
        }
    }
    return NULL;
}

const gcSample *
GCIndividual::GetSample(size_t index) const
{
    assert(index < m_samples.size());
    return m_samples[index];
}

void
GCIndividual::DebugDump(wxString prefix) const
{
    wxLogDebug("%sIndividual %s of region %s with %d samples",  // EWDUMPOK
               prefix.c_str(),
               m_name.c_str(),
               m_regionRef.GetName().c_str(),
               (int)(m_samples.size()));
}

//____________________________________________________________________________________
