/*
 * WineMine (main.c)
 * 
 * Copyright 2000 Joshua Thielen <jt85296@ltu.edu>
 * To be distributed under the Wine License
 */


#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include "main.h"
#include "dialog.h"
#include "resource.h"

/* Work around a Wine bug which defines handles as UINT rather than LPVOID */
#ifdef WINE_STRICT
#define NULL_HANDLE NULL
#else
#define NULL_HANDLE 0
#endif

#ifdef DUMB_DEBUG
#include <stdio.h>
#define DEBUG(x) fprintf(stderr,x)
#else
#define DEBUG(x) 
#endif

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow )
{ 
    MSG msg;
    WNDCLASS wc;
    HWND hWnd;
    HACCEL haccel;        
    char appname[9];

    LoadString( hInst, IDS_APPNAME, appname, sizeof(appname));

    wc.style = 0;
    wc.lpfnWndProc = MainProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon( hInst, appname );
    wc.hCursor = LoadCursor( NULL_HANDLE, IDI_APPLICATION );
    wc.hbrBackground = (HBRUSH) GetStockObject( BLACK_BRUSH );
    wc.lpszMenuName = "MENU_WINEMINE";
    wc.lpszClassName = appname;
    
    if (!RegisterClass(&wc)) exit(1);
    hWnd = CreateWindow( appname, appname, 
        WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, 
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
        NULL_HANDLE, NULL_HANDLE, hInst, NULL );
    
    if (!hWnd) exit(1);
    
    ShowWindow( hWnd, cmdshow );
    UpdateWindow( hWnd );

    haccel = LoadAccelerators( hInst, appname );
    SetTimer( hWnd, ID_TIMER, 1000, NULL );

    while( GetMessage(&msg, NULL_HANDLE, 0, 0) ) {
        if (!TranslateAccelerator( hWnd, haccel, &msg ))
            TranslateMessage( &msg );
        
        DispatchMessage( &msg );
    }
    return msg.wParam;
}

LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    HMENU hMenu;        
    static BOARD board;     

    switch( msg ) {
    case WM_CREATE:         
        board.hInst = ((LPCREATESTRUCT) lParam)->hInstance;
        board.hWnd = hWnd;
        InitBoard( &board );
        CreateBoard( &board );
        return 0;

    case WM_PAINT:
      {
        HDC hMemDC;

        DEBUG("WM_PAINT\n");
        hdc = BeginPaint( hWnd, &ps );
        hMemDC = CreateCompatibleDC( hdc );

        DrawBoard( hdc, hMemDC, &ps, &board );

        DeleteDC( hMemDC );
        EndPaint( hWnd, &ps );

        return 0;
      }

    case WM_MOVE:
        DEBUG("WM_MOVE\n");
        board.pos.x = (unsigned) LOWORD(lParam);
        board.pos.y = (unsigned) HIWORD(lParam);    
        return 0;

    case WM_DESTROY:
        SaveBoard( &board );
        DestroyBoard( &board ); 
        PostQuitMessage( 0 );
        return 0;
    
    case WM_TIMER:
        if( board.status == PLAYING ) {
            board.time++;
                  RedrawWindow( hWnd, &board.timer_rect, NULL_HANDLE, 
                    RDW_INVALIDATE | RDW_UPDATENOW );      
        }
        return 0;

    case WM_LBUTTONDOWN:
        DEBUG("WM_LBUTTONDOWN\n");
        if( wParam & MK_RBUTTON )
            msg = WM_MBUTTONDOWN;        
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        SetCapture( hWnd );
        return 0;

    case WM_LBUTTONUP:
        DEBUG("WM_LBUTTONUP\n");
        if( wParam & MK_RBUTTON )
            msg = WM_MBUTTONUP;    
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        ReleaseCapture();
        return 0;

    case WM_RBUTTONDOWN:
        DEBUG("WM_RBUTTONDOWN\n");
        if( wParam & MK_LBUTTON ) {    
            board.press.x = 0;
            board.press.y = 0;    
            msg = WM_MBUTTONDOWN;
        }    
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        return 0;

    case WM_RBUTTONUP:
        DEBUG("WM_RBUTTONUP\n");
        if( wParam & MK_LBUTTON ) 
            msg = WM_MBUTTONUP;    
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        return 0;

    case WM_MBUTTONDOWN:
        DEBUG("WM_MBUTTONDOWN\n");
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        return 0;

    case WM_MBUTTONUP:
        DEBUG("WM_MBUTTONUP\n");
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        return 0;

    case WM_MOUSEMOVE:
    {
        if( (wParam & MK_LBUTTON) && (wParam & MK_RBUTTON) ) {
            msg = WM_MBUTTONDOWN;
        }
        else if( wParam & MK_LBUTTON ) {
            msg = WM_LBUTTONDOWN;
        }
        else {
            return 0;
        }

        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam),  msg );

        return 0;    
    } 

    case WM_COMMAND:
        switch(LOWORD(wParam)) {
        case IDM_NEW:
            CreateBoard( &board );
            return 0;

        case IDM_MARKQ:
            hMenu = GetMenu( hWnd );     
            board.IsMarkQ = !board.IsMarkQ;
            if( board.IsMarkQ )
                CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED );
            else 
                CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED );
            return 0;

        case IDM_BEGINNER:
            SetDifficulty( &board, BEGINNER );    
            CreateBoard( &board );
            return 0;

        case IDM_ADVANCED:
            SetDifficulty( &board, ADVANCED );    
            CreateBoard( &board );
            return 0;

        case IDM_EXPERT:
            SetDifficulty( &board, EXPERT );    
            CreateBoard( &board );
            return 0;

        case IDM_CUSTOM:
            SetDifficulty( &board, CUSTOM );
            CreateBoard( &board );
            return 0;

        case IDM_EXIT:
            SendMessage( hWnd, WM_CLOSE, 0, 0);
            return 0;

        case IDM_TIMES:
            DialogBoxParam( board.hInst, "DLG_TIMES", hWnd, 
                    TimesDlgProc, (LPARAM) &board);
            return 0;

        case IDM_ABOUT:
            DialogBox( board.hInst, "DLG_ABOUT", hWnd, AboutDlgProc );
            return 0;
        default:
            DEBUG("Unknown WM_COMMAND command message received\n");
            break;
        }
    } 
    return( DefWindowProc( hWnd, msg, wParam, lParam ));
}

void InitBoard( BOARD *p_board )
{
    HMENU hMenu;

    p_board->hMinesBMP = LoadBitmap( p_board->hInst, "mines");
    p_board->hFacesBMP = LoadBitmap( p_board->hInst, "faces");
    p_board->hLedsBMP = LoadBitmap( p_board->hInst, "leds");     
    
    LoadBoard( p_board );    
    
    if( p_board->pos.x < (unsigned) GetSystemMetrics( SM_CXFIXEDFRAME ))
        p_board->pos.x = GetSystemMetrics( SM_CXFIXEDFRAME );

    if( p_board->pos.x > (unsigned) (GetSystemMetrics( SM_CXSCREEN ) 
    - GetSystemMetrics( SM_CXFIXEDFRAME ))) {
        p_board->pos.x = GetSystemMetrics( SM_CXSCREEN ) 
        - GetSystemMetrics( SM_CXFIXEDFRAME );
    }

    if( p_board->pos.y < (unsigned) (GetSystemMetrics( SM_CYMENU )
    + GetSystemMetrics( SM_CYCAPTION )
    + GetSystemMetrics( SM_CYFIXEDFRAME ))) {
        p_board->pos.y = GetSystemMetrics( SM_CYMENU ) +
        GetSystemMetrics( SM_CYCAPTION ) +
        GetSystemMetrics( SM_CYFIXEDFRAME );
    }

    if( p_board->pos.y > (unsigned) (GetSystemMetrics( SM_CYSCREEN ) 
    - GetSystemMetrics( SM_CYFIXEDFRAME ))) {
        p_board->pos.y = GetSystemMetrics( SM_CYSCREEN )
        - GetSystemMetrics( SM_CYFIXEDFRAME );
    }
    
    hMenu = GetMenu( p_board->hWnd );
    CheckMenuItem( hMenu, IDM_BEGINNER + (unsigned) p_board->difficulty, 
            MF_CHECKED );
    if( p_board->IsMarkQ )
        CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED );
    else 
        CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED );
    CheckLevel( p_board );
}

