/*
 * ControlObject.h
 *
 */

#ifndef HA_CLIENTCONTROLOBJECT_H_
#define HA_CLIENTCONTROLOBJECT_H_

#include "HA_config.h"
#ifdef ENABLE_JNI_FOR_ANDROID
#include <jni.h>
#endif // ENABLE_JNI_FOR_ANDROID
#include <pthread.h>

#include "HA_Object.h"

namespace HARKAndroid {

class ClientControlObject : public HAObject {

private:

	static const int Invalidfd = -1;

	bool valid;

	::pthread_mutex_t Stop_mutex;
	bool Stopped;

	::pthread_mutex_t Start_Stop_mutex;

	int init();

public:
	ClientControlObject(const ClientControlObject &);
	ClientControlObject();
	virtual ~ClientControlObject();
	ClientControlObject & operator = (const ClientControlObject &);

	bool isValid() const {return(valid);}

	int SetStop();
	int ResetStop();
	bool isStop();

#ifdef ENABLE_JNI_FOR_ANDROID
	int Create(JNIEnv *env, jobject thiz);
	int Start(JNIEnv *env, jobject thiz);
	int Stop(JNIEnv *env, jobject thiz);
#else // ENABLE_JNI_FOR_ANDROID
	int Create();
	int Start();
	int Stop();
#endif // ENABLE_JNI_FOR_ANDROID

	int ConnectPortA();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortA(const int port, jdouble *array) const; // for compatibility
	int RecvFromPortA(const int port, jint *channel, jint *length, jint *advance, jdouble *mic_acoustics) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortA(const int port, float *array) const; // for compatibility
	int RecvFromPortA(const int port, int *channel, int *length, int *advance, float *mic_acoustics) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortA(const int port);

	int ConnectPortB();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortB(const int port, jdouble *array) const; // for compatibility
	int RecvFromPortB(const int port, jint *channel, jint *length, jint *advance, jint *fft_length, jdouble *mic_spectra) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortB(const int port, float *array) const; // for compatibility
	int RecvFromPortB(const int port, int *channel, int *length, int *advance, int *fft_length, float *mic_spectra) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortB(const int port);

	int ConnectPortC();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortC(const int port, jint *array_num, jdouble *array) const;
	int RecvFromPortC(const int port, jint *source_count, jint *source_ids, jdouble *source_coordinates) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortC(const int port, int *array_num, float *array) const;
	int RecvFromPortC(const int port, int *source_count, int *source_ids, float *source_coordinates) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortC(const int port);

	int ConnectPortD();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortD(const int port, jdouble *array) const; // for compatibility
	int RecvFromPortD(const int port, jint *source_count, jint *fft_length, jint *source_ids, jdouble *source_coordinates, jdouble *source_spectra) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortD(const int port, float *array) const; // for compatibility
	int RecvFromPortD(const int port, int *source_count, int *fft_length, int *source_ids, float *source_coordinates, float *source_spectra) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortD(const int port);

	int ConnectPortE();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortE(const int port, jdouble *array) const; // for compatibility
	int RecvFromPortE(const int port, jint *source_count, jint *banks, jint *source_ids, jdouble *source_coordinates, jdouble *source_features) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortE(const int port, float *array) const; // for compatibility
	int RecvFromPortE(const int port, int *source_count, int *banks, int *source_ids, float *source_coordinates, float *source_features) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortE(const int port);

	int ConnectPortF();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortF(const int port, jdouble *array) const; // for compatibility
	int RecvFromPortF(const int port, jint *source_count, jint *advance, jint *source_ids, jdouble *source_coordinates, jdouble *source_acoustics) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortF(const int port, float *array) const; // for compatibility
	int RecvFromPortF(const int port, int *source_count, int *advance, int *source_ids, float *source_coordinates, float *source_acoustics) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortF(const int port);

	int ConnectPortFwithSrc();
#ifdef ENABLE_JNI_FOR_ANDROID
	int RecvFromPortFwithSrc(const int port, jint *array_src, jdouble *array) const; // for compatibility
	int RecvFromPortFwithSrc(const int port, jint *source_count, jint *advance, jint *source_ids, jdouble *source_coordinates, jdouble *source_acoustics) const;
#else // ENABLE_JNI_FOR_ANDROID
	int RecvFromPortFwithSrc(const int port, int *array_src, float *array) const; // for compatibility
	int RecvFromPortFwithSrc(const int port, int *source_count, int *advance, int *source_ids, float *source_coordinates, float *source_acoustics) const;
#endif // ENABLE_JNI_FOR_ANDROID
	int ClosePortFwithSrc(const int port);
};

extern HARKAndroid::ClientControlObject *HARKClientControl;

}

#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

extern HARKAndroid::ClientControlObject *HARKClientControl;

#endif /* HA_CLIENTCONTROLOBJECT_H_ */
