/***************************************************************************
**
**  This file is part of gpmaplayer.
**
**  gpmaplayer 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.
**
**  gpmaplayer 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 Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2016-03-27
**  Copyright: 2016-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "RowImageMerger.h"

/*!
  \class RowImageMerger RowImageMerger.h
  \brief Brief description of class still missing

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
RowImageMerger::RowImageMerger()
  : ImageMerger()
{
  TRACE;
  _currentIndex=0;
}

/*!
  Description of destructor still missing
*/
RowImageMerger::~RowImageMerger()
{
  TRACE;
}

void RowImageMerger::setImage(QImage im, int minShift, int maxShift)
{
  TRACE;
  App::log(tr("Merging column image index %1\n").arg(_currentIndex) );
  if(_image.isNull()) {
    _image=im;
  } else {
    bool ok;
    int s=getPixelShift(im, _image, minShift, maxShift, ok);
    if(!ok) {
      App::log(tr("No correlation between successive images, check longitude step\n") );
      if(isDebugMode()) {
        QString fileName=QString("gpmaplayer_debug_row_%1-%2.png").arg(_currentIndex, 5, 10, QChar('_'));
        im.save(fileName.arg(1), "PNG");
        App::log(tr("New image  saved in '%1'\n").arg(fileName.arg(1)) );
        _image.save(fileName.arg(2), "PNG");
        App::log(tr("Main image  saved in '%1'\n").arg(fileName.arg(2)) );
      }
      printAverageSteps();
      ::exit(2);
    }
    QImage newIm(_image.size()+QSize(s, 0), _image.format());
    QPainter p;
    p.begin(&newIm);
    p.drawImage(s, 0, _image);
    p.drawImage(0, 0, im);
    p.end();
    _image=newIm;
  }
  _currentIndex++;
}

int RowImageMerger::getPixelShift(const QImage& im1, const QImage& im2, int minShift, int maxShift, bool& ok)
{
  TRACE;
  // New image is above the current main image
  // For correlation we just scan the top ot he main image
  DoubleSignal * newVector=imageVector(im1, im1.width());
  DoubleSignal * mainVector=imageVector(im2, im1.width());
  DoubleSignal * corr=new DoubleSignal();
  corr->normalizedCorrelation(mainVector, newVector, mainVector->nSamples()-1);
  int n=(corr->nSamples()-1)/2;
  int s=corr->maximumAt(n+minShift, n+maxShift);
  double sv=corr->amplitudeAt(s);
  s-=(corr->nSamples()-1)/2;
  App::log(tr("Best correlation at %1 (value=%2)\n").arg(s).arg(sv) );
  if(sv<0.5) {
    if(isDebugMode()) {
      exportDebugSignals(newVector, mainVector, corr);
    }
    ok=false;
  } else {
    ok=true;
  }
  delete newVector;
  delete mainVector;
  delete corr;
  return s;
}

DoubleSignal * RowImageMerger::imageVector(const QImage& im, int maxWidth)
{
  TRACE;
  const qint32 * m=reinterpret_cast<const qint32 *>(im.constBits());
  int w=im.width();
  int h=im.height();
  if(w>maxWidth) {
    w=maxWidth;
  }
  DoubleSignal * v=new DoubleSignal(w);
  v->setSamplingPeriod(1.0); // Useless here, just to avoid errors in GeopsyCore
  LOCK_SAMPLES(double, vSamples, v)
    for(int i=0; i<w; i++) {
      double sum=0.0;
      for(int j=0; j<h; j+=im.width()) {
        sum+=m[j];
      }
      vSamples[i]=sum/h;
      m++;
    }
  UNLOCK_SAMPLES(v)
  DoubleSignal * vP=preprocess(v);
  delete v;
  return vP;
}