void LoadBoard( BOARD *p_board ) 
{
    DWORD size;
    DWORD type;
    HKEY hkey;
    char data[16];
    char key_name[8];
    unsigned i;


    RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Wine\\WineMine", 
            0, KEY_QUERY_VALUE, &hkey );
    
    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Xpos", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS ) {
        p_board->pos.x = atoi( data );
    }
    else 
        p_board->pos.x = GetSystemMetrics( SM_CXFIXEDFRAME );

    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Ypos", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->pos.y = atoi( data );
    else 
        p_board->pos.y = GetSystemMetrics( SM_CYMENU )
        + GetSystemMetrics( SM_CYCAPTION ) 
        + GetSystemMetrics( SM_CYFIXEDFRAME );

    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Rows", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->rows = atoi( data );
    else
        p_board->rows = BEGINNER_ROWS;

    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Cols", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->cols = atoi( data );
    else
        p_board->cols = BEGINNER_COLS;    
    
    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Mines", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->mines = atoi( data );
    else 
        p_board->rows = BEGINNER_ROWS;

    size = sizeof( data );
    if( RegQueryValueEx( hkey, "Difficulty", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->difficulty = (DIFFICULTY) atoi( data );
    else 
        p_board->difficulty = BEGINNER;

    size = sizeof( data );
    if( RegQueryValueEx( hkey, "MarkQ", NULL, (LPDWORD) &type, 
            (LPBYTE) data, (LPDWORD) &size ) == ERROR_SUCCESS )
        p_board->IsMarkQ = atoi( data );
    else 
        p_board->IsMarkQ = TRUE;
        
    for( i = 0; i < 3; i++ ) {
        wsprintf( key_name, "Name%d", i );
        size = sizeof( data );
        if( RegQueryValueEx( hkey, key_name, NULL, (LPDWORD) &type, 
                (LPBYTE) data, 
                (LPDWORD) &size ) == ERROR_SUCCESS )
                    strncpy( p_board->best_name[i], data, sizeof( data ) );
        else 
            wsprintf( p_board->best_name[i], "Nobody");
    }
    
    for( i = 0; i < 3; i++ ) {
        wsprintf( key_name, "Time%d", i );
        size = sizeof( data );
        if( RegQueryValueEx( hkey, key_name, NULL, (LPDWORD) &type, 
                (LPBYTE) data, 
                (LPDWORD) &size ) == ERROR_SUCCESS )
            p_board->best_time[i] = atoi( data );
        else 
            p_board->best_time[i] = 999;
    }
    RegCloseKey( hkey );
}

void SaveBoard( BOARD *p_board )
{
    DWORD disp;
    HKEY hkey;
    SECURITY_ATTRIBUTES sa;
    unsigned i;
    char data[16];
    char key_name[8];
    
    if( RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
                "Software\\Wine\\WineMine", 0, NULL,
                REG_OPTION_NON_VOLATILE, KEY_WRITE, &sa, 
                &hkey, &disp ) != ERROR_SUCCESS)
        return;    

    wsprintf( data, "%d", p_board->pos.x );
    RegSetValueEx( hkey, "Xpos", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", p_board->pos.x );
    RegSetValueEx( hkey, "Ypos", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", (int) p_board->difficulty );
    RegSetValueEx( hkey, "Difficulty", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", p_board->rows );
    RegSetValueEx( hkey, "Rows", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", p_board->cols );
    RegSetValueEx( hkey, "Cols", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", p_board->mines );
    RegSetValueEx( hkey, "Mines", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    wsprintf( data, "%d", (int) p_board->IsMarkQ );
    RegSetValueEx( hkey, "MarkQ", 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );

    for( i = 0; i < 3; i++ ) {
        wsprintf( key_name, "Name%u", i );
        strncpy( data, p_board->best_name[i], sizeof( data ) );
        RegSetValueEx( hkey, key_name, 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );
    }

    for( i = 0; i < 3; i++ ) {
        wsprintf( key_name, "Time%u", i );
        wsprintf( data, "%d", p_board->best_time[i] );
        RegSetValueEx( hkey, key_name, 0, REG_SZ, (LPBYTE) data, strlen(data)+1 );
    }
    RegCloseKey( hkey );
}

void DestroyBoard( BOARD *p_board )
{
    DeleteObject( p_board->hFacesBMP );
    DeleteObject( p_board->hLedsBMP );
    DeleteObject( p_board->hMinesBMP );
}

void SetDifficulty( BOARD *p_board, DIFFICULTY difficulty )
{
    HMENU hMenu = GetMenu( p_board->hWnd );

    CheckMenuItem( hMenu, IDM_BEGINNER + p_board->difficulty, MF_UNCHECKED );
    p_board->difficulty = difficulty; 
    CheckMenuItem( hMenu, IDM_BEGINNER + difficulty, MF_CHECKED );
    
    switch( difficulty ) {
    case BEGINNER:    
        p_board->cols = BEGINNER_COLS;
        p_board->rows = BEGINNER_ROWS;
        p_board->mines = BEGINNER_MINES;
        break;

    case ADVANCED:    
        p_board->cols = ADVANCED_COLS;
        p_board->rows = ADVANCED_ROWS;
        p_board->mines = ADVANCED_MINES;
        break;

    case EXPERT:
        p_board->cols = EXPERT_COLS;
        p_board->rows = EXPERT_ROWS;
        p_board->mines = EXPERT_MINES;        
        break;    

    case CUSTOM:
        DialogBoxParam( p_board->hInst, "DLG_CUSTOM", p_board->hWnd, 
                CustomDlgProc, (LPARAM) p_board);
        break;    
    }
}

void CreateBoard( BOARD *p_board )
{
    int left, top, bottom, right, wnd_x, wnd_y, wnd_width, wnd_height;

    p_board->mb = MB_NONE;
    p_board->boxes_left = p_board->cols * p_board->rows - p_board->mines;
    p_board->num_flags = 0;
    
    CreateBoxes( p_board );

    p_board->width = p_board->cols * MINE_WIDTH + BOARD_WMARGIN * 2;
    
    p_board->height = p_board->rows * MINE_HEIGHT + LED_HEIGHT 
        + BOARD_HMARGIN * 3;

    wnd_x = p_board->pos.x - GetSystemMetrics( SM_CXFIXEDFRAME );
    wnd_y = p_board->pos.y - GetSystemMetrics( SM_CYMENU ) 
        - GetSystemMetrics( SM_CYCAPTION ) 
        - GetSystemMetrics( SM_CYFIXEDFRAME );
    wnd_width = p_board->width 
        + GetSystemMetrics( SM_CXFIXEDFRAME ) * 2;
    wnd_height = p_board->height 
        + GetSystemMetrics( SM_CYMENU ) 
        + GetSystemMetrics( SM_CYCAPTION ) 
        + GetSystemMetrics( SM_CYFIXEDFRAME ) * 2;

    /* setting the mines rectangle boundary */    
    left = BOARD_WMARGIN; 
    top = BOARD_HMARGIN * 2 + LED_HEIGHT; 
    right = left + p_board->cols * MINE_WIDTH;
    bottom = top + p_board->rows * MINE_HEIGHT;
    SetRect( &p_board->mines_rect, left, top, right, bottom );

    /* setting the face rectangle boundary */    
    left = p_board->width / 2 - FACE_WIDTH / 2;
    top = BOARD_HMARGIN;
    right = left + FACE_WIDTH;
    bottom = top + FACE_HEIGHT; 
    SetRect( &p_board->face_rect, left, top, right, bottom );
    
    /* setting the timer rectangle boundary */    
    left = BOARD_WMARGIN;
    top = BOARD_HMARGIN;
    right = left + LED_WIDTH * 3;
    bottom = top + LED_HEIGHT; 
    SetRect( &p_board->timer_rect, left, top, right, bottom );
        
    /* setting the counter rectangle boundary */    
    left =  p_board->width - BOARD_WMARGIN - LED_WIDTH * 3;
    top = BOARD_HMARGIN;
    right = p_board->width - BOARD_WMARGIN;
    bottom = top + LED_HEIGHT; 
    SetRect( &p_board->counter_rect, left, top, right, bottom );
        
    p_board->status = WAITING;
    p_board->face_bmp = SMILE_BMP;     
    p_board->time = 0;

    MoveWindow( p_board->hWnd, wnd_x, wnd_y, wnd_width, wnd_height, TRUE );
    RedrawWindow( p_board->hWnd, NULL, NULL_HANDLE, 
            RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE );
}


void CheckLevel( BOARD *p_board )
{
    if( p_board->rows < BEGINNER_ROWS )
        p_board->rows = BEGINNER_ROWS;

    if( p_board->rows > MAX_ROWS )
        p_board->rows = MAX_ROWS;
        
    if( p_board->cols < BEGINNER_COLS )
        p_board->cols = BEGINNER_COLS;

    if( p_board->cols > MAX_COLS )
        p_board->cols = MAX_COLS;

    if( p_board->mines < BEGINNER_MINES )
        p_board->mines = BEGINNER_MINES;               

    if( p_board->mines > p_board->cols * p_board->rows - 1 ) 
        p_board->mines = p_board->cols * p_board->rows - 1; 
}


void CreateBoxes( BOARD *p_board )
{
    int i, j;
    unsigned col, row;

    srand( (unsigned) time( NULL ) );

    /* Create the boxes...  
     * We actually create them with an empty border,
     * so special care doesn't have to be taken on the edges
     */
    
    for( col = 0; col <= p_board->cols + 1; col++ )
      for( row = 0; row <= p_board->rows + 1; row++ ) {
        p_board->box[col][row].IsPressed = FALSE;  
        p_board->box[col][row].IsMine = FALSE;
        p_board->box[col][row].FlagType = NORMAL;
        p_board->box[col][row].NumMines = 0;
      }

    /* create mines */
    i = 0;
     while( (unsigned) i < p_board->mines ) {
          col = (int) (p_board->cols * (float) rand() / RAND_MAX + 1);
          row = (int) (p_board->rows * (float) rand() / RAND_MAX + 1);

        if( !p_board->box[col][row].IsMine ) {
            i++;
            p_board->box[col][row].IsMine = TRUE;
        }
    }

    /*
     * Now we label the remaining boxes with the
     * number of mines surrounding them.
     */

    for( col = 1; col < p_board->cols + 1; col++ )
    for( row = 1; row < p_board->rows + 1; row++ ) {
        for( i = -1; i <= 1; i++ )
        for( j = -1; j <= 1; j++ ) {
            if( p_board->box[col + i][row + j].IsMine ) {
                p_board->box[col][row].NumMines++ ;
            }
        }
    }
}

void DrawMines ( HDC hdc, HDC hMemDC, BOARD *p_board )
{
    HGDIOBJ hOldObj;
    unsigned col, row;
    hOldObj = SelectObject (hMemDC, p_board->hMinesBMP);

    for( row = 1; row <= p_board->rows; row++ ) { 
      for( col = 1; col <= p_board->cols; col++ ) {
        DrawMine( hdc, hMemDC, p_board, col, row, FALSE );    
      }
    }
    SelectObject( hMemDC, hOldObj );
}

void DrawMine( HDC hdc, HDC hMemDC, BOARD *p_board, unsigned col, unsigned row, BOOL IsPressed )
{
    MINEBMP_OFFSET offset = BOX_BMP;

    if( col == 0 || col > p_board->cols || row == 0 || row > p_board->rows )
           return;    

    if( p_board->status == GAMEOVER ) {
        if( p_board->box[col][row].IsMine ) {
            switch( p_board->box[col][row].FlagType ) {
            case FLAG:
                offset = FLAG_BMP;
                break;
            case COMPLETE:
                offset = EXPLODE_BMP;                        
                break;
            case NORMAL:
                offset = MINE_BMP;
            }
        } else {
            switch( p_board->box[col][row].FlagType ) {    
            case QUESTION:
                offset = QUESTION_BMP;     
                break;
            case FLAG:
                offset = WRONG_BMP;
                break;
            case NORMAL:    
                offset = BOX_BMP;
                break;
            case COMPLETE:
                /* Do nothing */
                break;
            default:
                DEBUG("Unknown FlagType during game over in DrawMine\n"); 
                break;
            }
        } 
    } else {    /* WAITING or PLAYING */
        switch( p_board->box[col][row].FlagType ) {
        case QUESTION:
            if( !IsPressed )    
                offset = QUESTION_BMP;     
            else
                offset = QPRESS_BMP;    
            break;
        case FLAG:
            offset = FLAG_BMP;
            break;
        case NORMAL:    
            if( !IsPressed )
                offset = BOX_BMP;
            else 
                offset = MPRESS_BMP;
            break;
        case COMPLETE:
            /* Do nothing */
            break;
        default:
            DEBUG("Unknown FlagType while playing in DrawMine\n"); 
            break;
        }
    } 

    if( p_board->box[col][row].FlagType == COMPLETE  
        && !p_board->box[col][row].IsMine )
          offset = (MINEBMP_OFFSET) p_board->box[col][row].NumMines;
    
    BitBlt( hdc,
            (col - 1) * MINE_WIDTH + p_board->mines_rect.left,
            (row - 1) * MINE_HEIGHT + p_board->mines_rect.top,
            MINE_WIDTH, MINE_HEIGHT,
            hMemDC, 0, offset * MINE_HEIGHT, SRCCOPY );
}

void DrawLeds( HDC hdc, HDC hMemDC, BOARD *p_board, int number, int x, int y )
{
    HGDIOBJ hOldObj;
    unsigned led[3], i;
    int count;     

    count = number;
    if( count < 1000 ) {
        if( count >= 0 ) {
            led[0] = count / 100 ;
            count -= led[0] * 100;
        }
        else {
            led[0] = 10; /* negative sign */
            count = -count;
        }
        led[1] = count / 10;
        count -= led[1] * 10;
        led[2] = count;
    }
    else {
        for( i = 0; i < 3; i++ )
            led[i] = 10;
    }

    /* use unlit led if not playing */
    if( p_board->status == WAITING )
        for( i = 0; i < 3; i++ )
            led[i] = 11;  
    
    hOldObj = SelectObject (hMemDC, p_board->hLedsBMP);

    for( i = 0; i < 3; i++ ) {
        BitBlt( hdc,
            i * LED_WIDTH + x,
            y,
            LED_WIDTH,
            LED_HEIGHT,
            hMemDC, 
            0, 
            led[i] * LED_HEIGHT, 
            SRCCOPY);
    }
    
    SelectObject( hMemDC, hOldObj );
}


void DrawFace( HDC hdc, HDC hMemDC, BOARD *p_board )
{
    HGDIOBJ hOldObj; 

    hOldObj = SelectObject (hMemDC, p_board->hFacesBMP);

    BitBlt( hdc,
        p_board->face_rect.left,
        p_board->face_rect.top,
        FACE_WIDTH,
        FACE_HEIGHT,
        hMemDC, 0, p_board->face_bmp * FACE_HEIGHT, SRCCOPY);
    
    SelectObject( hMemDC, hOldObj );
}


void DrawBoard( HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, BOARD *p_board )
{
    RECT tmp_rect;    
    
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->counter_rect ) )    
        DrawLeds( hdc, hMemDC, p_board, p_board->mines - p_board->num_flags,
                  p_board->counter_rect.left,
                  p_board->counter_rect.top );

    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->timer_rect ) )    
        DrawLeds( hdc, hMemDC, p_board, p_board->time,
                  p_board->timer_rect.left, 
                  p_board->timer_rect.top );
    
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->face_rect ) )    
        DrawFace( hdc, hMemDC, p_board );
    
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->mines_rect ) )    
        DrawMines( hdc, hMemDC, p_board );
}    


