// Classifier.h - Obsahuje deklarace funkcí tvořících rozhraní pro klasifikátor
// Autor:   Jan Benda
// Datum:   25.10.2020

#ifndef CLASSIFIER_H
#define CLASSIFIER_H

#define CLASSIFIER_API __declspec(dllexport)

#include <basetsd.h>

#include "opencv2/ml.hpp"

#include "Dataset.h"

static INT16 bayes_9 = 12287, knearest_9 = 16165, svm_9 = 8231, rtrees_9 = 16361, ann_9 = 15805;
static INT16 bayes_10 = 2396, knearest_10 = 2309, svm_10 = 2053, rtrees_10 = 3358, ann_10 = 6970;
static INT16 bayes_11 = 16241, knearest_11 = 14881, svm_11 = 13317, rtrees_11 = 4045, ann_11 = 12189;
static INT16 bayes_12 = 15807, knearest_12 = 12191, svm_12 = 8197, rtrees_12 = 3035, ann_12 = 16251;

/*static INT16 bayes_9 = 9334, knearest_9 = 9334, svm_9 = 9334, rtrees_9 = 9334, ann_9 = 9334;
static INT16 bayes_10 = 109, knearest_10 = 109, svm_10 = 109, rtrees_10 = 109, ann_10 = 109;
static INT16 bayes_11 = 1145, knearest_11 = 1145, svm_11 = 1145, rtrees_11 = 1145, ann_11 = 1145;
static INT16 bayes_12 = 15807, knearest_12 = 12191, svm_12 = 8197, rtrees_12 = 11753, ann_12 = 16251;*/

namespace Classification
    {
    struct Classifiers
        {
        cv::Ptr<cv::ml::NormalBayesClassifier> bayesClassifier;
        cv::Ptr<cv::ml::KNearest> knearestClassifier;
        cv::Ptr<cv::ml::SVM> svmClassifier;
        cv::Ptr<cv::ml::RTrees> rtreesClassifier;
        cv::Ptr<cv::ml::ANN_MLP> annClassifier;
        std::vector<std::string> iLabels;
        };

    std::vector<float> createFeatureVector(const std::vector<float> iFeatureValues, const std::vector<std::string> iFeatureNames, INT16 iVersion);
    cv::Mat createFeatureMatrix(const std::vector<Dataset::TrainingSample> iTrainingSamples, INT16 iVersion);
    cv::Mat createLabelMatrix(const std::vector<Dataset::TrainingSample> iTrainingSamples, std::vector<std::string> iLabels);
    std::vector<int> createLabelVector(const std::vector<Dataset::TrainingSample> iTraining, std::vector<std::string> iLabels);
    extern "C++" CLASSIFIER_API Classifiers trainClassifiers(const std::vector<Dataset::TrainingSample> iTraining, const short iID);
    extern "C++" CLASSIFIER_API void clear(Classifiers& iClassifier);
    extern "C++" CLASSIFIER_API bool trained(Classifiers iClassifier);
    void sortAnnResponses(std::vector<float> iResponses, std::vector<float>& iWeights, std::vector<std::string>& iLabels, const std::vector<std::string> iNames);
    extern "C++" CLASSIFIER_API void testSample(Dataset::TestingSample & iSample, const Classifiers& iModels, const short iID);
    extern "C++" CLASSIFIER_API std::string LUTable(std::string iLabel);

    extern "C++" CLASSIFIER_API void fMaxSearch(std::string iFilename, const std::vector<Dataset::TrainingSample>&iTrainingDataset, std::vector<Dataset::TestingSample>&iTestingDataset, const short ID);
    
    extern "C++" CLASSIFIER_API void getTable(std::string iFilename, Classifiers iClassifiers, std::vector<Dataset::TestingSample>&iTesting, const short ID);
    extern "C++" CLASSIFIER_API void getTable1(std::string iFilename, const std::vector<Dataset::TrainingSample>&iTrainingDataset, std::vector<Dataset::TestingSample>&iTesting, const short ID);
    void prinTable(std::string name, int version, std::vector<std::vector<int>>& count, std::vector<std::string> labels, std::ofstream& myFile);
    }

#endif /*CLASSIFIER_H*/