/*!
  @mainpage

  @section 概要

  libharkio3 は、HARK の伝達関数や音源定位結果など、 HARK に関するファイルの I/O に関する API 群である。
　　関連するファイルは下記のとおり
  @li Matrix  伝達関数、 FFT したファイルなどのを表すバイナリファイル。
  @li XML     音源定位結果、TSP 信号測定方向など、位置の集合を表すテキストファイル。
  @li Zip     伝達関数など、複数の Matrix, XML が混在するファイル。
  @li wav    音声ファイルなど。標準の wav フォーマットを使用。

*/



/*!
* @file
*
* @author Takeshi Mizumoto
* @version 0.1
* @brief  全関数とデータ構造はこのファイルに定義されている。
*/
#ifndef __LIBHARKIO3__
#define __LIBHARKIO3__


#include <stdio.h>
#include <zip.h>
#include <complex.h>
#undef I
#undef complex

/*!
 *  @brief 浮動小数点が等しいか否かの閾値
 */
#define HARK_EPS 0.00001

/*! @def HARKIO_VER
 *  @brief libharkio3 の内部バージョン
 */
#define HARKIO_VER "1.3"

/*! @def HARKIO_TAG
 *  @brief libharkio3 現バージョンで作成したファイルに埋め込まれるタグ
 */
#define HARKIO_TAG "HARK1.3"


/*! @enum Coordinate
 *  @brief harkio_Positions で座標軸を表す。
 */
enum Coordinate          {
    Polar, /*!< 極座標系 */
    Cartesian /*!< 直交座標系 */
};

/*! @enum NeighborAlgorithm
 *  @brief harkio_Neighbors で、Position (伝達関数測定位置など) が隣接しているか否かを判定するアルゴリズムを表す。
 */
enum NeighborAlgorithm   {
    Undefined,      /*!< 未設定。デフォルト値 */
    NearestNeighbor /*!< Nearest Neighbor 法。　閾値より近い複数個の Position が隣接していると判定する */
};

/*! @enum harkio_Log_logLevel
 *  @brief harkio_Log で、メッセージのログがどのレベルかを表す。
 */
enum harkio_Log_logLevel {
    harkio_Log_Error,    /*!< 復帰不能なエラーメッセージ */
    harkio_Log_Warning,  /*!< 復帰可能な警告メッセージ */
    harkio_Log_Info,     /*!< 情報 */
    harkio_Log_Debug,    /*!< デバッグ用メッセージ */
    harkio_Log_Trace     /*!< 詳細デバッグ情報(関数トレース) */
};

/*! @enum harkio_TFType
 *  @brief 伝達関数が定位用か分離用かを表す。(内部用)
 */
enum harkio_TFType        { loctf , septf };

/*! @enum Calculate
 *  @brief 複素数計算のラベル (内部用)
 */
// enum Calculate           { Calc_Add , Calc_Sub , Calc_Multi , Calc_Div };

/*! @enum harkio_DataType
 *  @brief harkio_Matrix の型を表す
 */
enum harkio_DataType            { harkio_DataType_INT32 , harkio_DataType_FLOAT32 , harkio_DataType_COMPLEX };
enum UseTagType          { NON_TAG , USE_TAG , ID_TAG  };

/*! @enum InternalAllocFlag
 *  @brief 保持メモリの割当て状態を管理するフラグ（内部用）
 */
enum InternalAllocFlag  { NO_INTERNAL_ALLOC, INTERNAL_ALLOC };


//#ifdef __unix__
// #define COMPLEX_TYPE float _Complex
typedef float _Complex COMPLEX_TYPE;
//#else
//	#define COMPLEX_TYPE complex<float>
//#endif


/*! @struct harkio_Matrix_maps
 *  @brief harkio_Matrix_map で要素ごとの処理を行うための関数ポインタ群。
 */