void TestBoard( HWND hWnd, BOARD *p_board, unsigned x, unsigned y, int msg )
{
    POINT pt;
    
    pt.x = x;
    pt.y = y;

    if( PtInRect( &p_board->mines_rect, pt ) && p_board->status != GAMEOVER
    && p_board->status != WON ) 
        TestMines( p_board, pt, msg );
    else {
        UnpressBoxes( p_board, 
            p_board->press.x, 
            p_board->press.y );    
        p_board->press.x = 0;
        p_board->press.y = 0;
    }

    if( p_board->boxes_left == 0 ) {
        p_board->status = WON;
       
        if( p_board->difficulty != CUSTOM &&
                    p_board->time < p_board->best_time[p_board->difficulty] ) {
            p_board->best_time[p_board->difficulty] = p_board->time;
        
            DialogBoxParam( p_board->hInst, "DLG_CONGRATS", hWnd, 
                    CongratsDlgProc, (LPARAM) p_board);
    
            DialogBoxParam( p_board->hInst, "DLG_TIMES", hWnd, 
                    TimesDlgProc, (LPARAM) p_board);
        }
    }
    TestFace( p_board, pt, msg );    
}

void TestMines( BOARD *p_board, POINT pt, int msg )
{
    BOOL draw = TRUE;
    unsigned col, row;    

    col = (pt.x - p_board->mines_rect.left) / MINE_WIDTH + 1;
    row = (pt.y - p_board->mines_rect.top ) / MINE_HEIGHT + 1;
    
    switch ( msg ) {
    case WM_LBUTTONDOWN:
        if( p_board->press.x != col || p_board->press.y != row ) {
            UnpressBox( p_board, 
                    p_board->press.x, p_board->press.y );
            p_board->press.x = col;
            p_board->press.y = row;
            PressBox( p_board, col, row );    
        }    
        draw = FALSE;    
        break;

    case WM_LBUTTONUP:
        if( p_board->press.x != col || p_board->press.y != row )
            UnpressBox( p_board, 
                    p_board->press.x, p_board->press.y );
        p_board->press.x = 0;
        p_board->press.y = 0;
        if( p_board->box[col][row].FlagType != FLAG )
            p_board->status = PLAYING;    
        CompleteBox( p_board, col, row );
        break;

    case WM_MBUTTONDOWN:
        PressBoxes( p_board, col, row );
        draw = FALSE;
        break;

    case WM_MBUTTONUP:
        if( p_board->press.x != col || p_board->press.y != row )
            UnpressBoxes( p_board, 
                    p_board->press.x, p_board->press.y );
        p_board->press.x = 0;
        p_board->press.y = 0;
        CompleteBoxes( p_board, col, row );
        break;

    case WM_RBUTTONDOWN:
        AddFlag( p_board, col, row );
        p_board->status = PLAYING;    
        break;
    default:
        DEBUG("Unknown message type received in TestMines\n");
        break;
    }

    if( draw )
    {
        RedrawWindow( p_board->hWnd, NULL, NULL_HANDLE, 
            RDW_INVALIDATE | RDW_UPDATENOW );
    }
}    


