#pragma warning (disable:4996)
#pragma comment(lib,"comctl32")
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>

#include "resource.h"
#include "c2rw.h"
#include "c2rw_file.h"
#include "c2rw_gvar.h"
#include "c2rw_gui.h"
#include "c2rw_thr.h"

LRESULT CALLBACK main_dlgp(HWND hDlg, DWORD msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_CLOSE:
            gui_getall(0);
            DestroyWindow(hMain);
            return 0;
        case WM_QUIT:
            gui_getall(0);
            DestroyWindow(hMain);
            break;

        case WM_SHOWWINDOW:
            hMain=hDlg;
            CenterWindow(hMain,GetDesktopWindow());
            initrc();
//          SetFocus(GetDlgItem(hMain, IDC_SCTPSRCH));
            //SetActiveWindow(hMain);// GetDlgItem(hMain, IDC_KEYSRCHB));
            //SendMessage(GetDlgItem(hMain, IDC_SCTPSRCH), BM_CLICK, 0, 0);
            return 0;

        case WM_COMMAND:
            if (LOWORD(wParam) == CM_EXIT)
            {
                SendMessage(hMain, WM_CLOSE, 0, 0);
                break;
            }
            else if ((!updif) &&
                ((LOWORD(wParam) == IDE_SCKEYA) && (HIWORD(wParam) == EN_CHANGE)))
            {
                gui_dupkeyA();
                break;
            }
            else if ((!updif) &&
                ((LOWORD(wParam) == IDE_SCKEYB) && (HIWORD(wParam) == EN_CHANGE)) )
            {
                gui_dupkeyB();
                break;
            }
            else if ((!updif) && (HIWORD(wParam) == EN_CHANGE) &&
                ((LOWORD(wParam) == IDE_DATA0) ||
                ((LOWORD(wParam) >= IDE_PG00) && (LOWORD(wParam) <= IDE_PG02))) )
            {
                if (gui_getzero()) gui_upzero();
                break;
            }
            else if ((!updif) &&
                ((LOWORD(wParam) == IDC_SCTPSEL) && (HIWORD(wParam) == CBN_SELCHANGE))) // card type changed
            {
                gui_getall(0);                          // read all gui fields with old sector and type
                c2rw_set.qs = gui_getqs();              // save current quad sector
                c2rw_set.tp = gui_gettp();              // read type of card
                gui_setqs();                            // set new selector by card type
                gui_setdata();                          // update all fields with data from other quad
                gui_upzero();                           // update card parameters group
                gui_disen(TRUE);                        // update controls
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCUFIX) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_uidfix();   // BCC fix
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCSSEL) && (HIWORD(wParam) == CBN_SELCHANGE))   // sector changed
            {
                gui_getall(0);                          // read all gui fields with old sector
                c2rw_set.qs = gui_getqs();              // set new quad sector
                gui_setdata();                          // update all fields with data from other quad
                gui_disen(TRUE);                        // update controls
                break;
            }
            else if ((!updif) && (HIWORD(wParam) == BN_CLICKED) &&
                (((LOWORD(wParam) >= IDX_DATA0) && (LOWORD(wParam) <= IDX_DATA3)) ||        // state changed
                (((LOWORD(wParam) >= IDX_PG00) && (LOWORD(wParam) <= IDX_PG15)))) )         // state changed
            {
                c2rw_set.qs = gui_getqs();              // getting quad sector
                gui_getall(0);                          // read all gui fields
                gui_disen(TRUE);                        // update controls
                break;
            }
            else if (LOWORD(wParam) == CM_NRWMSG)       // change non-RW message state
            {
                gui_setmenucheck(CM_NRWMSG, (c2rw_set.flg ^= MASK_NRWMSG) & MASK_NRWMSG);
                break;
            }
            else if (LOWORD(wParam) == CM_ALLDT)        // change non-RW message state
            {
                gui_setmenucheck(CM_ALLDT, (c2rw_set.flg ^= MASK_ALLDATA) & MASK_ALLDATA);
                gui_disen(TRUE);                        // update controls
                break;
            }
            else if (LOWORD(wParam) == CM_ASCLD)        // load ascii file
            {
                gui_getall(0);                          // read all gui fields
                memset(filepath, 0, sizeof(filepath));  // clear filename
                if (dlg4load(STR_CLDASC, STR_FLTASC, filepath))
                {
                    if (!load_asc(filepath))
                    {
                        gui_res2stbar(STR_ELOAD);       // error message to status bar
                        dlg4err(STR_CERR, STR_ELOAD, 0, MB_OK | MB_ICONERROR);
                    }
                    else
                    {
                        gui_setqs();                    // set new selector
                        gui_settp();                    // set new card type
                        SendMessage(hMain, WM_COMMAND, MAKEWPARAM(IDC_SCTPSEL, CBN_SELCHANGE), 0);
                        gui_res2stbar(STR_GLOAD);       // ok message to status bar
                    }
                }
                break;
            }
            else if (LOWORD(wParam) == CM_ASCSV)        // save ascii file
            {
                gui_getall(0);                          // read all gui fields
                build_fname(STR_EXTASC);                // build filename
                if (dlg4save(STR_CSVASC, STR_FLTASC, filepath))
                {
                    if (!save_asc(filepath))
                    {
                        gui_res2stbar(STR_ESAVE);       // error message to status bar
                        dlg4err(STR_CERR, STR_ESAVE, 0, MB_OK | MB_ICONERROR);  // error box
                    }
                    else
                    {
                        gui_res2stbar(STR_GSAVE);       // ok message to status bar
                    }
                }
                break;
            }
            else if (LOWORD(wParam) == CM_BINLD)        // load bin file
            {
                gui_getall(0);                          // read all gui fields
                memset(filepath, 0, sizeof(filepath));  // clear filename
                if (dlg4load(STR_CLDBIN, STR_FLTBIN, filepath))
                {
                    if (!load_bin(filepath))
                    {
                        gui_res2stbar(STR_ELOAD);       // error message to status bar
                        dlg4err(STR_CERR, STR_ELOAD, 0, MB_OK | MB_ICONERROR);
                    }
                    else
                    {
                        gui_setqs();                    // set new selector
                        gui_settp();                    // set new card type
                        SendMessage(hMain, WM_COMMAND, MAKEWPARAM(IDC_SCTPSEL, CBN_SELCHANGE), 0);
                        gui_res2stbar(STR_GLOAD);       // ok message to status bar
                    }
                }
                break;
            }
            else if (LOWORD(wParam) == CM_BINSV)        // save bin file
            {
                gui_getall(0);                          // read all gui fields
                build_fname(STR_EXTBIN);                // build filename
                if (dlg4save(STR_CSVBIN, STR_FLTBIN, filepath))
                {
                    if (!save_bin(filepath))
                    {
                        gui_res2stbar(STR_ESAVE);       // error message to status bar
                        dlg4err(STR_CERR, STR_ESAVE, 0, MB_OK | MB_ICONERROR);  // error box
                    }
                    else
                    {
                        gui_res2stbar(STR_GSAVE);       // ok message to status bar
                    }
                }
                break;
            }
            else if (LOWORD(wParam) == CM_CFGLD)        // load cfg file
            {
                gui_getall(0);                          // read all gui fields
                memset(filepath, 0, sizeof(filepath));  // clear filename
                if (dlg4load(STR_CLDCFG, STR_FLTCFG, filepath))
                {
                    if (!load_cfg(filepath))
                    {
                        gui_res2stbar(STR_ELOAD);       // error message to status bar
                        dlg4err(STR_CERR, STR_ELOAD, 0, MB_OK | MB_ICONERROR);
                    }
                    else
                    {
                        gui_setqs();                    // set new selector
                        gui_settp();                    // set new card type
                        SendMessage(hMain, WM_COMMAND, MAKEWPARAM(IDC_SCTPSEL, CBN_SELCHANGE), 0);
                        gui_res2stbar(STR_GLOAD);       // ok message to status bar
                    }
                }
                break;
            }
            else if (LOWORD(wParam) == CM_CFGSV)        // save cfg file
            {
                gui_getall(0);                          // read all gui fields
                build_fname(STR_EXTCFG);                // build filename
                if (dlg4save(STR_CSVCFG, STR_FLTCFG, filepath))
                {
                    if (!save_cfg(filepath))
                    {
                        gui_res2stbar(STR_ESAVE);       // error message to status bar
                        dlg4err(STR_CERR, STR_ESAVE, 0, MB_OK | MB_ICONERROR);  // error box
                    }
                    else
                    {
                        gui_res2stbar(STR_GSAVE);       // ok message to status bar
                    }
                }
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCTPSRCH) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(0);                          // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_typesrch, STR_CTPSRCH); // card type search
                break;
            }
            else if ((LOWORD(wParam) == IDC_KEYSRCHA) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(0);                          // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_keyAsrch, STR_CTPSRCH); // key A search
                break;
            }
            else if ((LOWORD(wParam) == IDC_KEYSRCHB) && (HIWORD(wParam) == BN_CLICKED))
            {
                // key B search
                gui_getall(0);                          // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_keyBsrch, STR_CTPSRCH); // key B search
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCRDSEC) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(IFLG_NODATA);                // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_rdrs, STR_CRDRS);       // read sector
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCRDCRD) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(IFLG_NODATA);                // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_rdcard, STR_CRDCARD);   // read card
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCWRSEC) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(0);                          // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_wrrs, STR_CWRRS);       // write sector
                break;
            }
            else if ((LOWORD(wParam) == IDC_SCWRCRD) && (HIWORD(wParam) == BN_CLICKED))
            {
                gui_getall(0);                          // read all gui fields
                launch_thread((LPTHREAD_START_ROUTINE)t_wrcard, STR_CWRCARD);   // write card
                break;
            }
            goto defp;

        default:
            goto defp;
    }
    return 0;

