#ifndef GIMBALDATA_H
#define GIMBALDATA_H

#include <QThread>
#include <stdint.h>
#include "project.h"
#include "tuneState.h"
#include "comm.h"
#include "db.h"

//	----------------------------------------------------------------------------
//	global functions
//	----------------------------------------------------------------------------

	extern void setModeX(int modeX);

//	----------------------------------------------------------------------------
//	globals
//	----------------------------------------------------------------------------


//	extern steering_t steering;
	extern	controls_t controls;

	extern unsigned int camRecordReq;
	extern unsigned int shutdownRedReq;
	extern unsigned int shutdownStandbyReq;
	extern unsigned int shutdownPiReq;
	extern unsigned int targetReq;
	extern unsigned int altReq;
	extern unsigned int steerAltReq;

//	----------------------------------------------------------------------------
//	edit keys
//	----------------------------------------------------------------------------

enum{
		key_pGain = 1,
		key_iGain,
		key_dGain,
		key_limit,
		key_kT,
		key_kC,
		key_kP,
		key_kFF,
		key_kTach,
		key_kI,
		key_kILim,
		key_fType,
		key_fFreq,
		key_fQ,
		key_plotRaw,
		key_plotVar,
		key_plotAxis,
		key_enable,
		key_remote,
		key_backdrive,
		key_sinA,
		key_desiredPos,
		key_sinF,
		key_desiredRate,
		key_geoKP,
		key_geoKP2,
		key_geoKI,
		key_geoKD,
		key_geoKILim,
		key_geoKMys2,
		key_posKP,
		key_posKD,
		key_posKLim,
};

//	----------------------------------------------------------------------------
//	gimbalData
//	----------------------------------------------------------------------------

class gimbalData : public QThread
{
	Q_OBJECT

public:

	explicit gimbalData(QObject *parent = 0);
	~gimbalData();
//private:
	void run();
	void Sleep(int millisec);

public:
	state_t state;
	bwRes_t bwRes;
	bwPar_t bwPar;
	navToGim_t masterStatus;
	tuneState gimTun;
	tuneState refTun;
//	pidPar_t pidP[NiAXES];
//	filterPar_t filtP[NiAXES][NiFILT];
//	outerPar_t outerP[NoAXES];
	lensCommand_t lensCommand[NLENS];

public:
	int idTbl;
	int utilityTbl;
	int controlsTbl;
	int steeringTbl;
	int steeringAxisTbl;
	int controlsAxisTbl;
	int stateGyroTbl;
	int stateCommTbl;
	int stateNavTbl;
	int stateGeoTbl;
	int stateInputTbl;
	int stateAxisTbl;
	int stateOuterCmd;
	int stateOuterFb;
	int stateOdinTbl;
	int navboxTbl;
	int masterStatusTbl;
	int bwParTbl;
	int bwResTbl;
	int pidPTbl;
	int filtP0Tbl;
	int filtP1Tbl;
	int filtP2Tbl;
	int outerPTbl;
	int geoPTbl;
	int posPTbl;
	int lensPTbl;
	int gimReadoutsTbl;
	int operControlsTbl;
	int operSettingsTbl;
	int joystickTbl;
	int consInputTbl;
	int lensFeedbackTbl;
	int refPidPTbl;
	int refFiltP0Tbl;
	int refFiltP1Tbl;
	int refFiltP2Tbl;
	int refOuterPTbl;
	int refGeoPTbl;
	int refPosPTbl;
	int refLensPTbl;
	int initRef;

public:
	int cmdAutonull;
	int cmdGeo;
	float jscmd[3];
	int jsbutton[2];

public:
	float imuBuf[IMU_BUF_COUNT];
	float imuBuf2[IMU_BUF_COUNT];
	uint32_t imuBufIndex;
	uint32_t logAddress;

public:
	char guiIpAddress[250];
	char guiComPort[250];
	int guiConnect;
	int guiReconnect;
	int guiIpPort;
	int guiBaud;
	int connected;
	int connectedX;
	int hwmode;
	int gimbalPresent;
	db dbase;
	bool quit;
	int controlsReady;

private:
	QMutex mutex;
	QWaitCondition cond;
	comm *gim;
	comm *cons;
	char editVString[40];
	int editKey;
	int editAxis;
	int editFilt;
	int editPar;
	int editType;

signals:
	void errorx(int type, int socketError, const QString &message);
	void connectedState(int clr, QString lbl);
	void lastTable();
	void newTableData(int cmd);
	void newImuData();
	void newTuneData();

//	void newTable(int device,int module,int table);
//	void newDevice(int device, int found);
//	void dataSent();

public slots:
	void guiConnectReq(int newstate);
	void sendError(int socketError,const QString &message);
	void sendCommError(int socketError,const QString &message);
//	void rxDbtNotifySlot(int device,int module,int table,int len);
//	void selectTableS(const QStringList &list);
//	void selectTable(QString s);
//	void saveTable(QString s);
	void stop();
	void newMsg(unsigned char *message,int numread);

public:
	void pollGimbalRx();
	void pollGimbalTx();
	void steering();
	void steeringBits();
	void parseGyro(unsigned char *m,int len);
	int parseMsgX(unsigned char *m,int len);
	int commandCheck(msgHeader_t *h, uint32_t *len, uint32_t maxlen);
	void parseBwRes(unsigned char *m,int len);
	void parseBwPar(unsigned char *m,int len);
	void parseControls(unsigned char *m,int len);
	void parseState(unsigned char *m,int len);
	void parseLog(unsigned char *m,int len);
	void parseTunings(unsigned char *m,int len);
	void parseConsInput(unsigned char *m, int len);
	void parseMasterStatus(unsigned char *m, int len);
	int different(void *a,void *b,int len);
	void connectx(int newstate,int reconnect);
	void settings(const char *reqIpAddress,const char *reqComPort,int reqIpPort,int reqBaud);
	int getMessage();
	void geo();

	void setStandby(int standby);
	void setGeo(int geo);
	void setAutonull(int autonull);
	void setHsPlot(int plot);
	void setHsAxis(int axis);
	void setConnect(int val);
	void setStep(int axis, int step, float amp);
	void startBode();
	void sendPidPar(int axis,pidPar_t *pPidPar);
	void sendOuterPar(int axis,outerPar_t *pOuterPar);
	void sendFilterPar(int axis,int ifilt,filterPar_t *pFilterPar);
	void sendTunings(tunings_t *t);
	void sendCommand(command_t *c);
	void initDatabase();
	void edit(int key,int axis,int filter,const char *vstring);
	void editI(int key, int axis, int filter, int value);
	void sendEdit();
	void sendMsg(msgHeader_t *message);
	void sendSteering(steering_t *s);
	void loadTunings(tunings_t *t);
	void newJoystick(steering_t *s,int button1,int button2,int buttons);

//	int cmdToTable(int cmd,int table);
//	int cmdToTable(int cmd);

//	extern int readGimbal();
//	extern int readGimbalM();
//	extern void	setFilters(int axis);
//	extern void	setGains();
//	extern void	unTrip();
//	extern void savePID();
//	extern void startFFT();
//	extern void stopFFT();
//	extern void getLogAddress();
//	extern void saveFilters(int axis);
//	extern void addFilter(int axis, int filter);
//	extern void deleteFilter(int axis, int filter);
//	extern void getLog(uint32_t address,uint16_t count);
//	extern void doFFT(float samples[IMU_BUF_COUNT],float results[IMU_BUF_COUNT]);
//	extern void startStep(int axis, int rate, int delay);
//	extern void reboot();

};

int pidType(int mode);

#endif // GIMBALDATA_H