typedef struct {
    int (*imap)(int);                      /*!< 整数型のときの関数ポインタ */
    float(*fmap)(float);                   /*!< 浮動小数点型のときの関数ポインタ */
    COMPLEX_TYPE(*cmap)(COMPLEX_TYPE);   /*!< 複素数型のときの関数ポインタ */
} harkio_Matrix_maps;

typedef int (*harkio_Matrix_calcfuncInt32)(int, int);
typedef float(*harkio_Matrix_calcfuncFloat32)(float, float);
typedef COMPLEX_TYPE(*harkio_Matrix_calcfuncComplex)(COMPLEX_TYPE, COMPLEX_TYPE);

/*! @def HARK_DIM
 *  @brief harkio_Matrix の次元。 2 (=行列) のみ。
 */
#define HARK_DIM   2            //dimention

/*! @def HARKIO_LOGLEVEL_ENV_NAME
 *  @brief ログレベルを環境変数で設定するときの変数名
 *  @details 値は error|e,warning|w,info|i,debug|d が設定可能
 */
#define HARKIO_LOGLEVEL_ENV_NAME "HARKIO_LOG_LEVEL"

/*! @def harkio_Log_setLevel
 *  @brief ログレベルを設定
 */
#define harkio_Log_setLevel(PrintLevel)      harkio_Log_printf_( (enum harkio_Log_logLevel)-1, "", PrintLevel, __func__, __LINE__)

/*! @def harkio_Log_printf
 *  @brief ログを出力するマクロ
 */
#define harkio_Log_printf(LogLevel, message, ...) harkio_Log_printf_(LogLevel, message, 0, __func__, __LINE__, ##__VA_ARGS__)

/*! @def MSG_LEN
 *  @brief 文字列生成時のバッファの長さを表す。
 */
#define MSG_LEN    4192


/*! @def DEPRECATED
 *  @brief deprecated関数定義用.ソース内で関数を使用している場合に,コンパイル時警告を出す属性を設定.
 */
// 引数付きdeprecated()は環境によって非対応のため修正(r7833). Windowsでの動作未確認.
#ifdef _MSC_VER
#define DEPRECATED(X) __declspec(deprecated(X))
#else
#define DEPRECATED(X) __attribute__((deprecated))
#endif

/*! @union multipleType
 *  @brief harkio_Matrix内部用。
 */
typedef union {
    int           *intdata;     /*!< 型が int の場合に利用されるメンバ*/
    float         *floatdata;   /*!< 型が float の場合に利用されるメンバ*/
    COMPLEX_TYPE *complexdata;  /*!< 型が Complex の場合に利用されるメンバ*/
} multipleType;

/*! @struct harkio_Matrix
 *  @brief 伝達関数などの、行列を表す構造体。
 */
typedef struct {
    char tag[32];        /*!< 保存時に埋め込まれる */
    char type[32];       /*!< データ型。 */
    int  dim;            /*!< 次元 */
    int  rows;           /*!< 行サイズ */
    int  cols;           /*!< 列サイズ */
    multipleType data;   /*!< データ自体 */
} harkio_Matrix;

/*! @struct harkio_Position
 *  @brief 位置を表す構造体。
 */
typedef struct {
    int   id;             /*!< 位置の ID  */
    enum  Coordinate sys; /*!< メンバ coord の座標系 */
    float *coord;         /*!< 座標 */
    char  *path;          /*!< この位置に対応するファイルのパス。TSP録音ファイルなど */
    harkio_Matrix *data;  /*!< この位置に対応する行列データ。伝達関数など */
    int   channelsUse;    /*!< この位置に対応するチャネルセット情報 (numChannels, channels) が有効かどうか。0 は使用しない。 1は使用する。*/
    int   numChannels;    /*!< この位置に対応するチャネルの数 */
    int  *channels;       /*!< この位置に対応するチャネルのリスト */
} harkio_Position;

/*! @struct harkio_Positions
 *  @brief 位置の集合を表す構造体。
 */
