import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.swing.*;
import javax.imageio.ImageIO;

/**
 * IgoGraphicPanel クラスは、グラフィック描画の碁盤を提供します。
 * @author Jiro Suzuki
 */
public class IgoGraphicPanel extends IgoPanel{

    private static final int BOX=32;
    private static final int ROSU=19;

    private IntBoard intBoard;
    private BufferedImage board;
    private BufferedImage blackStone;
    private BufferedImage whiteStone;
    private BufferedImage lastPoint;

    private IgoModel controller;
    private boolean isPutable;

    /**
     * 石が置かれていない碁盤イメージのインスタンスを生成します。
     */
    IgoGraphicPanel(){
        intBoard=new IntBoard();

        board=new BufferedImage(602,602,BufferedImage.TYPE_3BYTE_BGR);
        try{
            board=ImageIO.read(new File("碁盤.png"));
        }catch(Exception e) {
            e.printStackTrace();
            board = null;
        }

        blackStone = new BufferedImage(100,100,BufferedImage.TYPE_3BYTE_BGR);
        try{
            blackStone=ImageIO.read(new File("黒石.png"));
        } catch (Exception e) {
            e.printStackTrace();
            blackStone = null;
        }

        whiteStone = new BufferedImage(100,100,BufferedImage.TYPE_3BYTE_BGR);
        try{
            whiteStone=ImageIO.read(new File("白石.png"));
        } catch (Exception e) {
            e.printStackTrace();
            whiteStone = null;
        }

        lastPoint = new BufferedImage(100,100,BufferedImage.TYPE_3BYTE_BGR);
        try{
            lastPoint=ImageIO.read(new File("最終手.gif"));
        } catch (Exception e) {
            e.printStackTrace();
            lastPoint = null;
        }

        isPutable=false;
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent me){
                if(isPutable){
                    boolean isOnBoardRow=false;
                    boolean isOnBoardCol=false;
                    int x=me.getX();
                    int y=me.getY();
                    int minX,minY,row,col;
                    for(row=0;row<ROSU;row++){
                        minY=row*BOX+11;
                        if(y>=minY && y<minY+BOX){
                            isOnBoardRow=true;
                            break;
                        }
                    }
                    for(col=0;col<ROSU;col++){
                        minX=col*BOX+11;
                        if(x>=minX && x<minX+BOX){
                            isOnBoardCol=true;
                            break;
                        }
                    }
                    if(isOnBoardRow && isOnBoardCol){
                        controller.putStone(row,col);
                    }
                }
            }
        });

    }

    /**
     * グラフィック描画の碁盤を描画します。
     * @param g 保護対象の Graphics オブジェクト
     */
    public void paintComponent(Graphics g){ 
        super.paintComponent(g);

        //碁盤の描画
        g.drawImage(board,0,0,this);

        //石の描画
        int[][] ban=intBoard.getIntBoard();
        for(int row=0;row<ROSU;row++){
            for(int col=0;col<ROSU;col++){
                switch (ban[row][col]){
                    case 1:  //黒石の描画
                        g.drawImage(blackStone,col*BOX+11,row*BOX+11,this);
                        break;
                    case 2:  //白石の描画
                        g.drawImage(whiteStone,col*BOX+11,row*BOX+11,this);
                        break;
                    case 11: //最終手黒の描画
                        g.drawImage(blackStone,col*BOX+11,row*BOX+11,this);
                        g.drawImage(lastPoint,col*BOX+11,row*BOX+11,this);
                        break;
                    case 12:  //最終手白の描画
                        g.drawImage(whiteStone,col*BOX+11,row*BOX+11,this);
                        g.drawImage(lastPoint,col*BOX+11,row*BOX+11,this);
                        break;
                }
            }
        }
    }

    /**
     * グラフィック描画の碁盤を更新します。
     * @param intBoard 碁盤に見立てた行列に、石の色を配置した碁盤データ
     */
    public void update(IntBoard intBoard){
        this.intBoard=intBoard;
        repaint();
    }

    /**
     * コントローラーを設定します。
     * @param controller コントローラー
     */
    public void setIgoGameController(IgoModel controller){
        this.controller=controller;
        isPutable=true;
    }

}