// Initialise the graphic board
GraphicBoard::GraphicBoard
(
    wxWindow *parent,
    wxWindowID id,
    const wxPoint& point,
    const wxSize& size,
    int nbr_pixels
)   : wxControl( parent, id, point, size, BORDER_COMMON )
{
    pickup_file    = 0;
    pickup_rank    = 0;
    pickup_point.x = 0;
    pickup_point.y = 0;
    sliding = false;
    BoardBitmap40 bm1;
    BoardBitmap54 bm2;
    BoardBitmap   *bm;
    if( nbr_pixels == 40 )
        bm = &bm1;
    else
        bm = &bm2;
    white_king_mask   = bm->GetWhiteKingMask();
    white_queen_mask  = bm->GetWhiteQueenMask();
    white_knight_mask = bm->GetWhiteKnightMask();
    white_bishop_mask = bm->GetWhiteBishopMask();
    white_rook_mask   = bm->GetWhiteRookMask();
    white_pawn_mask   = bm->GetWhitePawnMask();
    black_king_mask   = bm->GetBlackKingMask();
    black_queen_mask  = bm->GetBlackQueenMask();
    black_knight_mask = bm->GetBlackKnightMask();
    black_bishop_mask = bm->GetBlackBishopMask();
    black_rook_mask   = bm->GetBlackRookMask();
    black_pawn_mask   = bm->GetBlackPawnMask();

    my_chess_bmp = wxBitmap( bm->GetXpm() );
	BITMAP info;

	// Orientation
	normal_orientation = true;

	// Highlights squares
	ClearHighlight1();
	ClearHighlight2();

	// Get dimensions of the wxBitmap
	//my_chess_bmp.GetBitmap( &info ); // return ::GetObject(m_hObject, sizeof(BITMAP), pBitMap);
    ::GetObject( my_chess_bmp.GetHBITMAP(), sizeof(BITMAP), &info ); //@@
    //this->board_rect = board_rect;
	width_bytes  = info.bmWidthBytes;   // bytes
	width        = info.bmWidth;        // pixels
  	assert( (info.bmWidthBytes%info.bmWidth) == 0 );
	density      = info.bmWidthBytes/info.bmWidth;
	height       = info.bmHeight;
	xborder	     = (width_bytes%8) / 2;
	yborder	     = (height%8) / 2;
  	DebugPrintf(( "width_bytes=%lu, width=%lu, height=%lu\n",
						(unsigned long)info.bmWidthBytes,
						(unsigned long)info.bmWidth,
						(unsigned long)info.bmHeight ));

	// Allocate an image of the board
	buf_board = new byte[width_bytes*height];
    memset( buf_board, 0, width_bytes*height);
	
	// Allocate an image of the box (pieces off the board)
	buf_box   = new byte[width_bytes*height];

	// Read the initial position displayed on the bitmap
	//my_chess_bmp.GetBitmapBits( width_bytes*height, buf_board );   //@@
    /*int ret=*/ ::GetBitmapBits((HBITMAP)(my_chess_bmp.GetHBITMAP()), width_bytes*height, buf_board );
    //DebugPrintf(( "::GetBitmapBits() returns %d\n",ret));

	// Read from position on left below (the .bmp resource) into the box
	//  at right. The box has all the piece/colour combinations we need
    //  (eg only two pawns from each side are needed, one of each colour).
    //  Also note that the two squares marked with * are the two empty
	//	squares (one of each colour) we need.
	//
	//	"rNbQkBnR"		 "rnbqkbnr"
	//	"Pp*qK*  "		 "pp      "
	//	"        "		 "        "
	//	"        "		 "   qk   "
	//	"        "		 "   QK   "
	//	"        "		 "**      "
	//	"        "		 "PP      "
	//	"        "		 "RNBQKBNR"
	//
	// Store these pieces from the board to their fixed
	//  positions in the 'box'
	Get( 'c','7', 'b','8' );  // preload black squares in the box
	Get( 'c','7', 'd','8' );
	Get( 'c','7', 'f','8' );
	Get( 'c','7', 'h','8' );
	Get( 'c','7', 'a','7' );
	Get( 'c','7', 'e','5' );
	Get( 'c','7', 'd','4' );
	Get( 'c','7', 'b','2' );
	Get( 'c','7', 'a','1' );
	Get( 'c','7', 'c','1' );
	Get( 'c','7', 'e','1' );
	Get( 'c','7', 'g','1' );
	Get( 'f','7', 'a','8' );  // preload white squares in the box
	Get( 'f','7', 'c','8' );
	Get( 'f','7', 'e','8' );
	Get( 'f','7', 'g','8' );
	Get( 'f','7', 'b','7' );
	Get( 'f','7', 'd','5' );
	Get( 'f','7', 'e','4' );
	Get( 'f','7', 'a','2' );
	Get( 'f','7', 'b','1' );
	Get( 'f','7', 'd','1' );
	Get( 'f','7', 'f','1' );
	Get( 'f','7', 'h','1' );
    
	Get( 'h','8', 'h','1', white_rook_mask );
	Get( 'b','8', 'g','1', white_knight_mask );
	Get( 'f','8', 'f','1', white_bishop_mask );
	Get( 'e','7', 'e','1', white_king_mask );
	Get( 'd','8', 'd','1', white_queen_mask );
	Get( 'f','8', 'c','1', white_bishop_mask );
    Get( 'b','8', 'b','1', white_knight_mask );
	Get( 'h','8', 'a','1', white_rook_mask );
	
	Get( 'a','7', 'a','2', white_pawn_mask );    // Only need pawns on a2, b2
	Get( 'a','7', 'b','2', white_pawn_mask );

	Get( 'b','7', 'a','7', black_pawn_mask );    // Only need pawns on a7, b7
	Get( 'b','7', 'b','7', black_pawn_mask );

	Get( 'a','8', 'h','8', black_rook_mask );
	Get( 'g','8', 'g','8', black_knight_mask );
	Get( 'c','8', 'f','8', black_bishop_mask );
	Get( 'e','8', 'e','8', black_king_mask );
	Get( 'd','7', 'd','8', black_queen_mask );
	Get( 'c','8', 'c','8', black_bishop_mask );
    Get( 'g','8', 'b','8', black_knight_mask );
	Get( 'a','8', 'a','8', black_rook_mask );

	Get( 'c','7', 'a','3' );  // empty black square
	Get( 'f','7', 'b','3' );  // empty white square
//	Get( 'c','3', 'c','3' );  // square with cross 
//	Get( 'd','3', 'd','3' );  // square with cross 
    
	Get( 'e','8', 'e','5', black_king_mask  );  // Black king on black square
	Get( 'e','7', 'e','4', white_king_mask  );  // White king on white square
	Get( 'd','7', 'd','5', black_queen_mask );  // Black queen on white square
	Get( 'd','8', 'd','4', white_queen_mask );  // White queen on black square
}
// Initialise the graphic board
GraphicBoard::GraphicBoard
(
    wxWindow *parent,
    wxWindowID id,
    const wxPoint& point,
    const wxSize& size,
    int nbr_pixels
)   : wxControl( parent, id, point, size, BORDER_COMMON )
{
    pickup_file    = 0;
    pickup_rank    = 0;
    pickup_point.x = 0;
    pickup_point.y = 0;
    sliding = false;
    BoardBitmap40 bm1;
    BoardBitmap54 bm2;
    BoardBitmap   *bm;
    if( nbr_pixels == 40 )
        bm = &bm1;
    else
        bm = &bm2;
    white_king_mask   = bm->GetWhiteKingMask();
    white_queen_mask  = bm->GetWhiteQueenMask();
    white_knight_mask = bm->GetWhiteKnightMask();
    white_bishop_mask = bm->GetWhiteBishopMask();
    white_rook_mask   = bm->GetWhiteRookMask();
    white_pawn_mask   = bm->GetWhitePawnMask();
    black_king_mask   = bm->GetBlackKingMask();
    black_queen_mask  = bm->GetBlackQueenMask();
    black_knight_mask = bm->GetBlackKnightMask();
    black_bishop_mask = bm->GetBlackBishopMask();
    black_rook_mask   = bm->GetBlackRookMask();
    black_pawn_mask   = bm->GetBlackPawnMask();

    my_chess_bmp = wxBitmap( bm->GetXpm() );

	// Orientation
	normal_orientation = true;

	// Highlights squares
	ClearHighlight1();
	ClearHighlight2();

#ifdef THC_WINDOWS
	BITMAP info;
	// Get dimensions of the wxBitmap
	//my_chess_bmp.GetBitmap( &info ); // return ::GetObject(m_hObject, sizeof(BITMAP), pBitMap);
    ::GetObject( my_chess_bmp.GetHBITMAP(), sizeof(BITMAP), &info ); //@@
    //this->board_rect = board_rect;
	width_bytes  = info.bmWidthBytes;   // bytes
	width        = info.bmWidth;        // pixels
	height       = info.bmHeight;
  	cprintf( "width_bytes=%lu, width=%lu, height=%lu\n",
						(unsigned long)info.bmWidthBytes,
						(unsigned long)info.bmWidth,
						(unsigned long)info.bmHeight );
	density      = info.bmWidthBytes/info.bmWidth;
#else
    height = my_chess_bmp.GetHeight();
#ifdef THC_MAC
    wxAlphaPixelData bmdata(my_chess_bmp);
#else
    wxNativePixelData bmdata(my_chess_bmp);
#endif
    height = bmdata.GetHeight();
    width  = bmdata.GetWidth();
    wxPoint x = bmdata.GetOrigin();
    wxSize  z = bmdata.GetSize();
    int row_stride = bmdata.GetRowStride();
    if( row_stride < 0 )
        row_stride = 0-row_stride;
    cprintf( "x=%d,%d z=%d,%d, height=%d, width=%d, row_stride=%d\n",x.x,x.y,z.x,z.y,height,width,row_stride);
    width_bytes = row_stride;
    if( width )
	    density      = width_bytes/width;
#endif
	xborder	     = (width_bytes%8) / 2;
	yborder	     = (height%8) / 2;

	// Allocate an image of the board
	buf_board = new byte[width_bytes*height];
    memset( buf_board, 0, width_bytes*height);
	
	// Allocate an image of the box (pieces off the board)
	buf_box   = new byte[width_bytes*height];

	// Read the initial position displayed on the bitmap
#ifdef THC_WINDOWS
	//my_chess_bmp.GetBitmapBits( width_bytes*height, buf_board );   //@@
    int ret= ::GetBitmapBits((HBITMAP)(my_chess_bmp.GetHBITMAP()), width_bytes*height, buf_board );
    //dbg_printf( "::GetBitmapBits() returns %d\n",ret);
#else
#ifdef THC_MAC
    wxAlphaPixelData::Iterator p(bmdata);
#else
    wxNativePixelData::Iterator p(bmdata);
#endif
    byte *dst = buf_board;
    for( int i=0; i<height*width; i++ )
    {
#ifdef THC_MAC
        *dst++ = p.Alpha();
#endif
        *dst++ = p.Red();
        *dst++ = p.Green();
        *dst++ = p.Blue();
        p++;
    }
#endif

	// Read from position on left below (the .bmp resource) into the box
	//  at right. The box has all the piece/colour combinations we need
    //  (eg only two pawns from each side are needed, one of each colour).
    //  Also note that the two squares marked with * are the two empty
	//	squares (one of each colour) we need.
	//
	//	"rNbQkBnR"		 "rnbqkbnr"
	//	"Pp*qK*  "		 "pp      "
	//	"        "		 "        "
	//	"        "		 "   qk   "
	//	"        "		 "   QK   "
	//	"        "		 "**      "
	//	"        "		 "PP      "
	//	"        "		 "RNBQKBNR"
	//
	// Store these pieces from the board to their fixed
	//  positions in the 'box'
	Get( 'c','7', 'b','8' );  // preload black squares in the box
	Get( 'c','7', 'd','8' );
	Get( 'c','7', 'f','8' );
	Get( 'c','7', 'h','8' );
	Get( 'c','7', 'a','7' );
	Get( 'c','7', 'e','5' );
	Get( 'c','7', 'd','4' );
	Get( 'c','7', 'b','2' );
	Get( 'c','7', 'a','1' );
	Get( 'c','7', 'c','1' );
	Get( 'c','7', 'e','1' );
	Get( 'c','7', 'g','1' );
	Get( 'f','7', 'a','8' );  // preload white squares in the box
	Get( 'f','7', 'c','8' );
	Get( 'f','7', 'e','8' );
	Get( 'f','7', 'g','8' );
	Get( 'f','7', 'b','7' );
	Get( 'f','7', 'd','5' );
	Get( 'f','7', 'e','4' );
	Get( 'f','7', 'a','2' );
	Get( 'f','7', 'b','1' );
	Get( 'f','7', 'd','1' );
	Get( 'f','7', 'f','1' );
	Get( 'f','7', 'h','1' );
    
	Get( 'h','8', 'h','1', white_rook_mask );
	Get( 'b','8', 'g','1', white_knight_mask );
	Get( 'f','8', 'f','1', white_bishop_mask );
	Get( 'e','7', 'e','1', white_king_mask );
	Get( 'd','8', 'd','1', white_queen_mask );
	Get( 'f','8', 'c','1', white_bishop_mask );
    Get( 'b','8', 'b','1', white_knight_mask );
	Get( 'h','8', 'a','1', white_rook_mask );
	
	Get( 'a','7', 'a','2', white_pawn_mask );    // Only need pawns on a2, b2
	Get( 'a','7', 'b','2', white_pawn_mask );

	Get( 'b','7', 'a','7', black_pawn_mask );    // Only need pawns on a7, b7
	Get( 'b','7', 'b','7', black_pawn_mask );

	Get( 'a','8', 'h','8', black_rook_mask );
	Get( 'g','8', 'g','8', black_knight_mask );
	Get( 'c','8', 'f','8', black_bishop_mask );
	Get( 'e','8', 'e','8', black_king_mask );
	Get( 'd','7', 'd','8', black_queen_mask );
	Get( 'c','8', 'c','8', black_bishop_mask );
    Get( 'g','8', 'b','8', black_knight_mask );
	Get( 'a','8', 'a','8', black_rook_mask );

	Get( 'c','7', 'a','3' );  // empty black square
	Get( 'f','7', 'b','3' );  // empty white square
//	Get( 'c','3', 'c','3' );  // square with cross 
//	Get( 'd','3', 'd','3' );  // square with cross 
    
	Get( 'e','8', 'e','5', black_king_mask  );  // Black king on black square
	Get( 'e','7', 'e','4', white_king_mask  );  // White king on white square
	Get( 'd','7', 'd','5', black_queen_mask );  // Black queen on white square
	Get( 'd','8', 'd','4', white_queen_mask );  // White queen on black square
}