void TestFace( BOARD *p_board, POINT pt, int msg )
{
    if( p_board->status == PLAYING || p_board->status == WAITING ) {
        if( msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN )
            p_board->face_bmp = OOH_BMP;
        else p_board->face_bmp = SMILE_BMP;
    }
    else if( p_board->status == GAMEOVER ) 
        p_board->face_bmp = DEAD_BMP;
    else if( p_board->status == WON ) 
            p_board->face_bmp = COOL_BMP;

    if( PtInRect( &p_board->face_rect, pt ) ) {        
        if( msg == WM_LBUTTONDOWN )     
            p_board->face_bmp = SPRESS_BMP;
        
        if( msg == WM_LBUTTONUP )     
            CreateBoard( p_board );    
    }

    RedrawWindow( p_board->hWnd, &p_board->face_rect, NULL_HANDLE, 
        RDW_INVALIDATE | RDW_UPDATENOW );
}


void CompleteBox( BOARD *p_board, unsigned col, unsigned row )
{
    int i, j;

    if( p_board->box[col][row].FlagType != COMPLETE && 
            p_board->box[col][row].FlagType != FLAG && 
            col > 0 && col < p_board->cols + 1 && 
            row > 0 && row < p_board->rows + 1 ) {
        p_board->box[col][row].FlagType = COMPLETE;
    
        if( p_board->box[col][row].IsMine ) {
            p_board->face_bmp = DEAD_BMP; 
            p_board->status = GAMEOVER;
        }
        else if( p_board->status != GAMEOVER ) 
            p_board->boxes_left--;

        if( p_board->box[col][row].NumMines == 0 ) 
        {
            for( i = -1; i <= 1; i++ )
            for( j = -1; j <= 1; j++ )
                CompleteBox( p_board, col + i, row + j  );
        }
    } 
}


