/*
 * 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"


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, 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, NULL, hInst, NULL );
    
    if (!hWnd) exit(1);
    
    ShowWindow( hWnd, cmdshow );
    UpdateWindow( hWnd );

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

    while( GetMessage(&msg, NULL, 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 = BeginPaint( hWnd, &ps );
        DrawBoard( hdc, &ps, &board );
        EndPaint( hWnd, &ps );
        return 0;

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

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

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

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

    case WM_RBUTTONDOWN:
        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:
        if( wParam & MK_LBUTTON ) 
            msg = WM_MBUTTONUP;    
        TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam), msg );
        return 0;

    case WM_MOUSEMOVE:
        if( wParam & MK_LBUTTON )
            TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam),  WM_LBUTTONDOWN );
        if( (wParam & MK_LBUTTON) && (wParam & MK_RBUTTON) )
            TestBoard( hWnd, &board, LOWORD(lParam), HIWORD(lParam),  WM_MBUTTONDOWN );
        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;
        }
        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.x = atoi( data );
    else 
        p_board->pos.x = 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\\The WINE team\\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, 
            sizeof( data ));

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

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

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

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

    wsprintf( data, "%d", p_board->mines );
    RegSetValueEx( hkey, "Mines", 0, REG_SZ, (LPBYTE) data, 
            sizeof( data ));
    
    wsprintf( data, "%d", (int) p_board->IsMarkQ );
    RegSetValueEx( hkey, "MarkQ", 0, REG_SZ, (LPBYTE) data, 
            sizeof( data ));

    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, 
                sizeof( data ));
    }

    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, 
                sizeof( data ));
    }
    RegCloseKey( hkey );
}

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, 
            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, BOARD *p_board )
{
    unsigned col, row;

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

void DrawMine( HDC hdc, BOARD *p_board, unsigned col, unsigned row, BOOL IsPressed )
{
    BITMAP bm ;
    HDC    hMemDC ;
    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;
            }
        } 
    } 
    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;
        }
    } 

    if( p_board->box[col][row].FlagType == COMPLETE  
    && !p_board->box[col][row].IsMine )
          offset = (MINEBMP_OFFSET) p_board->box[col][row].NumMines;
    
    hMemDC = CreateCompatibleDC( hdc );
    SelectObject (hMemDC, p_board->hMinesBMP);
    GetObject (p_board->hMinesBMP, sizeof (BITMAP), (PSTR) &bm);

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

    DeleteDC( hMemDC );
}

void DrawLeds( HDC hdc, BOARD *p_board, int number, int x, int y )
{
    HDC hMemDC;
    BITMAP bm ;
    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;  
    
    hMemDC = CreateCompatibleDC( hdc );
    SelectObject (hMemDC, p_board->hLedsBMP);
    GetObject (p_board->hLedsBMP, sizeof (BITMAP), (PSTR) &bm);
    
    for( i = 0; i < 3; i++ ) {
        BitBlt( hdc,
            i * LED_WIDTH + x,
            y,
            LED_WIDTH,
            LED_HEIGHT,
            hMemDC, 
            0, 
            led[i] * LED_HEIGHT, 
            SRCCOPY);
    }
    DeleteDC( hMemDC );
}


void DrawFace( HDC hdc, BOARD *p_board )
{
    BITMAP bm ;
    HDC    hMemDC ;
    
    hMemDC = CreateCompatibleDC( hdc );
    SelectObject (hMemDC, p_board->hFacesBMP);
    GetObject (p_board->hFacesBMP, sizeof (BITMAP), (PSTR) &bm);

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

    DeleteDC( hMemDC );
}


void DrawBoard( HDC hdc, PAINTSTRUCT *ps, BOARD *p_board )
{
    RECT tmp_rect;    
    
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->counter_rect ) )    
        DrawLeds( hdc, 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, 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, p_board );
    
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->mines_rect ) )    
        DrawMines( hdc, 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 );
        break;
    }
    if( draw )
    {
        RedrawWindow( p_board->hWnd, NULL, NULL, 
            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;
    }

    if( p_board->status == GAMEOVER ) 
        p_board->face_bmp = DEAD_BMP;

    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, 
        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;      

    hdc = GetDC( p_board->hWnd );
        DrawMine( hdc, p_board, col, row, TRUE );
    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; 

    hdc = GetDC( p_board->hWnd );
        DrawMine( hdc, p_board, col, row, FALSE );
    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 );
    }
}
