// Dataset.cpp - Obsahuje definice funkcí sloužících pro přidání a odebírání vzorů z trénovací/testovací množiny
// Autor:   Jan Benda
// Datum:   16.02.2021

#include "Dataset.h"

namespace Dataset
    {
    // Vloží vzorek z dané cesty (iFilepath) do daného trénovací množiny (iTrainingSamples) do dané třídy (sLabel)
    bool addTrainingSample(const std::string iLabel, const std::string iFilepath, std::vector<TrainingSample>& iTrainingSamples)
        {
        short LabelID = General::getID(iLabel);
        // Tohle je zde navíc, kontrola se provádí o úroveň výš
        if(LabelID < 9 || LabelID > 12  )
            throw std::exception("Class label ID out of range (9 - 12)");

        // Pokud se vzorek s daným názvem již v datasetu nachází, podruhé se vzorek nepřidá
        for(size_t i = 0; i < iTrainingSamples.size(); i++)
            if(iTrainingSamples.at(i).iSampleName == General::getFilename(iFilepath))
                return false;

        // Získání hodnot příznakového vektoru
        std::vector<std::string> temp_feature_names;
        std::vector<float> temp_feature_values;

        if(!Description::getFeatures(LabelID, iFilepath, temp_feature_names, temp_feature_values))
            return false;

        // Vytvořit dočasný vzorek, který bude vložen do datasetu
        TrainingSample temp_sample;
        temp_sample.iSampleName = General::getFilename(iFilepath);
        temp_sample.iFeatureValues = temp_feature_values;
        temp_sample.iFeatureNames = temp_feature_names;
        temp_sample.iLabel = iLabel;

        iTrainingSamples.push_back(temp_sample);

        return true;
        }

    // Odstraní vzorek s daným názvem (iFilename) z dané množiny (iTrainingSamples)
    void deleteTrainingSample(const std::string iFilename, std::vector<TrainingSample>& iTrainingSamples)
        {
        for(size_t i = 0; i < iTrainingSamples.size(); i++)
            if(iTrainingSamples.at(i).iSampleName == iFilename)
                {
                iTrainingSamples.erase(iTrainingSamples.begin() + i);
                iTrainingSamples.shrink_to_fit();

                if(iTrainingSamples.size() == 0)
                    iTrainingSamples.shrink_to_fit();
                }
        }

    // Vloží vzorek z dané cesty (iFilepath) do testovací množiny (iTestingSamples)
    bool addTestingSample(const std::string iFilepath, std::vector<TestingSample>& iTestingSamples, short& iID)
        {
        // Pokud se vzorek s daným názvem již v datasetu nachází, podruhé se vzorek nepřidá
        for(size_t i = 0; i < iTestingSamples.size(); i++)
            if(General::getFilename(iTestingSamples.at(i).iSamplePath) == General::getFilename(iFilepath))
                return false;

        // Získání hodnot příznakového vektoru
        std::vector<std::string> temp_feature_names;
        std::vector<float> temp_feature_values;
        if(!Description::getFeatures(iID, iFilepath, temp_feature_names, temp_feature_values))
            return false;

        // Vytvořit dočasný vzorek, který bude vložen do datasetu
        TestingSample temp_sample;
        temp_sample.iFeatureNames = temp_feature_names;
        temp_sample.iSamplePath = iFilepath;
        temp_sample.iSegmentedPath = "segmentation\\" + General::getFilename(iFilepath);
        temp_sample.iFeatureValues = temp_feature_values;

        iTestingSamples.push_back(temp_sample);
        return true;
        }

    // Odstraní vzorek s daným názvem (iFilename) z testovací množiny (iTTesting)
    void deleteTestingSample(const std::string iFilepath, std::vector<TestingSample>& iTestingSamples)
        {
        size_t sample_index = 0;
        bool exception = true;
        for(size_t i = 0; i < iTestingSamples.size(); i++)
            if(General::getFilename(iTestingSamples.at(i).iSamplePath) == General::getFilename(iFilepath))
                {
                sample_index = i;
                exception = false;
                }

        if(!exception)
            {
            iTestingSamples.erase(iTestingSamples.begin() + sample_index);
            iTestingSamples.shrink_to_fit();

            if(iTestingSamples.size() == 0)
                iTestingSamples.shrink_to_fit();
            }
        }
	}