void CompleteBoxes( BOARD *p_board, unsigned col, unsigned row )
{
    unsigned numFlags = 0;
    int i, j;

    if( p_board->box[col][row].FlagType == COMPLETE ) {
        for( i = -1; i <= 1; i++ )
          for( j = -1; j <= 1; j++ ) {
            if( p_board->box[col+i][row+j].FlagType == FLAG ) 
                numFlags++;
          }
    
        if( numFlags == p_board->box[col][row].NumMines ) {
            for( i = -1; i <= 1; i++ )
              for( j = -1; j <= 1; j++ ) {
                if( p_board->box[col+i][row+j].FlagType != FLAG ) 
                    CompleteBox( p_board, col+i, row+j );
              }
        }
    }
}


void AddFlag( BOARD *p_board, unsigned col, unsigned row )
{
    if( p_board->box[col][row].FlagType != COMPLETE ) {
        switch( p_board->box[col][row].FlagType ) {
        case FLAG:
            if( p_board->IsMarkQ )
                p_board->box[col][row].FlagType = QUESTION;
            else 
                p_board->box[col][row].FlagType = NORMAL;
            p_board->num_flags--;
            break;

        case QUESTION:
            p_board->box[col][row].FlagType = NORMAL;
            break;
        
        default:
            p_board->box[col][row].FlagType = FLAG;
            p_board->num_flags++;
        }    
    }    
}


