/*
 * File:   FastaParser.h
 * Author: yangxi
 *
 * Created on December 19, 2012, 11:24 AM
 */

#ifndef HTIO2_FASTA_IO_H
#define	HTIO2_FASTA_IO_H

#include "htio2/SeqIO.h"

namespace htio2
{

class FastaIO;

class FastaIO : public SeqIO
{
public:
    typedef htio2::SmartPtr<FastaIO> Ptr;
    typedef htio2::SmartPtr<const FastaIO> ConstPtr;
public:
    /**
     * create sequence IO object by file name
     * @param file file to open
     * @param mode read/write/append
     * @param comp compress format. COMPRESS_UNKNOWN for automatically guess.
     */
    FastaIO(const std::string& file, IOMode mode, CompressFormat comp = COMPRESS_UNKNOWN);

    /**
     * create sequence IO object from HTIO file handle object
     * @param handle
     */
    FastaIO(FileHandle* handle);

    /**
     * create sequence IO object from C standard file handle
     * @param handle
     * @param auto_close if set to true, the underlying handle will be closed when sequence IO object is destroyed
     */
    FastaIO(FILE* handle, bool auto_close = true);

    /**
     * create sequence IO object from Zlib file handle
     * @param handle
     * @param auto_close if set to true, the underlying handle will be closed when sequence IO object is destroyed
     */
    FastaIO(gzFile handle, bool auto_close = true);
    virtual ~FastaIO();

    /**
     * Seek to a file offset.
     * It must be ensured that the offset is always on the beginning of a FASTA entry.
     * The offset can be different with the wrapped FileHandle's offset.
     * See implementation of next_seq() for detail.
     * @param offset
     * @param whence 0 for absolute, 1 for relative
     */
    virtual void seek(off_t offset, int whence = SEEK_SET) override;

    /**
     * get the current file offset
     * The offset can be different with the wrapped FileHandle's offset.
     * See implementation of next_seq() for detail.
     * @return file offset that is on the beginning of a FASTA entry.
     */
    virtual off_t tell() const override;

    /**
     * read one sequence
     * @param result
     * @return true if got a seq, false if reached end of file
     */
    virtual bool next_seq(SimpleSeq& result) override;

    /**
     * Read one sequence with quality. The qualities are set to 33+40.
     * @param result
     * @return true if got a seq, false if reached end of file
     */
    virtual bool next_seq(FastqSeq& result) override;

    /**
     * write one sequence
     * @param seq the sequence to be written
     */
    virtual void write_seq(const SimpleSeq& seq) override;

    virtual void write_seq(const FastqSeq& seq) override;
protected:
    /**
     * The FastaIO guarantee that it won't seek while reading and writing.
     * However, it could know the position of a record after the header line was read.
     * Thus we need these facilities to record the file offset before the header line.
     */
    off_t handle_offset;
    void init_buffer();
};
} // namespace htio2

#endif	/* HTIO2_FASTA_IO_H */

