public void paint(Graphics graphics) {
    super.paint(graphics);
    int size = getFont().getSize();
    for (int y = 0; y < Chess.NUM_OF_ROWS; y++) {
      for (int x = 0; x < Chess.NUM_OF_COLS; x++) {
        //                System.out.println(y + " " + x);
        int sqi =
            (m_bottom == Chess.WHITE
                ? Chess.coorToSqi(x, Chess.NUM_OF_ROWS - y - 1)
                : Chess.coorToSqi(Chess.NUM_OF_COLS - x - 1, y));
        if (Chess.isWhiteSquare(sqi)) {
          graphics.setColor(m_whiteSquareColor);
          graphics.fillRect(x * size, y * size, size, size);
        } else {
          graphics.setColor(m_blackSquareColor);
          graphics.fillRect(x * size, y * size, size, size);
        }
        int stone = (sqi == m_draggedFrom ? Chess.NO_STONE : m_position.getStone(sqi));
        graphics.setColor(Chess.stoneToColor(stone) == Chess.WHITE ? m_whiteColor : m_blackColor);
        if (m_solidStones) stone = Chess.pieceToStone(Chess.stoneToPiece(stone), Chess.BLACK);
        //                graphics.drawString(getStringForStone(stone, Chess.isWhiteSquare(sqi)), x
        // * size, (y + 1) * size);
        graphics.drawString(getStringForStone(stone, true), x * size, (y + 1) * size);
      }
    }

    if (m_draggedStone != Chess.NO_STONE) {
      graphics.setColor(
          Chess.stoneToColor(m_draggedStone) == Chess.WHITE ? m_whiteColor : m_blackColor);
      graphics.drawString(
          getStringForStone(m_draggedStone, true), m_draggedX - size / 2, m_draggedY + size / 2);
    }
  }
 public void mousePressed(MouseEvent e) {
   if (m_positionMotionListener == null) return;
   m_draggedFrom = getSquareForEvent(e);
   if (m_positionMotionListener.allowDrag(m_position, m_draggedFrom)) {
     m_draggedStone = m_position.getStone(m_draggedFrom);
     m_draggedX = e.getX();
     m_draggedY = e.getY();
     m_draggedPartnerSqi = m_positionMotionListener.getPartnerSqi(m_position, m_draggedFrom);
     // TODO mark m_draggedPartnerSqi
     repaint();
   } else {
     m_positionMotionListener.squareClicked(m_position, m_draggedFrom, e);
     m_draggedFrom = Chess.NO_SQUARE;
   }
 }
  /**
   * Create a new position view.
   *
   * @param position the position to display
   * @param bottomPlayer the player at the lower edge
   */
  public PositionView(AbstractMutablePosition position, int bottomPlayer) {
    m_position = position;
    m_bottom = bottomPlayer;
    m_showSqiEP = false;
    m_whiteSquareColor = new Color(128, 128, 192);
    m_blackSquareColor = new Color(0, 0, 192);
    m_whiteColor = Color.WHITE;
    m_blackColor = Color.BLACK;
    m_solidStones = true;
    setFont(new Font("Chess Cases", Font.PLAIN, 32));

    m_draggedStone = Chess.NO_STONE;
    m_draggedFrom = Chess.NO_SQUARE;
    m_draggedPartnerSqi = Chess.NO_SQUARE;
    m_positionMotionListener = null;
    m_position.addPositionListener(this); // TODO: when do we remove it?
    addMouseListener(this);
    addMouseMotionListener(this);
  }
 /**
  * Determines whether or not the en passant square should be marked. NOT YET IMPLEMENTED.
  *
  * @param showSqiEP whether or not to mark the en passant square
  */
 public void setShowSqiEP(boolean showSqiEP) {
   m_showSqiEP = showSqiEP;
   sqiEPChanged(m_position.getSqiEP());
 }