/*
 * 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 PATH_H_INCLUDED
#define PATH_H_INCLUDED

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

#ifndef STL_LIST_INCLUDED
#include <list>
#define STL_LIST_INCLUDED
#endif

#ifndef STL_REFCOUNT_INCLUDED
#include <refcount>
#define STL_REFCOUNT_INCLUDED
#endif

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

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

class Path {
    
    class Edge;
    typedef std::list<Edge> container_type;
    
public:
    typedef typename container_type::const_iterator const_iterator;
    
    Path();
    Path(const Haplotype&);

public:    
    const_iterator	begin() const;
    const_iterator	end() const;
    unsigned int	size() const;
    
public:
    log_probability	Weight() const;
    const Haplotype&	From() const;
    const Haplotype&	To() const;
    
    void	Add(const Edge&);
    void	Merge(Path&);
    Path&	operator+=(const Path&);

    void	Write(ostream&) const;
    
public:
    struct Edge {
	Haplotype	haplotype;
	log_probability	weight;
	
	Edge();
	Edge(const Haplotype&, log_probability);
    };
    
private:
    struct EdgePlus {
	log_probability	operator() (log_probability, const Edge&) const;
    };
    
    struct PathValue : public rc_object {
	container_type edges;
    };
    
    rc_ptr<PathValue> _value;
};

ostream&	operator<<(ostream&, const Path&);
const Path	operator+(const Path&, const Path&);

#include <path_inline.h>

#endif // PATH_H_INCLUDED
