#include "proteincode_lib.h"
#include <pappsomspp/utils.h>


void
FastaProteinArrayHandler::setSequence(const QString &description_in,
                                      const QString &sequence_in)
{
  m_proteinArray.push_back({description_in, sequence_in});
}

const std::vector<pappso::Protein> &
FastaProteinArrayHandler::getProteinArray() const
{
  return m_proteinArray;
};


void
writeProteinConvolutionScore(
  const QString &filename,
  const pappso::Protein &protein,
  const pappso::ProteinPresenceAbsenceMatrix *pmatrix,
  const std::vector<double> &convolution_score)
{

  QFile file(filename);
  // file.open(QIODevice::WriteOnly);
  OdsDocWriter writer(&file);

  writer.writeSheet(protein.getAccession());
  writer.writeCell("sequence");
  for(long long i = 0; i < protein.getSequence().size(); i++)
    {
      writer.writeCell(protein.getSequence()[i]);
    }
  writer.writeLine();
  writer.writeCell("convolution score");
  for(long long i = 0; i < protein.getSequence().size(); i++)
    {
      writer.writeCell(convolution_score[i]);
    }
  writer.writeLine();
  if(pmatrix != nullptr)
    {


      auto matrix = pmatrix->getPresenceAbsenceMatrix();
      for(long long j = 0; j < 5; j++)
        {

          writer.writeCell(QString("%1aa").arg(j + 1));
          for(long long i = 0; i < protein.getSequence().size(); i++)
            {

              if(matrix(i, j) == pappso::ProteinPresenceAbsenceMatrix::
                                   ProteinPresenceAbsenceMatrixElement::present)
                {
                  writer.writeCell("X");
                }
              else
                {
                  writer.writeEmptyCell();
                }
            }

          writer.writeLine();
        }
    }

  writer.close();
}

void
writeSelfSpectrum(const QString &filename,
                  const pappso::specself::SelfSpectrum &self_spectrum,
                  const pappso::AaStringCodec &aa_codec)
{
  qDebug();
  QFile file(filename);
  // file.open(QIODevice::WriteOnly);
  OdsDocWriter writer(&file);

  writer.writeSheet("spectrum_matrix");

  const pappso::specself::SelfSpectrumMatrix &matrix =
    self_spectrum.getMatrix();
  const pappso::Trace &trace = self_spectrum.getTrace();


  writer.writeLine();
  writer.writeEmptyCell();
  writer.writeEmptyCell();
  for(auto datapoint : trace)
    {
      writer.writeCell(datapoint.x);
    }
  auto it_trace = trace.begin();
  for(auto itmi = ++matrix.begin1(); itmi != matrix.end1(); ++itmi, ++it_trace)
    {
      writer.writeLine();
      writer.writeCell(it_trace->x);
      writer.writeCell(it_trace->y);
      for(auto itmj = ++itmi.begin(); itmj != itmi.end(); itmj++)
        {
          writer.writeCell(aa_codec.decode((*itmj).aaCodeList).join(" "));
        }
    }
  qDebug();
  writer.close();
}


void
writeSpectralAlignmentMatrix(
  const QString &filename,
  const pappso::specglob::SpectralAlignment &spectral_alignment)
{

  QFile file(filename);
  // file.open(QIODevice::WriteOnly);
  OdsDocWriter writer(&file);

  const matrix<pappso::specglob::SpectralAlignmentDataPoint> &matrix =
    spectral_alignment.getMatrix();

  pappso::PeptideSp peptide_sp =
    spectral_alignment.getPeptideSpectraCsp().get()->getPeptideSp();

  writer.writeSheet("score");
  std::size_t i = 0;
  // output_stream << "\n" << getExpeSpec().getMassList());
  for(auto itr1 = matrix.begin1(); itr1 != matrix.end1(); ++itr1, i++)
    {
      if(i < peptide_sp.get()->size())
        writer.writeCell(peptide_sp.get()->getConstAa(i).toProForma());
      else
        writer.writeEmptyCell();
      for(auto itr2 = itr1.begin(); itr2 != itr1.end(); itr2++)
        {
          writer.writeCell((*itr2).score);
        }
      writer.writeLine();
    }

  writer.writeSheet("alignment_type");
  for(auto itr1 = matrix.begin1(); itr1 != matrix.end1(); ++itr1)
    {
      for(auto itr2 = itr1.begin(); itr2 != itr1.end(); itr2++)
        {
          writer.writeCell(
            QString("[%1,%2]")
              .arg(pappso::Utils::toString((*itr2).alignment_type))
              .arg((*itr2).origin_column_indices));
        }
      writer.writeLine();
    }

  writer.writeSheet("mass_difference");
  for(auto itr1 = matrix.begin1(); itr1 != matrix.end1(); ++itr1)
    {
      for(auto itr2 = itr1.begin(); itr2 != itr1.end(); itr2++)
        {
          writer.writeCell((*itr2).mass_difference);
        }
      writer.writeLine();
    }
  writer.close();
}
