// Controls.cpp - Obsahuje definice funkcí tvořících rozhraní pro práci s ovládacími prvky aplikace
// Autor:   Jan Benda
// Datum:   25.10.2020

#include "Controls.h"
#include "Resource.h"

namespace Controls
    {
    //
//   FUNCTION: CreateControls(HWND hWnd, HINSTANCE hInstance)
//
//   PURPOSE: Create controls in main window
//
    void CreateControls(HWND hWnd, HINSTANCE hInstance)
        {
        // ------ PRIDANI TRENOVACIHO VZORU -----
        if(CreateWindowW(WC_BUTTON, L"ADD TRAINING\nSAMPLE(S)", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 20, 30, 110, 40,
           hWnd, (HMENU) IDC_BUTTON_ADD_TRAIN_SAMPLE, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"DELETE\nSAMPLE", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 140, 30, 75, 40,
           hWnd, (HMENU) IDC_BUTTON_DELETE_TRAIN_SAMPLE, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"ADD\nCLASS", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 280, 30, 75, 40,
           hWnd, (HMENU) IDC_BUTTON_ADD_TRAIN_CLASS, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"DELETE\nCLASS", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 365, 30, 75, 40,
           hWnd, (HMENU) IDC_BUTTON_DELETE_TRAIN_CLASS, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_LISTBOX, L"List", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_WANTKEYBOARDINPUT, 20, 105, 420, 415,
           hWnd, (HMENU) IDC_LISTBOX_TRAIN_SAMPLES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_EDIT, L"Class Label...", WS_CHILD | WS_VISIBLE | WS_BORDER, 20, 80, 420, 20,
           hWnd, (HMENU) IDC_EDIT_TRAIN_SAMPLE_CLASS, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_STATIC, L" Number of Samples: 0", WS_CHILD | WS_VISIBLE, 20, 520, 180, 20,
           hWnd, (HMENU) IDC_STATIC_TRAIN_SAMPLES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_STATIC, L" Number of Trained Classes: 0", WS_CHILD | WS_VISIBLE, 210, 520, 210, 20,
           hWnd, (HMENU) IDC_STATIC_TRAIN_CLASSES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"TRAINING DATA", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 10, 5, 440, 545,
           hWnd, (HMENU) IDC_STATIC_TRAINING_DATA, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        // ------ PRIDANI TRENOVACIHO VZORU -----


        // ------ PRIDANI TESTOVACIHO VZORU -----
        if(CreateWindowW(WC_BUTTON, L"ADD TESTING SAMPLE(S)", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 465, 30, 180, 20,
           hWnd, (HMENU) IDC_BUTTON_ADD_TEST_SAMPLE, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"DELETE SAMPLE", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 655, 30, 180, 20,
           hWnd, (HMENU) IDC_BUTTON_DELETE_TEST_SAMPLE, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_LISTBOX, L"List", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_WANTKEYBOARDINPUT, 465, 60, 370, 460,
           hWnd, (HMENU) IDC_LISTBOX_TEST_SAMPLES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_STATIC, L" Number of Samples: 0", WS_CHILD | WS_VISIBLE, 465, 520, 180, 20,
           hWnd, (HMENU) IDC_STATIC_TEST_SAMPLES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"TESTING DATA", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 455, 5, 390, 545,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        // ------ PRIDANI TESTOVACIHO VZORU -----


            //------- CONTROLS --------
        if(CreateWindowW(WC_BUTTON, L"TRAIN", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 860, 30, 125, 50,
           hWnd, (HMENU) IDC_BUTTON_TRAIN, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"LOAD", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 990, 85, 125, 50,
           hWnd, (HMENU) IDC_BUTTON_LOAD, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"SAVE", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 860, 85, 125, 50,
           hWnd, (HMENU) IDC_BUTTON_SAVE, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"CLEAR\nALL", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_MULTILINE, 990, 30, 125, 50,
           hWnd, (HMENU) IDC_BUTTON_CLEAR, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"CONTROLS", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 5, 275, 140,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        //------- CONTROLS --------   

        //-------- RESULTS ---------
        if(CreateWindowW(WC_BUTTON, L"BAYES", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 150, 275, 50,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        if(CreateWindowW(WC_STATIC, L"", WS_CHILD | WS_VISIBLE, 860, 175, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_BAYES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"K-NEAREST", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 205, 275, 50,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        if(CreateWindowW(WC_STATIC, L"", WS_CHILD | WS_VISIBLE, 860, 230, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_KNEAREST, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"SVM", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 260, 275, 50,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        if(CreateWindowW(WC_STATIC, L"", WS_CHILD | WS_VISIBLE, 860, 285, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_SVM, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"R-TREES", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 315, 275, 50,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        if(CreateWindowW(WC_STATIC, L"", WS_CHILD | WS_VISIBLE, 860, 340, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_RTREES, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"ANN-MLP", WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | BS_GROUPBOX, 850, 370, 275, 120,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        if(CreateWindowW(WC_STATIC, L"1.", WS_CHILD | WS_VISIBLE, 860, 395, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_ANN1, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_STATIC, L"2.", WS_CHILD | WS_VISIBLE, 860, 430, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_ANN2, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_STATIC, L"3.", WS_CHILD | WS_VISIBLE, 860, 465, 255, 15,
           hWnd, (HMENU) IDC_STATIC_RESULTS_ANN3, hInstance, NULL) == NULL)
            throw std::exception();

        // -------- CHECKBOXES ---------
        if(CreateWindowW(WC_STATIC, L"Show Segmentation", WS_CHILD | WS_VISIBLE, 860, 505, 130, 20,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"Checkbox_seg", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 995, 505, 15, 15, hWnd, (HMENU) IDC_CHECK_BOX_SEGMENTATION, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");

        if(CreateWindowW(WC_STATIC, L"Show Grayscale", WS_CHILD | WS_VISIBLE, 860, 520, 130, 20,
           hWnd, NULL, hInstance, NULL) == NULL)
            throw std::exception();
        if(CreateWindowW(WC_BUTTON, L"Checkbox_gray", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 995, 520, 15, 15, hWnd, (HMENU) IDC_CHECK_BOX_GRAYSCALE, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");
        //-------- RESULTS ---------

        /*if(CreateWindowW(WC_BUTTON, L"SR", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 1030, 505, 30, 30,
           hWnd, (HMENU) IDC_SUCCESS_RATE, hInstance, NULL) == NULL)
            throw std::exception("Failed to create controls");*/
        }

    std::string getText(HWND iHWND, int iIDC)
        {
        HWND editHWND = GetDlgItem(iHWND, iIDC);
        int length = (int) GetWindowTextLengthW(editHWND) + 1;
        TCHAR* fName;
        fName = new TCHAR[length];

        GetWindowTextW(editHWND, fName, length);

        std::string item = ws2s(fName);
        delete[] fName;
        return item;    
        }

    void insertItem(HWND iHWND, int iIDC, std::string iItem)
        {
        HWND editHWND = GetDlgItem(iHWND, iIDC);
        SendMessageW(editHWND, LB_ADDSTRING, 0, (LPARAM)s2ws(iItem).c_str());
        }

    std::string getItem(HWND iHWND, int iIDC)
        {
        HWND listHWND = GetDlgItem(iHWND, iIDC);
        TCHAR* name;
        std::string output;
        int index = (int) SendMessageW(listHWND, LB_GETCURSEL, 0, 0);
        int textLen = (int) SendMessageW(listHWND, LB_GETTEXTLEN, (WPARAM) index, 0) + 1;
        if(textLen > 0)
            {
            name = new TCHAR[textLen];
            SendMessageW(listHWND, LB_GETTEXT, (WPARAM) index, (LPARAM) name);
            output = ws2s(name);
            delete[] name;
            }
        return output;
        }

    std::string itemFilename(std::string iItem)
        {
        const size_t index = iItem.find_first_of(" - ");
        if(std::string::npos != index)
            iItem.erase(0, index + 3);
            
        return iItem;
        }

    short itemLabel(std::string iItem)
        {
        const size_t index = iItem.find_first_of(" - ");
        if(std::string::npos != index)
            return stoi(iItem.substr(1, 2));
        return -1;
        }

    void deleteItem(HWND iHWND, int iIDC, std::string iFilename)
        { 
        HWND hwndList = GetDlgItem(iHWND, iIDC);
        int index = (int)SendMessageW(hwndList, LB_FINDSTRING, (WPARAM)-1, (LPARAM)s2ws(iFilename).c_str());
        SendMessageW(hwndList, LB_DELETESTRING, (WPARAM) index, 0);
        }

    void clearListBox(HWND iHWND, int iIDC)
        {
        SendMessage(GetDlgItem(iHWND, iIDC), LB_RESETCONTENT, 0, 0);
        }

    std::string ws2s(const std::wstring& s)
        {
        int slength = (int) s.length() + 1;
        int len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
        char* buf = new char[len];
        WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
        std::string r(buf);
        delete[] buf;
        return r;
        }
     
    std::wstring s2ws(const std::string& s)
        {
        int slength = (int) s.length() + 1;
        int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
        wchar_t* buf = new wchar_t[len];
        MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
        std::wstring r(buf);
        delete[] buf;
        return r;
        }

    void hideControls(HWND hWnd)
        {
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_SAMPLE), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_SAMPLE), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_CLASS), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_CLASS), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAIN_CLASSES), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), SW_HIDE);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAINING_DATA), SW_HIDE);
        }

    void showControls(HWND hWnd)
        {
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_SAMPLE), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_SAMPLE), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_CLASS), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_CLASS), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAIN_CLASSES), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAIN_SAMPLES), SW_SHOW);
        ShowWindow(GetDlgItem(hWnd, IDC_STATIC_TRAINING_DATA), SW_SHOW);
        }

    void disableControls(HWND hWnd)
        {
        EnableWindow(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_SAMPLE), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_SAMPLE), false);
        EnableWindow(GetDlgItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_CLASS), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_CLASS), false);

        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TEST_SAMPLE), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), false);
        EnableWindow(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), false);

        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_TRAIN), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_CLEAR), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_LOAD), false);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_SAVE), false);

        EnableWindow(GetDlgItem(hWnd, IDC_CHECK_BOX_SEGMENTATION), false);
        EnableWindow(GetDlgItem(hWnd, IDC_CHECK_BOX_GRAYSCALE), false);
        }

    void enableControls(HWND hWnd, const bool test, const bool train)
        {
        EnableWindow(GetDlgItem(hWnd, IDC_EDIT_TRAIN_SAMPLE_CLASS), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_SAMPLE), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_SAMPLE), true);
        EnableWindow(GetDlgItem(hWnd, IDC_LISTBOX_TRAIN_SAMPLES), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TRAIN_CLASS), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TRAIN_CLASS), true);

        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_DELETE_TEST_SAMPLE), true);
        if(test)
            EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_ADD_TEST_SAMPLE), true);
        EnableWindow(GetDlgItem(hWnd, IDC_LISTBOX_TEST_SAMPLES), true);
        if(train)
            EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_TRAIN), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_CLEAR), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_LOAD), true);
        EnableWindow(GetDlgItem(hWnd, IDC_BUTTON_SAVE), true);

        EnableWindow(GetDlgItem(hWnd, IDC_CHECK_BOX_SEGMENTATION), true);
        EnableWindow(GetDlgItem(hWnd, IDC_CHECK_BOX_GRAYSCALE), true);
        }

    }