defp:
    return (DefWindowProc(hDlg, msg, wParam, lParam));
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    HANDLE                  hMutex;
    WNDCLASSEX              wc;
    HACCEL                  hAcl = NULL;
    MSG                     msg;

    DWORD                   defCBR[10] = { 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 };
    TCHAR                   cfgpath[MAX_PATH + 1];
    char                    aCmd[32];
    DWORD                   ctmp, cnt;

    // connect to library
    InitCommonControls();

    if (hPrevInstance) goto main_exit;
    hInst = hInstance;
    hMutex = CreateMutex(NULL, TRUE, TEXT(C2RW_RCCLASS));
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        CloseHandle(hMutex);
        goto main_exit;
    }
    // init global variables
    gvar_init();

    // parse command line
    memset(aCmd, 0, sizeof(aCmd));
    for (cnt = 0; cnt < strlen(lpszCmdParam); cnt++)
        if (lpszCmdParam[cnt] != 0x20) break;
    if ((ctmp = strlen(&lpszCmdParam[cnt])) > 20) ctmp = 20;
    if (ctmp > 8)
    {
        memcpy(aCmd, &lpszCmdParam[cnt], ctmp);
        if (!strnicmp(aCmd, "COM", 3))
        {
            if (isdigit(aCmd[3]))
            {
                sscanf(&aCmd[3], "%u", &cport);
                if ((cport) && (cport < 256))
                {
                    for (cnt = 3; cnt < strlen(aCmd); cnt++)
                        if (!isdigit(aCmd[cnt])) break;
                    for (; cnt < strlen(aCmd); cnt++)
                        if (aCmd[cnt] != 0x20) break;
                    if (isdigit(aCmd[cnt]))
                    {
                        ctmp = 0;
                        sscanf(&aCmd[cnt], "%u", &ctmp);
                        for (cnt = 0; cnt < sizeof(defCBR) / sizeof(defCBR[0]); cnt++)
                        {
                            if (ctmp == defCBR[cnt])
                            {
                                cbr = ctmp;
                                break;
                            }
                        }
                        ctmp = 0;
                    }
                }
            }
        }
    }
    if ((ctmp) && (!cport) && (!cbr))
    {
        dlg4err(STR_CINFO, STR_USAGE, 0, MB_OK);
        goto main_exit;
    }
    // load cfg-file
    lstrcpy(cfgpath, GetProgramDir());
    lstrcat(cfgpath, CFG_FNAME);
    load_cfg(cfgpath);
    // load accelerators
    hAcl = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDD_MAIN));
    // register window class
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;             // class style
    wc.lpfnWndProc = (WNDPROC)main_dlgp;            // dialog fn
    wc.cbClsExtra = 0;                              // no extra data
    wc.cbWndExtra = DLGWINDOWEXTRA;                 //
    wc.hInstance = hInstance;                       // handler приложения
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);       // установка курсора
    wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    wc.lpszMenuName = MAKEINTRESOURCE(IDD_MAIN);    // имя меню в .RC файле
    wc.lpszClassName = TEXT(C2RW_RCCLASS);          // имя для создания окна
    wc.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 16, 16, 0);
    if (!RegisterClassEx(&wc)) goto main_exit;
    // create dialog box
    hMain = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, NULL, NULL);
    if (!hMain) goto main_exit;
    ShowWindow(hMain, SW_SHOWNORMAL);
    UpdateWindow(hMain);
    // main loop
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (TranslateAccelerator(hMain, hAcl, &msg) == FALSE)
        {
            if (IsDialogMessage(hMain, &msg) == FALSE)
            {
                TranslateMessage(&msg); // Translates virtual key codes
                DispatchMessage(&msg);  // Dispatches message to window
            }
        }
    }
    save_cfg(cfgpath);  // save cfg
main_exit:
    if (hAcl) DestroyAcceleratorTable(hAcl);    // destroy accelerators

    return 0;
}
