//     HTIO - a high-throughput sequencing reads input/output library
//
//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
//
//     You should have received a copy of the GNU General Public License
//     along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef HTIO2_GZIP_FILE_HANDLE_H
#define	HTIO2_GZIP_FILE_HANDLE_H

#include "htio2/FileHandle.h"
#include <zlib.h>

namespace htio2
{

class GzipFileHandle : public FileHandle
{
    friend class ::TestFramework;
public:
    typedef SmartPtr<GzipFileHandle> Ptr;
    typedef SmartPtr<const GzipFileHandle> ConstPtr;

public:
    /**
     * create by file name and mode
     * @param file file name
     * @param mode "rb" for read, "wb" for write
     */
    GzipFileHandle(const std::string& file, IOMode mode);

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

    virtual ~GzipFileHandle();

    /**
     * Read one line. The end-of-line character can be CR, LF and CRLF.
     * @param buffer
     * @return true if get a line, false if reached end of file.
     */
    virtual bool read_line(std::string& buffer);

    /**
     * Write one line. The end-of-line character is decided by the system.
     * @param content
     */
    virtual void write_line(const std::string& content);

    /**
     * Seek to a file offset.
     * The offset can be different with the wrapped FILE* or gzFile's offset.
     * See implementation of read_line() for detail.
     * @param offset
     * @param whence SEEK_SET or 0 for absolute, SEEK_CUR or 1 for relative. Note: SEEK_END is not supported by zlib.
     */
    virtual void seek(off_t offset, int whence = SEEK_SET);

    /**
     * Get the current file offset.
     * The offset can be different with the wrapped FILE* or gzFile's offset.
     * See implementation of read_line() for detail.
     * @return offset
     */
    virtual off_t tell() const;
private:
    gzFile handle;
    bool auto_close;
    off_t offset;
    char curr_chr;
};

} // namespace htio2

#endif	/* HTIO2_GZIP_FILE_HANDLE_H */