void PressBox( BOARD *p_board, unsigned col, unsigned row )
{
    HDC hdc;      
    HGDIOBJ hOldObj; 
    HDC hMemDC;

    hdc = GetDC( p_board->hWnd );
    hMemDC = CreateCompatibleDC( hdc );
    hOldObj = SelectObject (hMemDC, p_board->hMinesBMP);

    DrawMine( hdc, hMemDC, p_board, col, row, TRUE );

    SelectObject( hMemDC, hOldObj ); 
    DeleteDC( hMemDC );
    ReleaseDC( p_board->hWnd, hdc );
}


void PressBoxes( BOARD *p_board, unsigned col, unsigned row )
{
    int i, j;

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        p_board->box[col + i][row + j].IsPressed = TRUE;    
        PressBox( p_board, col + i, row + j );
    }

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        if( !p_board->box[p_board->press.x + i][p_board->press.y + j].IsPressed )    
            UnpressBox( p_board, p_board->press.x + i, p_board->press.y + j );
    }

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        p_board->box[col + i][row + j].IsPressed = FALSE;    
        PressBox( p_board, col + i, row + j );
    }

    p_board->press.x = col;
    p_board->press.y = row;    
}


void UnpressBox( BOARD *p_board, unsigned col, unsigned row )
{
    HDC hdc; 
    HGDIOBJ hOldObj; 
    HDC hMemDC;

    hdc = GetDC( p_board->hWnd );
    hMemDC = CreateCompatibleDC( hdc );
    hOldObj = SelectObject( hMemDC, p_board->hMinesBMP );

    DrawMine( hdc, hMemDC, p_board, col, row, FALSE );

    SelectObject( hMemDC, hOldObj ); 
    DeleteDC( hMemDC );
    ReleaseDC( p_board->hWnd, hdc );
}


void UnpressBoxes( BOARD *p_board, unsigned col, unsigned row )
{
    int i, j;    
    
    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        UnpressBox( p_board, col + i, row + j );
      }
}