typedef struct {
    int size;               /*!< 構造体が保持する pos の長さ */
    int frame;              /*!< この構造体が対応するフレーム番号 */
    char *type;             /*!< この構造体のタイプを表す文字列 */
    harkio_Position **pos;  /*!< この構造体が保持する位置の配列 */
    enum InternalAllocFlag allocflag; /*!< posのメモリ管理方法を表すフラグ */
} harkio_Positions;

/*! @struct harkio_Config
 *  @brief 伝達関数の計測条件などの一般的な情報を表す構造体
 */
typedef struct {
    char *comment;          /*!< コメントに使用する任意の文字列  */
    int synchronousAverage; /*!< TSPの同期加算回数      */
    char *TSPpath;          /*!< TSPの元信号へのパス  */
    int TSPoffset;          /*!< TSPが開始するまでのオフセット [サンプル]  */
    int TSPLength;          /*!< 収録するTSP信号の長さ [サンプル]  */
    int peakSearchFrom;     /*!< インパルス応答のピーク検索範囲の開始位置  */
    int peakSearchTo;       /*!< インパルス応答のピーク検索範囲の終了位置  */
    int nfft;               /*!< FFT長  */
    int samplingRate;       /*!< 音響信号ファイルのサンプリング周波数  */
    int signalMax;          /*!< 音響信号ファイルの振幅の最大値  */
} harkio_Config;

/*! @struct harkio_Neighbors
 *  @brief harkio_Positions の隣接関係を表す構造体。自分を含む。s
 *  @details 隣接関係を表現したい Position の総数が size に入る。
 　　        ids はそれらの Position の id を表している。
             numNeighbors は、idごとに、何個の隣接 Position が存在するかを表し、
             neighbors はその id が何かを表している。

             例
             id が [0, 1, 2, 3] のposes について、隣接関係が
             0 --> 0, 1
             1 --> 0, 1, 2
             2 --> 1, 2
             3 --> 3 (隣接なし)
             の場合、
             size = 4                     ([0, 1, 2, 3]だから)
             ids = [0, 1, 2, 3]           (実際の id たち)
             numNeighbors = [2, 3, 2, 1]  (隣接個数)
             neighbors = [[0, 1], [0, 1, 2], [1, 2], [3]]
             という値がはいる。
 */
typedef struct {
    int size;                       /*!< 隣接関係を表したいPositionの数 */
    int *ids;                       /*!< 隣接関係を表したいPositionのidのリスト */
    int *numNeighbors;              /*!< Positionごとの、隣接するPositionの個数 */
    int **neighbors;                /*!< Positionごとの、隣接するPositionのidのリスト */
    harkio_Positions *poses;        /*!< 隣接関係が表す Posisition のリスト   */
    enum NeighborAlgorithm alg;     /*!< 隣接関係を求めるアルゴリズム */
} harkio_Neighbors;

/*! @struct harkio_XML
 *  @brief 伝達関数ファイルの XML (位置、隣接関係、設定) の読み書きのための構造体
 */
typedef struct {
    harkio_Positions *poses;    /*!< Positions タグに対応するメンバ */
    harkio_Neighbors *nbrs;     /*!< Neighbors タグに対応するメンバ */
    harkio_Config *cfg;         /*!< Config タグに対応するメンバ */
} harkio_XML;

/*! @struct harkio_TransferFunction
 *  @brief 伝達関数そのものを表す構造体
 */
typedef struct {
    struct zip *handle;         /*!< 伝達関数ファイルのハンドル */
    harkio_Positions *poses;    /*!< TSP測定位置を表すメンバ */
    harkio_Positions *mics;     /*!< マイク位置を表すメンバ */
    harkio_Config *cfg;         /*!< 一般設定を表すメンバ */
    harkio_Neighbors *nbrs;     /*!< TSP測定位置の近接関係を表すメンバ */
    harkio_Matrix **loctfs;     /*!< 定位用伝達関数を表すメンバ */
    harkio_Matrix **septfs;     /*!< 分離用伝達関数を表すメンバ */
    int internal_locsize;       /*!< loctfsのメモリ管理状況を表すメンバ 0のとき関数外管理 */
    int internal_sepsize;       /*!< septfsのメモリ管理状況を表すメンバ 0のとき関数外管理 */
} harkio_TransferFunction;



