/*
 * WineMine (main.c)
 * 
 * Copyright 2000 Joshua Thielen <jt85296@ltu.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#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 );
      }
}
