#include <windows.h>
#include <tchar.h>
#include <rapi.h>

#include "..\common.h"

// max size for text box in dialog
const int MAX_CHARS = 32;
const int TEXT_MAX = MAX_CHARS+1;   

BOOL CALLBACK DlgProc(HWND hwndDlg, 
                      UINT uMsg, 
                      WPARAM wParam, 
                      LPARAM lParam); 


HRESULT DoCRI();
void SendText(HWND hwnd);
BOOL Connect(HWND hwnd);
BOOL Disconnect(HWND hwnd);

IRAPIStream *g_pStream = NULL;


int WINAPI WinMain (HINSTANCE hInstance,
		            HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int nCmdShow)
{
    RAPIINIT ri = { sizeof(RAPIINIT) };

    if ( SUCCEEDED(CeRapiInitEx(&ri)) )
    {
        // wait for 15 seconds for the connection...
        if ( (WaitForSingleObject(ri.heRapiInit, 15000) == WAIT_OBJECT_0) && 
             SUCCEEDED(ri.hrRapiInit) )
        {
            DialogBox(hInstance, 
                      MAKEINTRESOURCE(IDD_MAINDLG), 
                      NULL, 
                      (DLGPROC)DlgProc);
        }
        else
        {
            MessageBox(NULL, _T("CeRapiInitEx failed"), _T("CeRapiInitEx failed"), MB_OK);
        }

        // have to call uninit even if the connection did not succeed
        CeRapiUninit();
    }
    else
    {
        MessageBox(NULL, _T("CeRapiInitEx failed"), _T("CeRapiInitEx failed"), MB_OK);
    }

    return 0;
}


BOOL CALLBACK DlgProc(HWND hwndDlg, 
                      UINT uMsg, 
                      WPARAM wParam, 
                      LPARAM lParam)
{
    BOOL    bRet = FALSE;

    switch( uMsg )
    {
        case WM_INITDIALOG:
            SendMessage(GetDlgItem(hwndDlg, IDC_TEXT), EM_LIMITTEXT, MAX_CHARS, 0);
            EnableWindow(GetDlgItem(hwndDlg, IDC_CONNECT), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_SEND), FALSE);
            break;

        case WM_COMMAND:
        {
            int     nID = LOWORD(wParam);
            int     wNotify = HIWORD(wParam);
            HWND    hwndCtl = (HWND)lParam;

            // handle a click on the send, connect, or cancel buttons
            if ( wNotify == BN_CLICKED )
            {
              switch( nID )
              {
                case IDCANCEL:
                    Disconnect(hwndDlg);
                    EndDialog(hwndDlg, IDCANCEL);
                    bRet = TRUE;
                    break;

                case IDC_CONNECT:
                    if ( g_pStream )
                        Disconnect(hwndDlg);
                    else
                        Connect(hwndDlg);
                    bRet = TRUE;
                    break;

                case IDC_SEND:
                    SendText(hwndDlg);
                    bRet = TRUE;
                    break;
              }
            }
        }
        break;
    }

    return bRet;
}


BOOL Connect(HWND hwnd)
{
    HRESULT hr = DoCRI();

    if ( CRI_Success(hr) )
    {
        // enable UI to show connectivity
        EnableWindow(GetDlgItem(hwnd, IDC_TEXT), TRUE);
        EnableWindow(GetDlgItem(hwnd, IDC_SEND), TRUE);

        SetWindowText(GetDlgItem(hwnd, IDC_CONNECT), _T("&Disconnect"));

    }
    else
    {
        // notify w/ a messagebox
        MessageBox(hwnd, _T("Could not connect"), _T("Error"), MB_OK);
    }

    return CRI_Success(hr);

}

BOOL Disconnect(HWND hwnd)
{
    DWORD   cbWritten, cb;
    TCHAR chBuf[TEXT_MAX];

    if ( g_pStream )
    {
        wcscpy(chBuf, L"\x01|done|\x02");
        cb = (wcslen(chBuf)*sizeof(TCHAR)) + sizeof(TCHAR);

        g_pStream->Write(&cb, sizeof cb, &cbWritten);
        g_pStream->Write(chBuf, cb, &cbWritten);

        g_pStream->Release();
        g_pStream = NULL;
    }

    // enable UI to show connectivity
    EnableWindow(GetDlgItem(hwnd, IDC_TEXT), FALSE);
    EnableWindow(GetDlgItem(hwnd, IDC_SEND), FALSE);

    SetWindowText(GetDlgItem(hwnd, IDC_CONNECT), _T("&Connect"));

    return TRUE;

}



HRESULT DoCRI()
{
    HRESULT hr;

    DWORD cb = 0;
    PBYTE pbuf = NULL;


    hr = CeRapiInvoke(_T("cridll.dll"), 
                      _T("DlgStreamTest"), 
                      0,
                      NULL,
                      &cb,
                      &pbuf,
                      &g_pStream,
                      0);

    // free any allocated output buffer
    if ( pbuf )
        CeRapiFreeBuffer(pbuf);

    return hr;
}


void SendText(HWND hwndDlg)
{
    DWORD   cbWritten, cb;
    TCHAR chBuf[TEXT_MAX];


    if ( g_pStream )
    {
        GetWindowText(GetDlgItem(hwndDlg, IDC_TEXT), 
                                chBuf, 
                                TEXT_MAX);

        cb = (wcslen(chBuf)*sizeof(TCHAR)) + sizeof(TCHAR);

        g_pStream->Write(&cb, sizeof cb, &cbWritten);
        g_pStream->Write(chBuf, cb, &cbWritten);
    }
}



