#pragma warning (disable:4996)

#include <windows.h>
#include <commctrl.h>

#include "scc.h"
#include "scc_gvar.h"
#include "resource.h"

// центровка одного окна относительно другого
BOOL CenterWindow(HWND hwndChild, HWND hwndParent)
{
    RECT            rcChild,rcParent;
    int             cxChild,cyChild,cxParent,cyParent;
    int             cxScreen,cyScreen, xNew,yNew;
    HDC             hdc;

    // get the Height and Width of the child window
    GetWindowRect(hwndChild, &rcChild);
    cxChild=rcChild.right-rcChild.left;
    cyChild=rcChild.bottom-rcChild.top;
    // get the Height and Width of the parent window
    GetWindowRect(hwndParent,&rcParent);
    cxParent=rcParent.right-rcParent.left;
    cyParent=rcParent.bottom-rcParent.top;
    // get the display limits
    hdc = GetDC(hwndChild);
    cxScreen = GetDeviceCaps(hdc, HORZRES);
    cyScreen = GetDeviceCaps(hdc, VERTRES);
    ReleaseDC(hwndChild, hdc);
    // calculate new X position, then adjust for screen
    xNew = rcParent.left + ((cxParent - cxChild) / 2);
    if (xNew < 0) xNew = 0;
    else if ((xNew + cxChild) > cxScreen) xNew = cxScreen - cxChild;
    // Calculate new Y position, then adjust for screen
    yNew = rcParent.top  + ((cyParent - cyChild) / 2);
    if (yNew < 0) yNew = 0;
    else if ((yNew + cyChild) > cyScreen) yNew = cyScreen - cyChild;
    // Set it, and return
    return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}

void gui_stbar(LPTSTR szText)
{
    if (szText[0])
    {
        DWORD       icn = IDI_STINFO;
        if (szText[0] == 2) icn = IDI_STOK;
        else if (szText[0] == 3) icn = IDI_STFAIL;
        else if (szText[0] == 4) icn = IDI_STRFSH;
        SendMessage(GetDlgItem(hMain, IDC_STBAR), SB_SETICON, 0, (LPARAM)LoadImage(hInst, MAKEINTRESOURCE(icn), IMAGE_ICON, 16, 16, LR_SHARED));
        SendMessage(GetDlgItem(hMain, IDC_STBAR), SB_SETTEXT, 0, (LPARAM)&szText[1]);
    }
}

void gui_setuid(BYTE uidlen, PBYTE uid)
{
    TCHAR       szUID[32];
    TCHAR       szLocal[32];
    DWORD       cnt;

    szUID[0] = 0;
    if ((uidlen & 15) && (uid))
    {
        for (cnt = 0; (cnt < ((DWORD)uidlen & 15)) && (cnt < 10); cnt++)
            wsprintf(&szUID[lstrlen(szUID)], TEXT("%02X"), uid[cnt]);

        GetDlgItemText(hMain, IDE_SCUID, szLocal, sizeof(szLocal) / sizeof(TCHAR));
        if (lstrcmp(szLocal, szUID))
        {
            SetDlgItemText(hMain, IDE_SCATS, TEXT(""));
            SetDlgItemText(hMain, IDE_SCUID, szUID);
        }
    }
    else
    {
        SetDlgItemText(hMain, IDE_SCUID, TEXT(""));
        SetDlgItemText(hMain, IDE_SCATS, TEXT(""));
    }
}

void gui_setatqasak(WORD atqa, BYTE sak, BOOL ei)
{
    TCHAR       szLocal[8];

    szLocal[0] = 0;
    if (ei) wsprintf(szLocal, TEXT("%04X"), atqa);
    SetDlgItemText(hMain, IDE_SCATQA, szLocal);

    szLocal[0] = 0;
    if (ei) wsprintf(szLocal, TEXT("%02X"), sak);
    SetDlgItemText(hMain, IDE_SCSAK, szLocal);
}

