#pragma once
#ifndef LOOPCLF_DLLAPI_H_
#define LOOPCLF_DLLAPI_H_

#include "interop_negotiator.h"

#ifdef LOOP_CLASSF_MODEL_DLL
#define LOOP_CLASSF_MODEL_API __declspec(dllexport)
#else 
#define LOOP_CLASSF_MODEL_API __declspec(dllimport)
#endif 

//looper classifier handle
#define LOOPER_CLF_H void*
//loop classifier handle
#define CLF_H void*
//dataset handle
#define DATASET_H void*
//loop classifier optimizer handle
#define CLF_OPT_H void*


#ifdef __cplusplus
extern "C" {
#endif 

//LooperClassifier
	LOOP_CLASSF_MODEL_API LOOPER_CLF_H init_LooperClf(const char* filename);
	LOOP_CLASSF_MODEL_API int kill_LooperClf(LOOPER_CLF_H LooperClf);
	LOOP_CLASSF_MODEL_API int LooperClf_optimize_weights(LOOPER_CLF_H LooperClf);
	LOOP_CLASSF_MODEL_API int LooperClf_optimize_params(LOOPER_CLF_H LooperClf);
	LOOP_CLASSF_MODEL_API int LooperClf_cross_val_report(LOOPER_CLF_H LooperClf);
	LOOP_CLASSF_MODEL_API int LooperClf_predict(LOOPER_CLF_H LooperClf, const double *data, const unsigned n_samples, int* y_pred);
	LOOP_CLASSF_MODEL_API int LooperClf_save_to(LOOPER_CLF_H LooperClf, const char* filename);
	LOOP_CLASSF_MODEL_API int LooperClf_get_info(LOOPER_CLF_H LooperClf, char* info);
	LOOP_CLASSF_MODEL_API int LooperClf_n_features(LOOPER_CLF_H LooperClf, unsigned* n_features);
    LOOP_CLASSF_MODEL_API int LooperClf_set_negotiator(LOOPER_CLF_H LooperClf, const InteropNegotiator* negotiator);
    LOOP_CLASSF_MODEL_API int LooperClf_cancel(LOOPER_CLF_H LooperClf);


//LoopClassifier
	LOOP_CLASSF_MODEL_API CLF_H init_LoopClf(const char* filename);
	LOOP_CLASSF_MODEL_API CLF_H copy_LoopClf(CLF_H LoopClf);
	LOOP_CLASSF_MODEL_API void kill_LoopClf(CLF_H LoopClf);
	LOOP_CLASSF_MODEL_API void LoopClf_save_to(CLF_H LoopClf, const char* filename);
	LOOP_CLASSF_MODEL_API void LoopClf_train(CLF_H LoopClf, DATASET_H dataset);
	LOOP_CLASSF_MODEL_API void LoopClf_predict(CLF_H LoopClf, const double *data, unsigned n_samples, int* y_pred);
	LOOP_CLASSF_MODEL_API void LoopClf_get_neighbors(CLF_H LoopClf, const double* sample, unsigned n_neighbors, double* out_data, int* out_targets, char** out_labels, double* out_distances, unsigned* out_ranks, char** out_pathes);
	LOOP_CLASSF_MODEL_API void LoopClf_classification_info(CLF_H LoopClf, const double* sample, char* info);
    LOOP_CLASSF_MODEL_API void LoopClf_get_probs(CLF_H LoopClf, const double* sample, double* probs, int* classes);
	LOOP_CLASSF_MODEL_API unsigned LoopClf_n_features(CLF_H LoopClf);
	LOOP_CLASSF_MODEL_API const DATASET_H LoopClf_dataset(CLF_H LoopClf);


//LoopClassifierOpt
	LOOP_CLASSF_MODEL_API CLF_OPT_H init_LoopClfOpt(const char* filename);
	LOOP_CLASSF_MODEL_API double LoopClfOpt_cross_val_score(CLF_OPT_H loopClfOpt, DATASET_H dataset, CLF_H loopClf);
	LOOP_CLASSF_MODEL_API double LoopClfOpt_optimize_weights(CLF_OPT_H loopClfOpt, DATASET_H dataset, CLF_H loopClf);
	LOOP_CLASSF_MODEL_API void kill_LoopClfOpt(CLF_H LoopClf);

//Dataset
	LOOP_CLASSF_MODEL_API DATASET_H create_Dataset();
	LOOP_CLASSF_MODEL_API DATASET_H init_Dataset(const char* filename);
	LOOP_CLASSF_MODEL_API void kill_Dataset(DATASET_H dataset);
	LOOP_CLASSF_MODEL_API int Dataset_add_sample(DATASET_H dataset, const char* label, const char* path, const double* data, unsigned n_points);
	LOOP_CLASSF_MODEL_API int Dataset_remove_sample(DATASET_H dataset, const char* path);
	LOOP_CLASSF_MODEL_API void Dataset_save_to(DATASET_H dataset, const char* filename);
	LOOP_CLASSF_MODEL_API unsigned Dataset_n_classes(DATASET_H dataset);
	LOOP_CLASSF_MODEL_API unsigned Dataset_get_classes(DATASET_H dataset, char** class_names, int* class_codes);
	LOOP_CLASSF_MODEL_API void Dataset_get_scheme(DATASET_H dataset, char* classes);

#ifdef __cplusplus
}
#endif 




#endif


