/***************************************************************************
**
**  This file is part of ArrayCore.
**
**  ArrayCore 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.
**
**  ArrayCore 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: 2004-06-21
**  Copyright: 2004-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "GaussianFrequencyBand.h"
#include "ArrayStationSignals.h"

namespace ArrayCore {

  /*!
    \class ArrayStationSignals ArrayStationSignals.h
    \brief Signal station for FK processing

    A ArrayStationSignals can deselected for a temporary exclusion from processing.
    Currently used only by linear arrays (near-field effect reduction)
  */

  /*!
    Construct a selected station
  */
  ArrayStationSignals::ArrayStationSignals(const StationSignals * originalSignals)
    : StationProcessSignals(originalSignals)
  {
    TRACE;
  }

  ArrayStationSignals::~ArrayStationSignals()
  {
    TRACE;
  }

//#define PROCESS_TIMING

  /*!
    Set processed signals for all components
  */
  bool ArrayStationSignals::setSpectrumValue(const TimeRange &tw, const AbstractParameters *param, const FourierPlan &plan)
  {
#ifdef PROCESS_TIMING
    QTime chrono;
    int ts, tt, tft, tts=0, ttt=0, ttft=0;
#endif
    int nComp=nComponents();
    for(int iComp=0; iComp<nComp; iComp++) {
      if(!copyOriginalSignal(iComp, tw)) {
        return false;
      }
#ifdef PROCESS_TIMING
      chrono.start();
#endif
      DoubleSignal *& sig=processed(iComp);
      //printf("Effective number of samples in window %i\n", sig->nSamples());
      sig->subtractValue();
#ifdef PROCESS_TIMING
      ts=chrono.elapsed();
#endif
      const ArrayParameters * arrayParam=static_cast<const ArrayParameters *>(param);
      // By default, set a 10% taper in time domain
      sig->taper(arrayParam->taper());
#ifdef PROCESS_TIMING
        tt=chrono.elapsed();
#endif

      // Enlarge signal for frequency oversampling
      if(arrayParam->oversamplingFactor()>1.0) {
        DoubleSignal * sigLarge=new DoubleSignal(static_cast<int>(sig->nSamples()*arrayParam->oversamplingFactor()));
        sigLarge->setSamplingPeriod(sig->samplingPeriod());
        sigLarge->setValue(0.0);
        sigLarge->copySamplesFrom(sig, 0.0, 0.0, sig->duration());
        delete sig;
        sig=sigLarge;
      }

      // Switch to frequency domain
#ifndef COMPATIBILITY_2_5_0
      if(arrayParam->frequencyBandwidth()==0.0) {
        _spectrumValue[iComp]=sig->discreteFourierTransform(plan);
      } else {
#endif
        sig->fastFourierTransform(DoubleSignal::Spectrum);
#ifndef COMPATIBILITY_2_5_0
      }
#endif
#ifdef PROCESS_TIMING
      tft=chrono.elapsed();
      tts+=ts;
      ttt+=tt-ts;
      ttft+=tft-tt;
#endif

      /*int nSamples=sig->nSamples();
      CONST_LOCK_SAMPLES(double, samples, sig)
      for(int i=0; i<nSamples/2; i++) {
        printf("%lg %lg\n",(double)i*sig->duration(),
                sig->amplitude(samples, i));
      }
      UNLOCK_SAMPLES(this)*/
    }
#ifdef PROCESS_TIMING
    App::log(3, tr("Spectrum computation (subtract %1 ms,  taper %2 ms, dtft %3 ms)\n")
              .arg(tts).arg(ttt).arg(ttft));
#endif
    return true;
  }

} // namespace ArrayCore
