/*
 * Copyright (c) 1999 Johnny C. Lam.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  The author makes no representations
 * about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 */

// -*- C++ -*-

#ifndef DICTIONARY_H_INCLUDED
#define DICTIONARY_H_INCLUDED

#ifndef IOSFWD_INCLUDED
#include <iosfwd>
#define IOSFWD_INCLUDED
#endif

#ifndef STL_MAP_INCLUDED
#include <map>
#define STL_MAP_INCLUDED
#endif

#ifndef STL_VECTOR_INCLUDED
#include <vector>
#define STL_VECTOR_INCLUDED
#endif

#ifndef HAPLOTYPE_H_INCLUDED
#include "haplotype.h"
#endif

#ifndef TYPES_H_INCLUDED
#include "types.h"
#endif

class SegmentProbability;

///////////////////////////////////////////////////////////////////////////
//
// HDictionary
//
// Concrete class implementing haplotype dictionary using STL maps.
//
///////////////////////////////////////////////////////////////////////////

class HDictionary {
public:
    typedef Haplotype::size_type size_type;
    
    HDictionary(SegmentProbability*, bool = false);

    // Reads delimited haplotypes from istr.
    void	ReadDelimited(istream&, char = '\n', unsigned int = 0);

    // Reads allele frequencies from istr.
    void	ReadFrequencies(istream&, size_type);

    // Returns the frequency of the haplotype h starting at pos.
    probability	Frequency(const Haplotype&, size_type) const;
    
    // Sets the frequency of the haplotype h starting at pos to prob.
    void	AddFrequency(const Haplotype&, size_type, probability);
    
    // Returns the probability of haplotype h starting at pos.
    probability	Probability(const Haplotype&, size_type);
    
    // Returns the total number of (full) haplotypes.
    size_type	NumberOfHaplotypes() const;
    
    // Writes the contents of the dictionary to ostream.
    void	Write(ostream&) const;
    
    // Returns if dictionary should be verbose.
    bool	Verbose() const;
    
private:
    void	AddHaplotype(const Haplotype&);
    void	Freeze();
    
    typedef std::map<Haplotype, probability> HaploMap;
    typedef std::vector<HaploMap> Volumes;
    
    SegmentProbability* _segment;
    bool	_verbose;
    Volumes	_dictionaries;
    size_type	_num_haps;
    bool	_frozen;
};

#include "dictionary_inline.h"

#endif /* DICTIONARY_H_INCLUDED */