#if defined(__cplusplus)
extern "C" {
#endif

/******
  API declaration
 ******/
// Matrix
harkio_Matrix* harkio_Matrix_new(char *type, int rows, int cols);
harkio_Matrix* harkio_Matrix_eye(char *type, int size);
harkio_Matrix* harkio_Matrix_zeros(char *type, int rows, int cols);
harkio_Matrix* harkio_Matrix_vstack(harkio_Matrix* src, harkio_Matrix* stack);
harkio_Matrix* harkio_Matrix_ones(char *type, int rows, int cols);
harkio_Matrix* harkio_Matrix_fromFile(char *path);
harkio_Matrix* harkio_Matrix_fromZip(struct zip *handle, char *path);
harkio_Matrix* harkio_Matrix_copy(harkio_Matrix *m);

void harkio_Matrix_delete(harkio_Matrix **m);
void harkio_Matrix_print(harkio_Matrix *m);
char* harkio_Matrix_printBuffer(harkio_Matrix *m);
int harkio_Matrix_write(harkio_Matrix *m, char *path);
char* harkio_Matrix_writeBuffer(harkio_Matrix *m, size_t *size);
size_t harkio_Matrix_size(harkio_Matrix *m, int *size);

harkio_Matrix* harkio_Matrix_add(harkio_Matrix *a, harkio_Matrix *b);
harkio_Matrix* harkio_Matrix_sub(harkio_Matrix *a, harkio_Matrix *b);
harkio_Matrix* harkio_Matrix_mul(harkio_Matrix *a, harkio_Matrix *b);
harkio_Matrix* harkio_Matrix_emul(harkio_Matrix *a, harkio_Matrix *b);
harkio_Matrix* harkio_Matrix_sumRow(harkio_Matrix *matrix);
harkio_Matrix* harkio_Matrix_sumCol(harkio_Matrix *matrix);
harkio_Matrix* harkio_Matrix_sumAll(harkio_Matrix *matrix);

harkio_Matrix* harkio_Matrix_sum(harkio_Matrix **matrix , int num);

harkio_Matrix* harkio_Matrix_ediv(harkio_Matrix *a, harkio_Matrix* b);
harkio_Matrix* harkio_Matrix_getDiag(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_makeDiag(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_esquare(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_eabs(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_econj(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_etanh(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_ecosh(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_elog(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_elog10(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_ereal(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_eimag(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_emulCInt32(harkio_Matrix *m, int value);
harkio_Matrix* harkio_Matrix_emulCFloat32(harkio_Matrix *m, float value);
harkio_Matrix* harkio_Matrix_emulCComplex(harkio_Matrix *m, COMPLEX_TYPE value);
harkio_Matrix* harkio_Matrix_edivCInt32(harkio_Matrix *m, int value);
harkio_Matrix* harkio_Matrix_edivCFloat32(harkio_Matrix *m, float value);
harkio_Matrix* harkio_Matrix_edivCComplex(harkio_Matrix *m, COMPLEX_TYPE value);
harkio_Matrix* harkio_Matrix_epowerCInt32(harkio_Matrix *m, int value);
harkio_Matrix* harkio_Matrix_epowerCFloat32(harkio_Matrix *m, float value);
harkio_Matrix* harkio_Matrix_epowerCComplex(harkio_Matrix *m, COMPLEX_TYPE value);
harkio_Matrix* harkio_Matrix_emap(harkio_Matrix *m, harkio_Matrix_maps *map);
harkio_Matrix* harkio_Matrix_ecalcCInt32(harkio_Matrix *m, int value, harkio_Matrix_calcfuncInt32 func);
harkio_Matrix* harkio_Matrix_ecalcCFloat32(harkio_Matrix *m, float value, harkio_Matrix_calcfuncFloat32 func);
harkio_Matrix* harkio_Matrix_ecalcCComplex(harkio_Matrix *m, COMPLEX_TYPE value, harkio_Matrix_calcfuncComplex func);
harkio_Matrix* harkio_Matrix_reshape(harkio_Matrix *m, int rows, int cols);
harkio_Matrix* harkio_Matrix_transpose(harkio_Matrix *m);
harkio_Matrix* harkio_Matrix_ctranspose(harkio_Matrix *m);

int harkio_Matrix_setValueInt32(harkio_Matrix *m, int row, int col, int value);
int harkio_Matrix_getValueInt32(harkio_Matrix *m, int row, int col, int *value);
int harkio_Matrix_setValueFloat32(harkio_Matrix *m, int row, int col, float value);
int harkio_Matrix_getValueFloat32(harkio_Matrix *m, int row, int col, float *value);
int harkio_Matrix_setValueComplex(harkio_Matrix *m, int row, int col, COMPLEX_TYPE value);
int harkio_Matrix_getValueComplex(harkio_Matrix *m, int row, int col, COMPLEX_TYPE *value);
harkio_Matrix*  harkio_Matrix_getValues(harkio_Matrix *matrix,int rowFrom ,int rowTo,int colFrom,int colTo);
int  harkio_Matrix_setValues(harkio_Matrix *m1 , harkio_Matrix *m2 , int row , int col);
char* harkio_Matrix_getTag(harkio_Matrix *xml);
int harkio_Matrix_isEqual(harkio_Matrix *a, harkio_Matrix *b);
// int harkio_Complex_calc(COMPLEX_TYPE *value , COMPLEX_TYPE valuea , COMPLEX_TYPE valueb , enum Calculate calc);
int harkio_CheckType(char *type);


// Config
harkio_Config* harkio_Config_new(void);
harkio_Config* harkio_Config_copy(harkio_Config *cfg);
void harkio_Config_delete(harkio_Config **cfg);

int harkio_Config_getSynchronousAverage(harkio_Config *cfg);
char *harkio_Config_getTSPpath(harkio_Config *cfg);
int harkio_Config_getTSPoffset(harkio_Config *cfg);
int harkio_Config_getPeakSearchFrom(harkio_Config *cfg);
int harkio_Config_getPeakSearchTo(harkio_Config *cfg);
int harkio_Config_getNfft(harkio_Config *cfg);
int harkio_Config_getSamplingRate(harkio_Config *cfg);
int harkio_Config_getTSPLength(harkio_Config *cfg);
int harkio_Config_getSignalMax(harkio_Config *cfg);

char* harkio_Config_getComment(harkio_Config *cfg);

int harkio_Config_setSynchronousAverage(harkio_Config *cfg, int value);
int harkio_Config_setTSPpath(harkio_Config *cfg, const char *value);
int harkio_Config_setTSPoffset(harkio_Config *cfg, int value);
int harkio_Config_setPeakSearchFrom(harkio_Config *cfg, int value);
int harkio_Config_setPeakSearchTo(harkio_Config *cfg, int value);
int harkio_Config_setNfft(harkio_Config *cfg, int value);
int harkio_Config_setComment(harkio_Config *cfg, const char *value);
int harkio_Config_setSamplingRate(harkio_Config *cfg, int value);
int harkio_Config_setTSPlength(harkio_Config *cfg, int value);
int harkio_Config_setSignalMax(harkio_Config *cfg, int value);

int harkio_Config_isEqual(harkio_Config *a, harkio_Config *b);
int harkio_Config_isEqual(harkio_Config *a, harkio_Config *b);
void harkio_Config_print(harkio_Config *cfg);
char* harkio_Config_printBuffer(harkio_Config *cfg);

// Position
harkio_Position* harkio_Position_new(int id, enum Coordinate sys, float *coord, char *path);
void harkio_Position_delete(harkio_Position **pos);
void harkio_Position_print(harkio_Position* pos);
char* harkio_Position_printBuffer(harkio_Position* pos);

float* harkio_Position_getPosition(harkio_Position* pos);
int harkio_Position_setPosition(harkio_Position* pos, enum Coordinate sys, float *coord);
int  harkio_Position_getSys(harkio_Position *pos);
int harkio_Position_isEqual(harkio_Position *a, harkio_Position *b);
harkio_Position* harkio_Position_copy(harkio_Position *p);
int harkio_Position_Convert(harkio_Position *pos, float *coord, enum Coordinate type);
float harkio_Position_convToRadian(float degree);
float harkio_Position_convToDegree(float radian);
int harkio_Position_getID(harkio_Position* pos);
int  harkio_Positions_getFrame(harkio_Positions *poses);
int harkio_Position_setChannels(harkio_Position* pos , const int *channels, const int numChannels);
int harkio_Position_setNumChannels(harkio_Position* pos , int numChannels);
int harkio_Position_setChannelsUse(harkio_Position* pos , int channels_use);


// Positions
harkio_Positions* harkio_Positions_new(char *type, int frame, int size, harkio_Position **pos);
harkio_Positions* harkio_Positions_newFromXMLbuffer(char *buffer, int len, char *dtdpath);
void harkio_Positions_delete(harkio_Positions **pos);
void harkio_Positions_print(harkio_Positions* pos);
char* harkio_Positions_printBuffer(harkio_Positions* pos);
harkio_Positions* harkio_Positions_copy(harkio_Positions* pos);
int harkio_Positions_append(harkio_Positions *poses, harkio_Position *pos);
int harkio_Positions_removeById(harkio_Positions *poses, int id);
int harkio_Positions_removeByCoord(harkio_Positions *poses, enum Coordinate sys, float *coord, float tolerance);
harkio_Position* harkio_Positions_getById(harkio_Positions *poses, int id);
harkio_Position* harkio_Positions_getByCoord(harkio_Positions *poses, enum Coordinate sys, float *coord, float tolerance);
char*  harkio_Positions_getType(harkio_Positions *poses);
int harkio_Positions_isEqual(harkio_Positions *a, harkio_Positions *b);
int  harkio_Positions_getSize(harkio_Positions *poses);



// Neighbors
harkio_Neighbors* harkio_Neighbors_new(harkio_Positions *poses);
harkio_Neighbors* harkio_Neighbors_copy(harkio_Neighbors *poses);
void harkio_Neighbors_delete(harkio_Neighbors **nbrs);

int harkio_Neighbors_calcNeighbors(harkio_Neighbors *nbrs, enum NeighborAlgorithm alg, ...);
int harkio_Neighbors_getNeighbors(harkio_Neighbors *nbrs, int id, int *numNeighbors, int **neighbors);
int harkio_Neighbors_append(harkio_Neighbors *nbrs, int id, int numNeighbors, int *neighbors);
int harkio_Neighbors_getSize(harkio_Neighbors *nbs);
enum NeighborAlgorithm harkio_Neighbors_getNeighborAlgorithm(harkio_Neighbors *nbs);

int harkio_Neighbors_Algorithms_NearestNeighbor(harkio_Neighbors *nbrs, int n, float thresh);
void harkio_Neighbors_print(harkio_Neighbors *nbrs);

int harkio_Neighbors_isEqual(harkio_Neighbors* a, harkio_Neighbors *b);

// utils
float euclidDistance(harkio_Position *pos_a ,  harkio_Position *pos_b , int length);


// XML
harkio_XML* harkio_XML_new(void);
harkio_XML* harkio_XML_newFromXML(char *xmlpath, char *dtdpath);
harkio_XML* harkio_XML_newFromXMLbuffer(char *buffer, int strlen, char *dtdpath);
harkio_XML* harkio_XML_newFromData(harkio_Positions *ps, harkio_Neighbors *nbrs, harkio_Config *cfg);
void harkio_XML_delete(harkio_XML **xml);

harkio_Config*  harkio_XML_getConfig(harkio_XML *xml);

int harkio_XML_write(harkio_XML *xml, FILE *outstream);
int harkio_XML_writeHead(FILE *outstream);
int harkio_XML_writePositions(harkio_Positions *poses, FILE *outstream);
int harkio_XML_writeTail(FILE *outstream);

harkio_Neighbors *harkio_XML_getNeighbors(harkio_XML *xml);
harkio_Positions *harkio_XML_getPositions(harkio_XML *xml);
char* harkio_XML_writeBuffer(harkio_XML *xml);


// TF
harkio_TransferFunction* harkio_TransferFunction_new(void);
harkio_TransferFunction* harkio_TransferFunction_fromFile(char *path, char *signature);
harkio_TransferFunction* harkio_TransferFunction_fromData(harkio_Positions *poses, harkio_Positions *mics, harkio_Config *cfg, harkio_Neighbors *nbrs);
void harkio_TransferFunction_delete(harkio_TransferFunction **tf);

int harkio_TransferFunction_write(harkio_TransferFunction *tf, char *path, char *signature);
//int harkio_TransferFunction_readTFs(harkio_TransferFunction *tf);

harkio_Config* harkio_TransferFunction_getConfig(harkio_TransferFunction *tf);
harkio_Neighbors* harkio_TransferFunction_getNeighbors(harkio_TransferFunction *tf);
harkio_Positions* harkio_TransferFunction_getMicrophones(harkio_TransferFunction *tf);
harkio_Positions* harkio_TransferFunction_getPositions(harkio_TransferFunction *tf);

int harkio_TransferFunction_setConfig(harkio_TransferFunction *tf, harkio_Config *value);
int harkio_TransferFunction_setNeighbors(harkio_TransferFunction *tf, harkio_Neighbors *value);
int harkio_TransferFunction_setMicrophones(harkio_TransferFunction *tf, harkio_Positions *value);
int harkio_TransferFunction_setPositions(harkio_TransferFunction *tf, harkio_Positions *value);

harkio_Matrix* harkio_TransferFunction_getTFByPos(harkio_TransferFunction *tf, harkio_Position *pos, float tolerance, enum harkio_TFType tf_type);
harkio_Matrix* harkio_TransferFunction_getTFById(harkio_TransferFunction *tf, int id, enum harkio_TFType tf_type);
int harkio_TransferFunction_setLocTFs(harkio_TransferFunction *tf, harkio_Matrix **tfs);
int harkio_TransferFunction_setSepTFs(harkio_TransferFunction *tf, harkio_Matrix **tfs);
int harkio_TransferFunction_appendLocTF(harkio_TransferFunction *tf, harkio_Matrix *tfs);
int harkio_TransferFunction_appendSepTF(harkio_TransferFunction *tf, harkio_Matrix *tfs);

harkio_TransferFunction* harkio_Compat_TransferFunction_readlibharkio2(char *loctfpath , char *septfpath);
harkio_TransferFunction* harkio_Compat_SeparationMatrix_readlibharkio2(char *sepmatpath , char *tfzippath);
DEPRECATED("use 'harkio_Compat_TransferFunction_readlibharkio2'") int libharkio3_TransferFunction_readlibhakio2(harkio_TransferFunction **tf, char *loctfpath , char *septfpath);
DEPRECATED("use 'harkio_Compat_SeparationMatrix_readlibharkio2'") int libharkio3_SeparationMatrix_readlibhakio2(harkio_TransferFunction **tf, char *sepmatpath , char *tfzippath);




// Log
void harkio_Log_printf_(enum harkio_Log_logLevel LogLevel, char *message , int PrintLevel, const char *func, int line, ...);
void harkio_Log_FileOpenFailed(char *filename);
void harkio_Log_WrongValue(char *valuename, char *reason);
void harkio_Log_NullPointer(char *valuename);
//void harkio_Log_FuncStart(char *funcname);


#if defined(__cplusplus)
}
#endif

#endif
