// $Id: Converter_IndividualDS.h,v 1.15 2018/01/03 21:32:56 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: Patrick Colacurcio, Peter Beerli, Mary Kuhner, Jon Yamato 
/* Authors: Patrick Colacurcio, Peter Beerli, Mary Kuhner, Jon Yamato 
and Joseph Felsenstein */


// IndividualDS is a representation of the data for any individual.
// Each individual owns a name, and a sequence'.
// Theres no validation on individual, however, there is on sequence, so if you
// use the constructor that takes (string name, string sequence) you may
// get a ConverterBaseError of some type.

// TODO  Find out if no name is okay.

// Methods
// const Sequence& getSequence() returns a const reference to the Sequence.
// const string& getName() returns the individual name as a const string reference.  (may be "")

// IndividualDS(const string& name, const Sequence& seq)
// IndividualDS(const string& name, const string& seq)

#ifndef CONVERTER_INDIVIDUALDS_H
#define CONVERTER_INDIVIDUALDS_H

#include <string>
#include <vector>
#include "Converter_DataSourceIf.h"
#include "Converter_Sequence.h"

using std::string;
using std::vector;

class IndividualDS : public DataSourceIf
{
  private:
    string m_name;
    vector<Sequence> m_seq;
    vector<string> m_seqnames;
    vector<long> m_unknownphase;

    IndividualDS();  // undefined

  public:
    IndividualDS(const string& name) : m_name(name) {};
    IndividualDS(const string& name, const Sequence& seq);
    // TODO. Take this out once operator ::string is a part of Sequence
    IndividualDS(const string& name, const string& seq);
    IndividualDS(const string& name, const string& seq, const string& dataType);

    virtual ~IndividualDS();

    // Use the Default Copy Constructor.
    // Use the Default operator=

    //  get the name of the individual
    string getName() const;

    //  set the name of the individual
    void setName(const string& name);

    // Two helper functions.  Get the guts of the Sequence
    //  get the sequence (as a string).
    string getSequence() const;

    //  get the sequenceLength (as a int).
    int getSequenceLength() const;

    //  get the datatype of the first sequence
    string getDataType() const { return m_seq.front().getDataType(); };

    //  get all the sequence names in the individual
    vector<string> GetAllSeqNames() const;

    //  get the sequence names (supporter function for haplotyping, where
    //  the sequence names stand in for haplotype names)
    vector<string> GetHapNames() const;

    //  a supporter function for error reporter, returns a comma delimited
    //  list of the haplotype names in a single string
    string GetHapNamesForPrint() const;

    //  get the number of haplotypes
    long GetNHaps() const { return static_cast<long>(m_seqnames.size()); };

    // add a haplotype name or set of names to the individual
    void AddHap(const string& name) { m_seqnames.push_back(name); };
    void AddHap(const vector<string>& names) { m_seqnames.insert(
            m_seqnames.end(),
            names.begin(),
            names.end()); };
    // add a sequence
    void AddSequence(const Sequence& seq) { m_seq.push_back(seq); };

    //  get the number of sequences
    unsigned long GetNumberOfSequences() const { return m_seq.size(); };

    // is a given sequence present?
    bool HasSequence(const string& seqname) const;

    // are any sequences present?
    bool HasNoSequences() const;

    // is any non-contiguous data present?
    bool HasNonContiguousData() const;

    // are any SNPs present?
    bool HasSNPs() const;

    // remove a single sequence
    Sequence PopSequence(const string& seqname);

    // add unknown phase information
    void SetUnknownPhase(const vector<long>& sites) { m_unknownphase = sites; };

    string getXML(unsigned int numTabs) const;   //  From DataSourceIf
};

#endif  // CONVERTER_INDIVIDUALDS_H

//____________________________________________________________________________________
