/* -*- c++ -*- */
/*
 * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
 *           http://gqrx.dk/
 *
 * Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
 *
 * Gqrx 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, or (at your option)
 * any later version.
 *
 * Gqrx 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 Gqrx; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */
#ifndef SPECWIDGET_H
#define SPECWIDGET_H

#include <QWidget>
#include <QVariant>
#include <fftw3.h>
#include <vector>
#include <QStandardItemModel>
#include "uhd_device.h"
#include "stdout_watcher.h"
namespace Ui {
	class specWidget;
}

class specWidget : public QWidget, public uhd_device
{
	Q_OBJECT
public:
	explicit specWidget(QWidget *parent = nullptr);
	~specWidget();
	void setRxRate(double rate);
protected:
	void timerEvent(QTimerEvent * e) override;
public slots:
	void slot_newDemodFreq(qint64 freq, qint64 delta); /* delta is the offset from the center */
	void slot_msg(QByteArray , bool);
public:
	void appendWavComplex(const double (* pWav)[2], const int count, double voltage_ref = 16384);
public:
	void setCenterFreq(quint64 f);	
private slots:
	void slot_YAxisRangeChanged(double minv, double maxv);
	void on_comboBox_fftSize_activated(int index);
	void on_doubleSpinBox_center_valueChanged(double arg1);
	void on_spinBox_gain_valueChanged(int arg1);
	void on_doubleSpinBox_range_max_valueChanged(double arg1);
	void on_doubleSpinBox_range_min_valueChanged(double arg1);
	void on_comboBox_atn_currentIndexChanged(const QString &arg1);
	void on_spinBox_chan_valueChanged(int arg1);
	void on_toolButton_br_clicked();
	void on_checkBox_save_stateChanged(int arg1);
	void on_spinBox_bw_valueChanged(int arg1);
	void on_toolButton_br_play_clicked();
	void on_checkBox_tx_stateChanged(int arg1);
	void on_doubleSpinBox_center_tx_valueChanged(double arg1);
	void on_spinBox_chan_tx_valueChanged(int arg1);
	void on_spinBox_gain_tx_valueChanged(int arg1);
	void on_spinBox_bw_tx_valueChanged(int arg1);
	void on_pushButton_connect_toggled(bool checked);
	void on_checkBox_rx_toggled(bool checked);
	void on_doubleSpinBox_spr_tx_valueChanged(double arg1);
	void on_checkBox_tx_toggled(bool checked);
	void on_checkBox_rxagc_toggled(bool checked);
	void on_spinBox_ui_percent_top_valueChanged(int arg1);

private:
	void loadSettings();
	void saveSettings();
	void update_Info();
private:
	void enumDevices();
	void connect_usrp();
	void disconnect_usrp();
	void do_rx(bool start);
	void do_tx(bool start);
private:
	void initFFTW();
	void freeFFTW();
	void initRx();
	void initTx();
	void freeRx();
	void freeTx();
private:
	Ui::specWidget *ui = nullptr;
	QStandardItemModel * m_pDevMod = nullptr;
	QStandardItemModel * m_attenMod = nullptr;
	QStandardItemModel * m_attenTxMod = nullptr;
	//Gains
	QStandardItemModel * m_pModRXGain = nullptr;
	QStandardItemModel * m_pModTXGain = nullptr;
private:
	//FFT
	int	m_nFFTSize = 16384;
	std::vector<double> m_dHammingWnd;
	std::vector<double> m_dFFTAmp;
	fftw_plan m_pFFTPlan = nullptr;
	fftw_complex * m_pFFTIn = nullptr;
	fftw_complex * m_pFFTOut = nullptr;
	int m_nTimerID = -1;
	int m_nCurrentCenter = 0;
	double m_dManuAdd = 0;
	//Thread
	uhd_io_thread * m_rxth = nullptr;
	uhd_io_thread * m_saveth = nullptr;
	uhd_io_thread * m_txth = nullptr;
	uhd_io_thread * m_readth = nullptr;
	unsigned long long save_count;
	unsigned long long read_count;
	std::atomic<bool> m_bSaveToFile;
	std::atomic<bool> m_bPlayFromFile;
	std::atomic<bool> m_dataproduce_ok;
	QString m_strFolder;
	QString m_strFolderPlay;
	//stdout reader
	stdout_watcher * watcher = nullptr;
};

#endif // SPECWIDGET_H
