// GUICLassificator.cpp : Defines the entry point for the application.
//

#include "Controls.h"
#include "framework.h"
#include "ClassifierGUI.h"
#include "FileManager.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
HWND hWndImage = nullptr;

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                      _In_opt_ HINSTANCE hPrevInstance,
                      _In_ LPWSTR    lpCmdLine,
                      _In_ int       nCmdShow)
    {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_CLASSIFIERGUI, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if(!InitInstance(hInstance, nCmdShow))
        {
        return FALSE;
        }

    MSG msg;

    // Main message loop:
    while(GetMessage(&msg, nullptr, 0, 0))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }

    return (int) msg.wParam;
    }

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CLASSIFIERGUI));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_CLASSIFIERGUI);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
    }

//
//   FUNCTION: InitInstance(HINSTANCE, int) 
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
    hInst = hInstance; // Store instance handle in our global variable

    HWND hWnd = CreateWindowW(L"CLASSIFIERGUI", L"ClassifierGUI", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1150, 600, nullptr, nullptr, hInstance, nullptr);
    
    cv::namedWindow(WIN_NAME_CV, CV_WINDOW_KEEPRATIO);  // create an OpenCV win
    hWndImage = (HWND) cvGetWindowHandle(WIN_NAME_CV);  // get the handle of OpenCV Window
    ShowWindow(hWndImage, SW_HIDE);

    if(!hWnd)
        return false;

    HWND hOldParent = ::GetParent(hWndImage);
    SetParent(hWndImage, hWnd);     // move the OpenCV window to the new parent (your static control)
    ShowWindow(hOldParent, SW_HIDE); // hide the old parent window

    if(!hWnd)
        {
        return FALSE;
        }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    try
        {
        Controls::CreateControls(hWnd, hInstance);
        } catch(std::exception& e)
            {
            MessageBox(NULL, (LPCWSTR) L"Failed to create control", (LPCWSTR) L"ERROR", MB_OK | MB_ICONERROR);
            return EXIT_FAILURE;
            }

        if(!FileManager::DirectoryExists("segmentation"))
            CreateDirectoryA("segmentation", NULL);

        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_TRAIN), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), false);
        return TRUE;
    }

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE: Processes messages for the main window.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch(message)
        {
        case WM_LBUTTONDOWN:
            {
            if(LOWORD(lParam) >= 465 && LOWORD(lParam) <= (465 + 370) && HIWORD(lParam) >= 60 && HIWORD(lParam) <= (60 + 460));
            else
                {
                SetFocus(hWnd);
                Controls::showControls(hWnd);
                ShowWindow(hWndImage, SW_HIDE);
                }
            }
            break;
        case WM_COMMAND:
            {
            switch(LOWORD(wParam))
                {
                // -------------------------------------------------------- TRAINING DATA ------------------------------------------------------- 
                case IDC_BUTTON_ADD_TRAIN_SAMPLE:
                    {
                    Controls::disableControls(hWnd);
                    std::vector<std::string> filepaths;
                    FileManager::OpenDialog(filepaths, true, false, "jpg");
                    std::string label_name = Controls::getText(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS);
                    MSG msg;
                    try
                        {
                        switch(General::getID(label_name))
                            {
                            case 9:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                        
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining9))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 10:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining10))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 11:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining11))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 12:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining12))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            default:
                                MessageBoxW(hWnd, (LPCWSTR) L"Formát názvu třídy musí být ve tvaru: xYYxx, kde YY je z rozsahu 09 - 12\nnapř.  90901", NULL, MB_OK);
                                break;
                            }
                        }
                    catch(std::exception& e)
                        {
                        MessageBoxW(hWnd, (LPCWSTR) Controls::s2ws(e.what()).c_str(), NULL, MB_OK);
                        }                   

                    if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                        train = true;

                    Controls::enableControls(hWnd, test, train);
                    SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), (LPCSTR) "Class Label...");
                    }
                    break;
                case IDC_BUTTON_DELETE_TRAIN_SAMPLE:
                    {
                    std::string item = Controls::getItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES);
                    
                    if(item != "")
                        {
                        Controls::disableControls(hWnd);
                        std::string filename = Controls::itemFilename(item);
                        int ID = Controls::itemLabel(item);
                        switch(ID)
                            {
                            case 9:
                                Dataset::deleteTrainingSample(filename, iDataset.iTraining9);
                                break;
                            case 10:
                                Dataset::deleteTrainingSample(filename, iDataset.iTraining10);
                                break;
                            case 11:
                                Dataset::deleteTrainingSample(filename, iDataset.iTraining11);
                                break;
                            case 12:
                                Dataset::deleteTrainingSample(filename, iDataset.iTraining12);
                                break;
                            default:
                                break;
                            }
                            
                        Controls::deleteItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, item);

                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                        
                        if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                            train = true;

                        Controls::enableControls(hWnd, test, train);
                        }
                    }
                    break;
                case IDC_BUTTON_ADD_TRAIN_CLASS:
                    {
                    Controls::disableControls(hWnd);
                    std::vector<std::string> filepaths;
                    FileManager::OpenDialog(filepaths, false, true, "jpg");
                    std::string label_name = Controls::getText(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS);
                    MSG msg;
                    try
                        {
                        switch(General::getID(label_name))
                            {
                            case 9:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);  
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining9))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 10:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining10))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 11:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining11))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            case 12:
                                for(size_t n = 0; n < filepaths.size(); n++)
                                    {
                                    PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                    if(Dataset::addTrainingSample(label_name, filepaths.at(n), iDataset.iTraining12))
                                        {
                                        Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, (label_name + " - " + General::getFilename(filepaths.at(n))));
                                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                                       + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                                        }
                                    }
                                break;
                            default:
                                MessageBoxW(hWnd, (LPCWSTR) L"Formát názvu třídy musí být ve tvaru: xYYxx, kde YY je z rozsahu 09 - 12\nnapř.  90901", NULL, MB_OK);
                                break;
                            }
                        }
                    catch(std::exception& e)
                        {
                        MessageBoxW(hWnd, (LPCWSTR) Controls::s2ws(e.what()).c_str(), NULL, MB_OK);
                        }

                    if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                        train = true;

                    Controls::enableControls(hWnd, test, train);
                    SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), (LPCSTR) "Class Label...");
                    }
                    break;
                case IDC_BUTTON_DELETE_TRAIN_CLASS:
                    {
                    std::string label_name = Controls::getText(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS);
                    Controls::disableControls(hWnd);
                    MSG msg;
                    switch(General::getID(label_name))
                        {
                        case 9:
                            for(size_t i = 0; i < iDataset.iTraining9.size(); i++)
                                {
                                PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                if(iDataset.iTraining9.at(i).iLabel == label_name)
                                    {
                                    Controls::deleteItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, label_name + " - " + iDataset.iTraining9.at(i).iSampleName);
                                    Dataset::deleteTrainingSample(iDataset.iTraining9.at(i).iSampleName, iDataset.iTraining9);
                                    i--;
                                    }
                                }
                            break;
                        case 10:
                            for(size_t i = 0; i < iDataset.iTraining10.size(); i++)
                                {
                                PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                if(iDataset.iTraining10.at(i).iLabel == label_name)
                                    {
                                    Controls::deleteItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, label_name + " - " + iDataset.iTraining10.at(i).iSampleName);
                                    Dataset::deleteTrainingSample(iDataset.iTraining10.at(i).iSampleName, iDataset.iTraining10);
                                    i--;
                                    }
                                }
                            break;
                        case 11:
                            for(size_t i = 0; i < iDataset.iTraining11.size(); i++)
                                {
                                PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                if(iDataset.iTraining11.at(i).iLabel == label_name)
                                    {
                                    Controls::deleteItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, label_name + " - " + iDataset.iTraining11.at(i).iSampleName);
                                    Dataset::deleteTrainingSample(iDataset.iTraining11.at(i).iSampleName, iDataset.iTraining11);
                                    i--;
                                    }
                                }
                            break;
                        case 12:
                            for(size_t i = 0; i < iDataset.iTraining12.size(); i++)
                                {
                                PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                                if(iDataset.iTraining12.at(i).iLabel == label_name)
                                    {
                                    Controls::deleteItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, label_name + " - " + iDataset.iTraining12.at(i).iSampleName);
                                    Dataset::deleteTrainingSample(iDataset.iTraining12.at(i).iSampleName, iDataset.iTraining12);
                                    i--;
                                    }
                                }
                            break;
                        default:
                            break;
                        }

                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                   + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                    SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), (LPCSTR) "Class Label...");

                    if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                        train = true;

                    Controls::enableControls(hWnd, test, train);
                    }
                    break;
                    // -------------------------------------------------------- TRAINING DATA -------------------------------------------------------

                    // --------------------------------------------------------- TESTING DATA -------------------------------------------------------
                case IDC_BUTTON_ADD_TEST_SAMPLE:
                    {
                    Controls::disableControls(hWnd);
                    std::vector<std::string> filepaths;
                    short ID = 0;
                    FileManager::OpenDialog(filepaths, true, false, "jpg");
                    size_t i = 0;
                    MSG msg;
                    try
                        {
                        for(i = 0; i < filepaths.size(); i++)
                            {
                            PeekMessage(&msg, hWnd, 0, 0, PM_NOYIELD | PM_NOREMOVE);
                            bool added = false;
                            ID = 0;
                            if((added = Dataset::addTestingSample(filepaths.at(i), iDataset.iTesting, ID)))
                                switch(ID)
                                    {
                                    case 9:
                                        if(iDataset.iTraining9.size() > 0)
                                            {
                                            Classification::testSample(iDataset.iTesting.at(iDataset.iTesting.size() - 1), Classifier_909, 9);
                                            Controls::insertItem(hWnd, IDC_LISTBOX_TEST_SAMPLES, (General::getFilename(iDataset.iTesting.at(iDataset.iTesting.size() - 1).iSamplePath)));
                                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                                            }
                                        else
                                            {
                                            added = false;
                                            Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                                            MessageBoxW(hWnd, (LPCWSTR) L"Vkladano do skupiny 09, Classifier_909 neni natrenovan", NULL, MB_OK);
                                            }
                                        break;
                                    case 10:
                                        if(iDataset.iTraining10.size() > 0)
                                            {
                                            Classification::testSample(iDataset.iTesting.at(iDataset.iTesting.size() - 1), Classifier_910, 10);
                                            Controls::insertItem(hWnd, IDC_LISTBOX_TEST_SAMPLES, (General::getFilename(iDataset.iTesting.at(iDataset.iTesting.size() - 1).iSamplePath)));
                                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                                            }
                                        else
                                            {
                                            added = false;
                                            Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                                            MessageBoxW(hWnd, (LPCWSTR) L"Vkladano do skupiny 10, Classifier_910 neni natrenovan", NULL, MB_OK);
                                            }
                                        break;
                                    case 11:
                                        if(iDataset.iTraining11.size() > 0)
                                            {
                                            Classification::testSample(iDataset.iTesting.at(iDataset.iTesting.size() - 1), Classifier_911, 11);
                                            Controls::insertItem(hWnd, IDC_LISTBOX_TEST_SAMPLES, (General::getFilename(iDataset.iTesting.at(iDataset.iTesting.size() - 1).iSamplePath)));
                                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                                            }
                                        else
                                            {
                                            added = false;
                                            Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                                            MessageBoxW(hWnd, (LPCWSTR) L"Vkladano do skupiny 11, Classifier_911 neni natrenovan", NULL, MB_OK);
                                            }
                                        break;
                                    case 12:
                                        if(iDataset.iTraining12.size() > 0)
                                            {
                                            Classification::testSample(iDataset.iTesting.at(iDataset.iTesting.size() - 1), Classifier_912, 12);
                                            Controls::insertItem(hWnd, IDC_LISTBOX_TEST_SAMPLES, (General::getFilename(iDataset.iTesting.at(iDataset.iTesting.size() - 1).iSamplePath)));
                                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                                            }
                                        else
                                            {
                                            added = false;
                                            Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                                            MessageBoxW(hWnd, (LPCWSTR) L"Vkladano do skupiny 12, Classifier_912 neni natrenovan", NULL, MB_OK);
                                            }
                                        break;
                                    default:
                                        Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                                        added = false;
                                        break;
                                    }
                            }
                        }
                        catch(std::exception& e)
                            {
                            Dataset::deleteTestingSample(filepaths.at(i), iDataset.iTesting);
                            MessageBoxW(hWnd, (LPCWSTR) Controls::s2ws(e.what()).c_str(), NULL, MB_OK);
                            }
                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                        
                        if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                            train = true;

                        Controls::enableControls(hWnd, test, train);
                    }
                    break;
                case IDC_BUTTON_DELETE_TEST_SAMPLE:
                    {
                    std::string item = Controls::getItem(hWnd, IDC_LISTBOX_TEST_SAMPLES);
                    if(item != "")
                        {
                        Controls::disableControls(hWnd);

                        TCHAR infoBuf[MAX_PATH];
                        if(GetCurrentDirectory(MAX_PATH, infoBuf))
                            std::remove((Controls::ws2s(infoBuf) + "\\" + item).c_str());

                        Controls::deleteItem(hWnd, IDC_LISTBOX_TEST_SAMPLES, item);
                        Dataset::deleteTestingSample(item, iDataset.iTesting);
                        SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());
                        Controls::enableControls(hWnd, test, train);
                        }
                    }
                    break;
                case IDC_LISTBOX_TEST_SAMPLES:
                    {
                    int index = -1; 
                    if(HIWORD(wParam) == LBN_SELCHANGE)
                        {
                        if((index = (int) SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), LB_GETCURSEL, 0, 0)) >= 0)
                            {
                            std::string sample_name = Controls::getItem(hWnd, IDC_LISTBOX_TEST_SAMPLES);
                            if(sample_name != General::getFilename(iDataset.iTesting.at(index).iSamplePath))
                                {
                                TCHAR* name;
                                std::string output;
                                int index = (int) SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), LB_GETCURSEL, 0, 0);
                                int textLen = (int) SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), LB_GETTEXTLEN, (WPARAM) index, 0) + 1;
                                if(textLen > 0)
                                    {
                                    name = new TCHAR[textLen];
                                    SendMessageW(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), LB_GETTEXT, (WPARAM) index, (LPARAM) name);
                                    output = Controls::ws2s(name);
                                    delete[] name;
                                    }
                                }
 
                            if(iDataset.iTesting.at(index).iPredictions.annLabels.size() == 3 && General::getFilename(iDataset.iTesting.at(index).iSamplePath) == sample_name)
                                {
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_BAYES), (LPCSTR) (Classification::LUTable(iDataset.iTesting.at(index).iPredictions.bayesLabel)).c_str());
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_KNEAREST), (LPCSTR) (Classification::LUTable(iDataset.iTesting.at(index).iPredictions.knearestLabel)).c_str());
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_SVM), (LPCSTR) (Classification::LUTable(iDataset.iTesting.at(index).iPredictions.svmLabel)).c_str());
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_RTREES), (LPCSTR) (Classification::LUTable(iDataset.iTesting.at(index).iPredictions.rtreesLabel)).c_str());

                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN1), (LPCSTR) ("1. " + Classification::LUTable(iDataset.iTesting.at(index).iPredictions.annLabels.at(0)) + "(" + std::to_string(iDataset.iTesting.at(index).iPredictions.annWeights.at(0)) + ")").c_str());
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN2), (LPCSTR) ("2. " + Classification::LUTable(iDataset.iTesting.at(index).iPredictions.annLabels.at(1)) + "(" + std::to_string(iDataset.iTesting.at(index).iPredictions.annWeights.at(1)) + ")").c_str());
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN3), (LPCSTR) ("3. " + Classification::LUTable(iDataset.iTesting.at(index).iPredictions.annLabels.at(2)) + "(" + std::to_string(iDataset.iTesting.at(index).iPredictions.annWeights.at(2)) + ")").c_str());

                                if(show_segmented)
                                    {
                                    Controls::hideControls(hWnd);

                                    TCHAR infoBuf[MAX_PATH];
                                    if(GetCurrentDirectory(MAX_PATH, infoBuf))
                                        {
                                        cv::Mat image = cv::imread(Controls::ws2s(infoBuf) + "\\" + iDataset.iTesting.at(index).iSegmentedPath, cv::IMREAD_COLOR);
                                        cv::imshow(WIN_NAME_CV, image);
                                        }
                                    SetWindowPos(hWndImage, 0, 10, 5, 440, 545, SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
                                    }
                                else if(show_grayscale)
                                    {
                                    Controls::hideControls(hWnd);

                                    cv::Mat image = cv::imread(iDataset.iTesting.at(index).iSamplePath, cv::IMREAD_COLOR);
                                    cv::imshow(WIN_NAME_CV, image);
                                    SetWindowPos(hWndImage, 0, 10, 5, 440, 545, SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
                                    }
                                else
                                    {
                                    Controls::showControls(hWnd);
                                    ShowWindow(hWndImage, SW_HIDE);
                                    }
                                }
                            if(iDataset.iTesting.size() == 0)
                                {
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_BAYES), (LPCSTR) (""));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_KNEAREST), (LPCSTR) (""));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_SVM), (LPCSTR) (""));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_RTREES), (LPCSTR) (""));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN1), (LPCSTR) ("1."));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN2), (LPCSTR) ("2."));
                                SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN3), (LPCSTR) ("3."));
                                }
                            }
                        }
                    }
                    break;
                    // --------------------------------------------------------- TESTING DATA -------------------------------------------------------

                    // ---------------------------------------------------------- CLASSIFIER --------------------------------------------------------
                case IDC_BUTTON_TRAIN:
                    {
                    Controls::disableControls(hWnd);
                    bool exception = true;
                    try
                        {
                        if(iDataset.iTraining9.size() > 0)
                            {
                            exception = false;
                            Classifier_909 = Classification::trainClassifiers(iDataset.iTraining9, 9);
                            }
                        if(iDataset.iTraining10.size() > 0)
                            {
                            exception = false;
                            Classifier_910 = Classification::trainClassifiers(iDataset.iTraining10, 10);
                            }
                        if(iDataset.iTraining11.size() > 0)
                            {
                            exception = false;
                            Classifier_911 = Classification::trainClassifiers(iDataset.iTraining11, 11);
                            }
                        if(iDataset.iTraining12.size() > 0)
                            {
                            exception = false;
                            Classifier_912 = Classification::trainClassifiers(iDataset.iTraining12, 12);
                            }
                        }
                    catch(std::exception& e)
                        {
                        exception = true;
                        MessageBoxW(hWnd, (LPCWSTR) Controls::s2ws(e.what()).c_str(), NULL, MB_OK);
                        }
                    if(!exception)
                        {
                        if(Classification::trained(Classifier_909) && Classification::trained(Classifier_910) && Classification::trained(Classifier_911) && Classification::trained(Classifier_912))
                            {
                            test = false;
                            }
                        else
                            {
                            test = true;
                            MessageBoxW(hWnd, (LPWSTR) (L"Trained"), (LPCWSTR) L"Info", MB_ICONINFORMATION | MB_OK);
                            }

                        }
                    Controls::enableControls(hWnd, test, train);
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_CLASSES), (LPCSTR) (" Number of Trained Classes: " + std::to_string(Classifier_909.iLabels.size()
                                   + Classifier_910.iLabels.size() + Classifier_911.iLabels.size() + Classifier_912.iLabels.size())).c_str());
                    }
                    break;
                case IDC_BUTTON_LOAD:
                    {
                    Controls::disableControls(hWnd);
                    size_t size9 = iDataset.iTraining9.size(), size10 = iDataset.iTraining10.size(), size11 = iDataset.iTraining11.size(), size12 = iDataset.iTraining12.size();
                    bool exception = false;
                    std::vector<std::string> filenames;
                    FileManager::OpenDialog(filenames, false, false, "xml");
                    if(filenames.size() == 1)
                        {
                        try
                            {
                            filemanager::readXML(filenames.at(0), Classifier_909, Classifier_910, Classifier_911, Classifier_912, iDataset);
                            }
                        catch(std::exception& e)
                            {
                            exception = true;
                            MessageBoxW(hWnd, (LPCWSTR) Controls::s2ws(e.what()).c_str(), NULL, MB_OK);
                            }
                        if(!exception)
                            {
                            for(size_t i = size9; i < iDataset.iTraining9.size(); i++)
                                Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, iDataset.iTraining9.at(i).iLabel + " - " + iDataset.iTraining9.at(i).iSampleName);
                            for(size_t i = size10; i < iDataset.iTraining10.size(); i++)
                                Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, iDataset.iTraining10.at(i).iLabel + " - " + iDataset.iTraining10.at(i).iSampleName);
                            for(size_t i = size11; i < iDataset.iTraining11.size(); i++)
                                Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, iDataset.iTraining11.at(i).iLabel + " - " + iDataset.iTraining11.at(i).iSampleName);
                            for(size_t i = size12; i < iDataset.iTraining12.size(); i++)
                                Controls::insertItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES, iDataset.iTraining12.at(i).iLabel + " - " + iDataset.iTraining12.at(i).iSampleName);

                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                           + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                            SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_CLASSES), (LPCSTR) (" Number of Trained Classes: " + std::to_string(Classifier_909.iLabels.size()
                                           + Classifier_910.iLabels.size() + Classifier_911.iLabels.size() + Classifier_912.iLabels.size())).c_str());
                            }
                        }

                    if(Classification::trained(Classifier_909) || Classification::trained(Classifier_910) || Classification::trained(Classifier_911) || Classification::trained(Classifier_912))
                        {
                        test = true;
                        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), true);
                        }
                    else
                        {
                        test = false;
                        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), false);
                        }

                    if(iDataset.iTraining9.size() > 0 || iDataset.iTraining10.size() > 0 || iDataset.iTraining11.size() > 0 || iDataset.iTraining12.size() > 0)
                        train = true;

                    Controls::enableControls(hWnd, test, train);
                    }
                    break;
                case IDC_BUTTON_SAVE:
                    {
                    Controls::disableControls(hWnd);
                    std::vector<std::string> filenames;
                    FileManager::OpenDialog(filenames, false, false, "xml");
                    if(filenames.size() == 1)
                        filemanager::writeXML(filenames.at(0), Classifier_909, Classifier_910, Classifier_911, Classifier_912, iDataset);
                    Controls::enableControls(hWnd, test, train);
                    }
                    break;
                case IDC_BUTTON_CLEAR:
                    {
                    Controls::disableControls(hWnd);
                    
                    Controls::clearListBox(hWnd, IDC_LISTBOX_TRAIN_SAMPLES);
                    iDataset.iTraining9.clear();
                    iDataset.iTraining9.shrink_to_fit();
                    iDataset.iTraining10.clear();
                    iDataset.iTraining10.shrink_to_fit();
                    iDataset.iTraining11.clear();
                    iDataset.iTraining11.shrink_to_fit();
                    iDataset.iTraining12.clear();
                    iDataset.iTraining12.shrink_to_fit();

                    Controls::clearListBox(hWnd, IDC_LISTBOX_TEST_SAMPLES);
                    iDataset.iTesting.clear();
                    iDataset.iTesting.shrink_to_fit();

                    TCHAR infoBuf[MAX_PATH];
                    if(; GetCurrentDirectory(MAX_PATH, infoBuf))
                        {
                        for(const auto& entry : std::filesystem::directory_iterator(Controls::ws2s(infoBuf) + "\\segmentation"))
                            std::filesystem::remove_all(entry.path());
                        }

                    Classification::clear(Classifier_909);
                    Classification::clear(Classifier_910);
                    Classification::clear(Classifier_911);
                    Classification::clear(Classifier_912);

                    train = false;

                    Controls::enableControls(hWnd, test, train);
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_CLASSES), (LPCSTR) (" Number of Trained Classes: " + std::to_string(Classifier_909.iLabels.size()
                                   + Classifier_910.iLabels.size() + Classifier_911.iLabels.size() + Classifier_912.iLabels.size())).c_str());
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTraining9.size()
                                   + iDataset.iTraining10.size() + iDataset.iTraining11.size() + iDataset.iTraining12.size())).c_str());
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_TEST_SAMPLES), (LPCSTR) (" Number of Samples: " + std::to_string(iDataset.iTesting.size())).c_str());

                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_BAYES), (LPCSTR) (""));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_KNEAREST), (LPCSTR) (""));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_SVM), (LPCSTR) (""));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_RTREES), (LPCSTR) (""));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN1), (LPCSTR) ("1."));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN2), (LPCSTR) ("2."));
                    SetWindowTextA(GetDlgItem(hWnd, IDC_STATIC_RESULTS_ANN3), (LPCSTR) ("3."));

                    if(Classification::trained(Classifier_909) || Classification::trained(Classifier_910) || Classification::trained(Classifier_911) || Classification::trained(Classifier_912))
                        {
                        test = true;
                        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), true);
                        }
                    else
                        {
                        test = false;
                        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), false);
                        }
                    Controls::showControls(hWnd);
                    ShowWindow(hWndImage, SW_HIDE);
                    }
                    break;
                    // ---------------------------------------------------------- CLASSIFIER --------------------------------------------------------

                case IDC_CHECK_BOX_SEGMENTATION:
                    {
                    if(HIWORD(wParam) == BN_CLICKED)
                        {
                        if(SendDlgItemMessage(hWnd, IDC_CHECK_BOX_SEGMENTATION, BM_GETCHECK, 0, 0))
                            {
                            show_segmented = true;
                            SendDlgItemMessage(hWnd, IDC_CHECK_BOX_GRAYSCALE, BM_SETCHECK, (WPARAM) BST_UNCHECKED, 0);
                            show_grayscale = false;
                            }
                        else
                            show_segmented = false;
                        }
                    break;
                    }
                case IDC_CHECK_BOX_GRAYSCALE:
                    {
                    if(HIWORD(wParam) == BN_CLICKED)
                        {
                        if(SendDlgItemMessage(hWnd, IDC_CHECK_BOX_GRAYSCALE, BM_GETCHECK, 0, 0))
                            {
                            show_grayscale = true;
                            SendDlgItemMessage(hWnd, IDC_CHECK_BOX_SEGMENTATION, BM_SETCHECK, (WPARAM) BST_UNCHECKED, 0);
                            show_segmented = false;
                            }
                        else
                            show_grayscale = false;
                        }
                    break;
                    }
                /*case IDC_SUCCESS_RATE:
                    {
                    
                    if(iDataset.iTraining9.size() > 0)
                        {
                        Classification::getTable("table9_final.csv", Classifier_909, iDataset.iTesting, 9);
                        Classification::getTable1("table9_config.csv", iDataset.iTraining9, iDataset.iTesting, 9);
                        //Classification::fMaxSearch("skupina9_50.csv", iDataset.iTraining9, iDataset.iTesting, 9);
                        }
                        
                    if(iDataset.iTraining10.size() > 0)
                        {
                        Classification::getTable("table10_final.csv", Classifier_910, iDataset.iTesting, 10);
                        Classification::getTable1("table10_config.csv", iDataset.iTraining10, iDataset.iTesting, 10);
                        //Classification::fMaxSearch("skupina10_50.csv", iDataset.iTraining10, iDataset.iTesting, 10);
                        }

                    if(iDataset.iTraining11.size() > 0)
                        {
                        Classification::getTable("table11_final.csv", Classifier_911, iDataset.iTesting, 11);
                        Classification::getTable1("table11_config.csv", iDataset.iTraining11, iDataset.iTesting, 11);
                        //Classification::fMaxSearch("skupina11_50.csv", iDataset.iTraining11, iDataset.iTesting, 11);
                        }

                    if(iDataset.iTraining12.size() > 0)
                        {
                        Classification::getTable("table12_final.csv", Classifier_912, iDataset.iTesting, 12);
                        Classification::getTable1("table12_config.csv", iDataset.iTraining12, iDataset.iTesting, 12);
                        //Classification::fMaxSearch("skupina12_50.csv", iDataset.iTraining12, iDataset.iTesting, 12);
                        }
                    break;
                    }*/
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
       case WM_CLOSE:
           {
           if(MessageBox(hWnd, L"Quit?", L"ClassifierGUI", MB_OKCANCEL) == IDOK)
               {
               DestroyWindow(hWnd);
               }
           break;
           }
        case WM_DESTROY:
            {
            TCHAR infoBuf[MAX_PATH];
            if(GetCurrentDirectory(MAX_PATH, infoBuf))
                {
                for(const auto& entry : std::filesystem::directory_iterator(Controls::ws2s(infoBuf) + "\\segmentation"))
                    std::filesystem::remove_all(entry.path());
                }
            PostQuitMessage(0);
            break;
            }
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    return 0;
    }