BOOL gui_getatqasak(PWORD patqa, PBYTE psak)
{
    TCHAR       szLocal[8];
    DWORD       cnt;
    // input ATQA
    if (GetDlgItemText(hMain, IDE_SCATQA, szLocal, sizeof(szLocal) / sizeof(TCHAR)) != 4) return FALSE;
    for (cnt = 0; cnt != 4; cnt++)
        if (!_istxdigit(szLocal[cnt])) break;
    if (cnt != 4) return FALSE;
    if (patqa)
    {
        cnt = 0;
        _stscanf(szLocal, TEXT("%X"), &cnt);
        *patqa = (WORD)cnt;
    }
    // input SAK
    if (GetDlgItemText(hMain, IDE_SCSAK, szLocal, sizeof(szLocal) / sizeof(TCHAR)) != 2) return FALSE;
    for (cnt = 0; cnt != 2; cnt++)
        if (!_istxdigit(szLocal[cnt])) break;
    if (cnt != 2) return FALSE;
    if (psak)
    {
        cnt = 0;
        _stscanf(szLocal, TEXT("%X"), &cnt);
        *psak = (BYTE)cnt;
    }

    return TRUE;
}

void gui_setats(BYTE atslen, PBYTE ats)
{
    TCHAR       szLocal[32];
    DWORD       cnt;

    szLocal[0] = 0;
    if (ats)
    {
        if (atslen == 0)
        {
            wsprintf(&szLocal[lstrlen(szLocal)], TEXT("none"));
        }
        else if (atslen == 1)
        {
            wsprintf(&szLocal[lstrlen(szLocal)], TEXT("none (ack=%02X)"), ats[0]);
        }
        else
        {
            for (cnt = 0; (cnt < ((DWORD)atslen)) && (cnt < 30); cnt++)
                wsprintf(&szLocal[lstrlen(szLocal)], TEXT("%02X"), ats[cnt]);
        }
    }
    SetDlgItemText(hMain, IDE_SCATS, szLocal);
}

void gui_setparm(void)
{
    TCHAR       szLocal[40];
    DWORD       cnt;

    SendMessage(GetDlgItem(hMain, IDC_SCTPSEL), CB_SETCURSEL, (WPARAM)scc_set.tp, 0);
    gui_setatqasak(scc_dsc[scc_set.tp].atqa, scc_dsc[scc_set.tp].sak, TRUE);
    SendMessage(GetDlgItem(hMain, IDC_SCRW), BM_SETCHECK, (WPARAM)((scc_set.rw) ? BST_CHECKED : BST_UNCHECKED), 0);
    SendMessage(GetDlgItem(hMain, IDC_SCBSEL), CB_SETCURSEL, (WPARAM)scc_set.blk, 0);

    for (szLocal[0] = 0, cnt = 0; cnt != 6; cnt++)
        wsprintf(&szLocal[lstrlen(szLocal)], TEXT("%02X"), scc_set.ak[cnt]);
    SetDlgItemText(hMain, IDE_SCAKEY, szLocal);

    SendMessage(GetDlgItem(hMain, IDC_SCAKSEL), CB_SETCURSEL, (WPARAM)scc_set.aktp & 1, 0);
    for (szLocal[0] = 0, cnt = 0; cnt != 16; cnt++)
        wsprintf(&szLocal[lstrlen(szLocal)], TEXT("%02X"), scc_set.data[cnt]);
    SetDlgItemText(hMain, IDE_SCDATA, szLocal);

    gui_setuid(scc_set.uidlen, scc_set.uid);
}


