/*!
 * \file galileo_e5a_noncoherent_iq_acquisition_caf.h
 * \brief Adapts a PCPS acquisition block to an AcquisitionInterface for
 *  Galileo E5a data and pilot Signals
  * \author Marc Sales, 2014. marcsales92(at)gmail.com
 * \based on work from:
 * 		<ul>
 *          <li> Javier Arribas, 2011. jarribas(at)cttc.es
 *          <li> Luis Esteve, 2012. luis(at)epsilon-formacion.com
 *          <li> Marc Molina, 2013. marc.molina.pena@gmail.com
 *          </ul>
 *
 * -------------------------------------------------------------------------
 *
 * Copyright (C) 2010-2015  (see AUTHORS file for a list of contributors)
 *
 * GNSS-SDR is a software defined Global Navigation
 *          Satellite Systems receiver
 *
 * This file is part of GNSS-SDR.
 *
 * GNSS-SDR 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.
 *
 * GNSS-SDR 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 GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
 *
 * -------------------------------------------------------------------------
 */

#ifndef GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_
#define GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_

#include <string>
#include <gnuradio/msg_queue.h>
#include <gnuradio/blocks/stream_to_vector.h>
#include "gnss_synchro.h"
#include "acquisition_interface.h"
#include "galileo_e5a_noncoherent_iq_acquisition_caf_cc.h"

class ConfigurationInterface;

class GalileoE5aNoncoherentIQAcquisitionCaf: public AcquisitionInterface
{
public:
    GalileoE5aNoncoherentIQAcquisitionCaf(ConfigurationInterface* configuration,
            std::string role, unsigned int in_streams,
            unsigned int out_streams, boost::shared_ptr<gr::msg_queue> queue);

	virtual ~GalileoE5aNoncoherentIQAcquisitionCaf();

	std::string role()
	    {
	        return role_;
	    }
	/*!
	 * \brief Returns "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF"
	 */
	 std::string implementation()
	    {
	        return "Galileo_E5a_Noncoherent_IQ_Acquisition_CAF";
	    }
	 size_t item_size()
	    {
	        return item_size_;
	    }

	 void connect(gr::top_block_sptr top_block);
	 void disconnect(gr::top_block_sptr top_block);
	 gr::basic_block_sptr get_left_block();
	 gr::basic_block_sptr get_right_block();

	 /*!
	  * \brief Set acquisition/tracking common Gnss_Synchro object pointer
	  * to efficiently exchange synchronization data between acquisition and
	  *  tracking blocks
	  */
	 void set_gnss_synchro(Gnss_Synchro* p_gnss_synchro);

	 /*!
	  * \brief Set acquisition channel unique ID
	  */
	 void set_channel(unsigned int channel);

	 /*!
	  * \brief Set statistics threshold of PCPS algorithm
	  */
	 void set_threshold(float threshold);

	 /*!
	  * \brief Set maximum Doppler off grid search
	  */
	 void set_doppler_max(unsigned int doppler_max);

	 /*!
	  * \brief Set Doppler steps for the grid search
	  */
	 void set_doppler_step(unsigned int doppler_step);

	 /*!
	  * \brief Set tracking channel internal queue
	  */
	 void set_channel_queue(concurrent_queue<int> *channel_internal_queue);

	 /*!
	  * \brief Initializes acquisition algorithm.
	  */
	 void init();

	 /*!
	  * \brief Sets local Galileo E5a code for PCPS acquisition algorithm.
	  */
	 void set_local_code();

	 /*!
	  * \brief Returns the maximum peak of grid search
	  */
	 signed int mag();

	 /*!
	  * \brief Restart acquisition algorithm
	  */
	 void reset();

     /*!
      * \brief If set to 1, ensures that acquisition starts at the
      * first available sample.
      * \param state - int=1 forces start of acquisition
      */
	 void set_state(int state);

private:
	 ConfigurationInterface* configuration_;
	 galileo_e5a_noncoherentIQ_acquisition_caf_cc_sptr acquisition_cc_;
	 gr::blocks::stream_to_vector::sptr stream_to_vector_;
	 size_t item_size_;
	 std::string item_type_;
	 unsigned int vector_length_;
	 unsigned int code_length_;
	 bool bit_transition_flag_;
	 unsigned int channel_;
	 float threshold_;
	 unsigned int doppler_max_;
	 unsigned int doppler_step_;
	 unsigned int shift_resolution_;
	 unsigned int sampled_ms_;
	 unsigned int max_dwells_;
	 long fs_in_;
	 long if_;
	 bool dump_;
	 std::string dump_filename_;
	 int Zero_padding;
	 int CAF_window_hz_;
	 std::complex<float> * codeI_;
	 std::complex<float> * codeQ_;
	 bool both_signal_components;
	 Gnss_Synchro * gnss_synchro_;
	 std::string role_;
	 unsigned int in_streams_;
	 unsigned int out_streams_;
	 boost::shared_ptr<gr::msg_queue> queue_;
	 concurrent_queue<int> *channel_internal_queue_;
	 float calculate_threshold(float pfa);
};
#endif /* GALILEO_E5A_NONCOHERENT_IQ_ACQUISITION_CAF_H_ */
