text: /**
   * UGENE - Integrated Bioinformatics Tools.
   * Copyright (C) 2008-2012 UniPro <ugene@unipro.ru>
   * http://ugene.unipro.ru
   *
   * 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 2
   * 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, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA 02110-1301, USA.
   */
  
  #ifndef _GENOME_ALIGNER_IO_H_
  #define _GENOME_ALIGNER_IO_H_
  
  
  #include "GenomeAlignerSearchQuery.h"
  #include "GenomeAlignerIndexPart.h"
  
  #include <U2Core/DNASequenceObject.h>
  #include <U2Core/GUrl.h>
  #include <U2Core/MAlignment.h>
  #include <U2Core/U2OpStatusUtils.h>
  #include <U2Core/U2DbiUtils.h>
  
  #include <U2Formats/StreamSequenceReader.h>
  #include <U2Formats/StreamSequenceWriter.h>
  #include <U2Lang/LocalDomain.h>
  #include <U2Lang/WorkflowUtils.h>
  
  #include <QtCore/QString>
  #include <QtCore/QSharedPointer>
  
  #include <memory>
  
  namespace U2 {
  
  /************************************************************************/
  /* Abstract short reads reader and writer                               */
  /************************************************************************/
  
  class GenomeAlignerReader {
  public:
      virtual ~GenomeAlignerReader() {}
      virtual SearchQuery *read() = 0;
      virtual bool isEnd() = 0;
      virtual int getProgress() = 0;
  };
  
  class GenomeAlignerWriter {
  public:
      virtual void write(SearchQuery *seq, SAType offset) = 0;
      virtual void close() = 0;
      virtual void setReferenceName(const QString &refName) = 0;
      quint64 getWrittenReadsCount() const {return writtenReadsCount;}
  protected:
      quint64 writtenReadsCount;
      QString refName;
  };
  
  /************************************************************************/
  /* Abstract container for storing in QVariant                            */
  /************************************************************************/
  class GenomeAlignerReaderContainer {
  public:
      GenomeAlignerReaderContainer() : reader(NULL) { }
      GenomeAlignerReaderContainer(GenomeAlignerReader* reader) {
          this->reader = reader;
      }
      GenomeAlignerReader* reader;
  };
  
  class GenomeAlignerWriterContainer {
  public:
      GenomeAlignerWriterContainer() : writer(NULL) {}
      GenomeAlignerWriterContainer(GenomeAlignerWriter* writer) {
          this->writer = writer;
      }
      GenomeAlignerWriter* writer;
  };
  
  /************************************************************************/
  /* URL short reads reader and writer                                    */
  /************************************************************************/
  
  class GenomeAlignerUrlReader : public GenomeAlignerReader {
  public:
      GenomeAlignerUrlReader(const QList<GUrl> &dnaList);
      inline SearchQuery *read();
      inline bool isEnd();
      int getProgress();
  private:
      bool initOk;
      StreamSequenceReader reader;
  };
  
  class GenomeAlignerUrlWriter : public GenomeAlignerWriter {
  public:
      GenomeAlignerUrlWriter(const GUrl &resultFile, const QString &refName, int refLength);
      inline void write(SearchQuery *seq, SAType offset);
      void close();
      void setReferenceName(const QString &refName);
  private:
      StreamShortReadsWriter seqWriter;
  };
  
  /************************************************************************/
  /* Workflow short reads reader and writer                               */
  /************************************************************************/
  namespace LocalWorkflow {
  
  class GenomeAlignerCommunicationChanelReader : public GenomeAlignerReader {
  public:
      GenomeAlignerCommunicationChanelReader(CommunicationChannel* reads);
      ~GenomeAlignerCommunicationChanelReader();
      inline SearchQuery *read();
      inline bool isEnd();
      int getProgress();
  private:
      CommunicationChannel* reads;
  };
  
  class GenomeAlignerMAlignmentWriter : public GenomeAlignerWriter {
  public:
      GenomeAlignerMAlignmentWriter();
      inline void write(SearchQuery *seq, SAType offset);
      void close();
      void setReferenceName(const QString &refName);
      MAlignment &getResult();
  private:
      MAlignment result;
  };
  
  } //LocalWorkflow
  
  /************************************************************************/
  /* DBI short reads reader and writer                                    */
  /************************************************************************/
  class GenomeAlignerDbiReader : public GenomeAlignerReader {
  public:
      GenomeAlignerDbiReader(U2AssemblyDbi *rDbi, U2Assembly assembly);
      inline SearchQuery *read();
      inline bool isEnd();
      int getProgress();
  private:
      bool end;
      U2AssemblyDbi *rDbi;
      U2Assembly assembly;
      QList<U2AssemblyRead> reads;
      U2Region wholeAssembly;
      U2OpStatusImpl status;
      QList<U2AssemblyRead>::Iterator currentRead;
      qint64 readNumber;
      qint64 maxRow;
      qint64 readsInAssembly;
      std::auto_ptr< U2DbiIterator<U2AssemblyRead> > dbiIterator;
  
      static const qint64 readBunchSize;
  };
  
  class GenomeAlignerDbiWriter : public GenomeAlignerWriter {
  public:
      GenomeAlignerDbiWriter(QString dbiFilePath, QString refName, int refLength);
      inline void write(SearchQuery *seq, SAType offset);
      void close();
      void setReferenceName(const QString &) {};
  private:
      U2OpStatusImpl status;
      QSharedPointer<DbiConnection> dbiHandle;
      U2Dbi* sqliteDbi;
      U2AssemblyDbi *wDbi;
      U2Assembly assembly;
      QList<U2AssemblyRead> reads;
  
      static const qint64 readBunchSize;
  };
  
  bool checkAndLogError(const U2OpStatusImpl & status);
  
  } //U2
  Q_DECLARE_METATYPE(U2::GenomeAlignerReaderContainer);
  Q_DECLARE_METATYPE(U2::GenomeAlignerWriterContainer);
  #endif //_GENOME_ALIGNER_IO_H_
  