BOOL gui_getparm(DWORD iflg)
{
    TCHAR       szLocal[40];
    TCHAR       szDgt[4];
    DWORD       cnt, tmp;
    BOOL        ierr = FALSE;

    // card type
    if (((tmp = SendMessage(GetDlgItem(hMain, IDC_SCTPSEL), CB_GETCURSEL, 0, 0)) == CB_ERR) || (tmp > MAX_CCTYPE))
    {
        tmp = 1;    // default type
        ierr = TRUE;
    }
    else scc_set.tp = (BYTE)tmp;
    // rw-mode
    scc_set.rw = (SendMessage(GetDlgItem(hMain, IDC_SCRW), BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;

    // get uid
    if ((iflg & IFLG_NOUID) == 0)
    {
        if ((tmp = GetDlgItemText(hMain, IDE_SCUID, szLocal, sizeof(szLocal) / sizeof(TCHAR))) > 20)
        {
            ierr = TRUE;
        }
        else
        {
            for (cnt = 0; cnt != tmp; cnt++)
                if (!_istxdigit(szLocal[cnt])) break;
            if (cnt != tmp)
            {
                ierr = TRUE;
            }
            else
            {
                if ((tmp == 0) || (tmp == 8) || (tmp == 14) || (tmp == 20))
                {
                    memset(scc_set.uid, 0, 10);
                    scc_set.uidlen = (BYTE)tmp / 2;
                    for (cnt = 0; cnt != tmp / 2; cnt++)
                    {
                        DWORD       tb;
                        szDgt[0] = szLocal[cnt * 2 + 0]; szDgt[1] = szLocal[cnt * 2 + 1]; szDgt[2] = 0;
                        tb = 0; _stscanf(szDgt, TEXT("%X"), &tb);
                        scc_set.uid[cnt] = (BYTE)tb;
                    }
                }
                else
                {
                    ierr = TRUE;
                }
            }
        }
    }
    // block
    if (((tmp = SendMessage(GetDlgItem(hMain, IDC_SCBSEL), CB_GETCURSEL, 0, 0)) == CB_ERR) || (tmp > 255))
    {
        ierr = TRUE;
    }
    else scc_set.blk = (BYTE)tmp;
    // ak
    if ((tmp = GetDlgItemText(hMain, IDE_SCAKEY, szLocal, sizeof(szLocal) / sizeof(TCHAR))) != 12)
    {
        ierr = TRUE;
    }
    else
    {
        for (tmp = 0; tmp != 12; tmp++)
            if (!_istxdigit(szLocal[tmp])) break;
        if (tmp != 12)
        {
            ierr = TRUE;
        }
        else
        {
            for (tmp = 0; tmp != 6; tmp++)
            {
                DWORD       tb;
                szDgt[0] = szLocal[tmp * 2 + 0]; szDgt[1] = szLocal[tmp * 2 + 1]; szDgt[2] = 0;
                tb = 0; _stscanf(szDgt, TEXT("%X"), &tb);
                scc_set.ak[tmp] = (BYTE)tb;
            }
        }
    }
    // key type
    if (((tmp = SendMessage(GetDlgItem(hMain, IDC_SCAKSEL), CB_GETCURSEL, 0, 0)) == CB_ERR) || (tmp > 1))
    {
        ierr = TRUE;
    }
    else scc_set.aktp = (BYTE)tmp;
    // data
    if ((iflg & IFLG_NODATA) == 0)
    {
        if ((tmp = GetDlgItemText(hMain, IDE_SCDATA, szLocal, sizeof(szLocal) / sizeof(TCHAR))) != 32)
        {
            ierr = TRUE;
        }
        else
        {
            for (tmp = 0; tmp != 32; tmp++)
                if (!_istxdigit(szLocal[tmp])) break;
            if (tmp != 32)
            {
                ierr = TRUE;
            }
            else
            {
                for (tmp = 0; tmp != 16; tmp++)
                {
                    DWORD       tb;
                    szDgt[0] = szLocal[tmp * 2 + 0]; szDgt[1] = szLocal[tmp * 2 + 1]; szDgt[2] = 0;
                    tb = 0; _stscanf(szDgt, TEXT("%X"), &tb);
                    scc_set.data[tmp] = (BYTE)tb;
                }
            }
        }
    }
    if (ierr) gui_setparm();

    return (BOOL)(!ierr);
}

void gui_disen(BOOL eidi)
{
    BOOL        clf, stf;
    // card type: UL / CL
    clf = (SendMessage(GetDlgItem(hMain, IDC_SCTPSEL), CB_GETCURSEL, 0, 0)) ? TRUE : FALSE;
    // rw-mode
    stf = (SendMessage(GetDlgItem(hMain, IDC_SCRW), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FALSE : TRUE;

    EnableWindow(GetDlgItem(hMain, IDC_SCTPSEL), eidi);
    EnableWindow(GetDlgItem(hMain, IDC_SCTPSRCH), eidi);
    EnableWindow(GetDlgItem(hMain, IDC_SCRW), eidi);

    SendMessage(GetDlgItem(hMain, IDE_SCUID), EM_SETREADONLY, stf || (!eidi), 0);
    EnableWindow(GetDlgItem(hMain, IDC_SCSETUID), eidi && (!stf));
    EnableWindow(GetDlgItem(hMain, IDE_SCATQA), eidi && (clf) && (!stf));
    EnableWindow(GetDlgItem(hMain, IDE_SCSAK), eidi && (clf) && (!stf));

    EnableWindow(GetDlgItem(hMain, IDC_SCBSEL), eidi);

    EnableWindow(GetDlgItem(hMain, IDE_SCAKEY), eidi && clf && stf);
    EnableWindow(GetDlgItem(hMain, IDC_SCAKSEL), eidi && clf && stf);
    EnableWindow(GetDlgItem(hMain, IDC_SCAKSRCH), eidi && clf && stf);

    EnableWindow(GetDlgItem(hMain, IDE_SCDATA), eidi);
    EnableWindow(GetDlgItem(hMain, IDC_SCREAD), eidi);
    EnableWindow(GetDlgItem(hMain, IDC_SCWRITE), eidi);
}

// resource initialization
void initrc(void)
{
    TCHAR               szLocal[180];
    DWORD               cnt;

    // main icon
    SendMessage(hMain, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_APPICON)));
    // type selector init
    SendMessage(GetDlgItem(hMain, IDC_SCTPSEL), CB_RESETCONTENT, 0, 0);
    for (cnt = 0; cnt < sizeof(scc_dsc) / sizeof(scc_dsc[0]); cnt++)
    {
        wsprintf(szLocal, TEXT(" %s"), scc_dsc[cnt].txt);
        SendMessage(GetDlgItem(hMain, IDC_SCTPSEL), CB_INSERTSTRING, cnt, (LPARAM)szLocal);
    }
    // UID limit set
    SendMessage(GetDlgItem(hMain, IDE_SCUID), EM_LIMITTEXT, 20, 0);
    // ATQA limit set
    SendMessage(GetDlgItem(hMain, IDE_SCATQA), EM_LIMITTEXT, 4, 0);
    // SAK limit set
    SendMessage(GetDlgItem(hMain, IDE_SCSAK), EM_LIMITTEXT, 2, 0);
    // ATS limit set
    SendMessage(GetDlgItem(hMain, IDE_SCATS), EM_LIMITTEXT, 60, 0);
    // block selector init
    SendMessage(GetDlgItem(hMain, IDC_SCBSEL), CB_RESETCONTENT, 0, 0);
    for (cnt = 0; cnt < 256; cnt++)
    {
        wsprintf(szLocal, TEXT(" %3u"), cnt);
        SendMessage(GetDlgItem(hMain, IDC_SCBSEL), CB_INSERTSTRING, cnt, (LPARAM)szLocal);
    }
    // ak limit set
    SendMessage(GetDlgItem(hMain, IDE_SCAKEY), EM_LIMITTEXT, 12, 0);
    // ak type selector init
    SendMessage(GetDlgItem(hMain, IDC_SCAKSEL), CB_RESETCONTENT, 0, 0);
    SendMessage(GetDlgItem(hMain, IDC_SCAKSEL), CB_INSERTSTRING, 0, (LPARAM)TEXT(" A"));
    SendMessage(GetDlgItem(hMain, IDC_SCAKSEL), CB_INSERTSTRING, 1, (LPARAM)TEXT(" B"));
    // data limit set
    SendMessage(GetDlgItem(hMain,IDE_SCDATA),EM_LIMITTEXT,32,0);
    // setup parameters
    gui_setparm();
    // enable controls
    gui_disen(TRUE);
    // set dialog message
    lstrcpy(szLocal, CAP_STARTMSG);
    lstrcat(szLocal, RDRAPI_VER);
    SetWindowText(hMain, szLocal);
    // set status message
    if ((cport) && (cbr)) wsprintf(szLocal, TEXT("\1COM%u, %ubps. "), cport, cbr);
    else lstrcpy(szLocal, TEXT("\1USB. "));
    lstrcat(szLocal, STB_STARTMSG);
    gui_stbar(szLocal);
}
