#ifndef _BLASR_ALIGNMENT_SET_TO_CMPH5_ADAPTER_HPP_
#define _BLASR_ALIGNMENT_SET_TO_CMPH5_ADAPTER_HPP_

#include <alignment/datastructures/alignment/ByteAlignment.h>
#include <alignment/algorithms/alignment/DistanceMatrixScoreFunction.hpp>
#include <alignment/datastructures/alignment/AlignmentCandidate.hpp>
#include <hdf/HDFCmpFile.hpp>
#include <pbdata/sam/AlignmentSet.hpp>
#include <pbdata/utils/SMRTReadUtils.hpp>

class RefGroupNameId
{
public:
    std::string name;
    unsigned int id;
    RefGroupNameId()
    {
        id = 0;
        name = "";
    }

    RefGroupNameId(std::string n, unsigned int i)
    {
        name = n;
        id = i;
    }

    RefGroupNameId(const RefGroupNameId &rhs)
    {
        name = rhs.name;
        id = rhs.id;
    }
};

// number of zmws per SMRTCell for springfield: 163482
const unsigned int numZMWsPerMovieSpringField = 163482;

template <typename T_CmpFile>
class AlignmentSetToCmpH5Adapter
{
public:
    // Map reference name to reference group (/RefGroup) name and ID.
    std::map<std::string, RefGroupNameId> refNameToRefGroupNameandId;
    std::map<std::string, unsigned int> knownMovies;
    std::map<std::string, unsigned int> knownPaths;
    unsigned int numAlignments;
    std::map<std::string, int> refNameToRefInfoIndex;

    void Initialize() { numAlignments = 0; }

    template <typename T_Reference>
    void StoreReferenceInfo(std::vector<T_Reference> &references, T_CmpFile &cmpFile);

    unsigned int StoreMovieInfo(std::string movieName, T_CmpFile &cmpFile);

    // Given a reference name, find whether there exists a refGroup
    // (e.g. /ref000001) associated with it.
    // If not, create a refGroup and update refNameToRefGroupNameandId.
    // Finally, return its associated refGroup ID.
    unsigned int StoreRefGroup(std::string refName, T_CmpFile &cmpFile);

    unsigned int StorePath(std::string &path, T_CmpFile &cmpFile);

    void RemoveGapsAtEndOfAlignment(AlignmentCandidate<> &alignment);

    void StoreAlignmentCandidate(AlignmentCandidate<> &alignment, int alnSegment,
                                 T_CmpFile &cmpFile, int moleculeNumber = -1, bool copyQVs = false);

    void StoreAlignmentCandidateList(std::vector<AlignmentCandidate<> > &alignments,
                                     T_CmpFile &cmpFile, int moleculeNumber = -1,
                                     bool copyQVs = false);

    void StoreAlignmentCandidate(AlignmentCandidate<> alignment, T_CmpFile &cmpFile)
    {
        StoreAlignmentCandidate(alignment, 0, cmpFile);
    }
};

#include "AlignmentSetToCmpH5AdapterImpl.hpp"

#endif
