

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;


/**
 *
 * @author Francisco Matesanz & Benjamin Nogal
 */
public class listenerButtonXY implements MouseListener {

    final int i;
    final int j;
    final slot[][] board;
    final boolean[][][] errorBoard; //board to take note about how many errors have each box
    final int ROW = 0;
    final int COL = 1;
    final int SQR = 2;
    final JButton[][] button;

    public listenerButtonXY(int i, int j, slot[][] board, JButton[][] button, boolean[][][] errorBoard) {
        this.i = i;
        this.j = j;
        this.board = board;
        this.button = button;
        this.errorBoard = errorBoard;
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
        if (board[i][j].aviable == true) {
            if (MouseEvent.BUTTON1 == e.getButton()) {

                board[i][j].value = (byte) ((board[i][j].value + 1) % 10);
                if (board[i][j].value != 0) {
                    button[i][j].setText(Integer.toString(board[i][j].value));
                } else {
                    button[i][j].setText("X");
                }
            } else if (MouseEvent.BUTTON3 == e.getButton()) {
                board[i][j].value = (byte) (board[i][j].value - 1);
                if (board[i][j].value < 0) {
                    board[i][j].value = 9;
                }
                if (board[i][j].value != 0) {
                    button[i][j].setText(Integer.toString(board[i][j].value));
                } else {
                    button[i][j].setText("X");
                }
            } else if (MouseEvent.BUTTON2 == e.getButton()) {
                board[i][j].value = 0;
                button[i][j].setText("X");
            }
            checkGame();
        }
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    private void checkGame() {

        //First we check the row
        checkRow();
        //Second we check the col
        checkCol();
        //Finally we check the square
        checkBigBox();
         
        //We force to repaint the button
        reSetColourButtons();
        //We check if game is over
        checkFinal();       
        button[i][j].repaint();

    }

    private void resetArray(byte[] array) {
        for (int x = 0; x < 10; x++) {
            array[x] = (byte) 0;
        }

    }

    private void reSetColourButtons() {
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {
                if ((errorBoard[x][y][ROW] == false) 
                		&& (errorBoard[x][y][COL] == false) 
                		&& (errorBoard[x][y][SQR] == false)) 
                {
                    if (board[x][y].aviable == true) {
                        if (((x < 3) && (y < 3)) || (x > 5) && (y < 3) 
                        		|| ((x < 3) && (y > 5)) || ((x > 5) && (y > 5)) 
                        		|| (((x > 2) && (x < 6)) && ((y > 2) && (y < 6)))) 
                        {
                            button[x][y].setBackground(Color.CYAN);
                        } else {
                            button[x][y].setBackground(Color.BLUE);
                        }
                    }
                    else
                    	button[x][y].setBackground(Color.GRAY);
                }
                else
                {
                    //if (board[x][y].aviable == true) {
                        button[x][y].setBackground(Color.RED);
                    //}
                }
            }
        }
    }

    private void checkRow() {
        byte[] boxToCheck = new byte[10];
        int x;
        int y;
        resetArray(boxToCheck);
        y = i;
        //We count how many numbers are of each one
        for (x = 0; x < 9; x++) { //9 NO included because it is boxes
            boxToCheck[board[y][x].value] += 1;
            errorBoard[y][x][ROW] = false; //Reset the values
        }
        //Now we check if there are repeated numbers
        for (x = 1; x <= 9; x++) { //9 include because it is valours
            if (boxToCheck[x] > 1) {
                for (int box = 0; box < 9; box++) {
                    if (board[y][box].value == x) { //Then set this like error
                        errorBoard[y][box][ROW] = true;
                    } else {
                        errorBoard[y][box][ROW] = false;
                    }
                }
            }
        }
    }

    private void checkCol() {
        byte[] boxToCheck = new byte[10];
        int x;
        int y;
        resetArray(boxToCheck);
        x = j;
        //We count how many numbers are of each one
        for (y = 0; y < 9; y++) { //9 NO included because it is boxes
            boxToCheck[board[y][x].value] += 1;
            errorBoard[y][x][COL] = false; //Reset the values
        }
        //Now we check if there are repeated numbers
        for (y = 1; y <= 9; y++) { //9 include because it is valours
            if (boxToCheck[y] > 1) {
                for (int box = 0; box < 9; box++) {
                    if (board[box][x].value == y) { //Then set this like error
                        errorBoard[box][x][COL] = true;
                    } else {
                        errorBoard[box][x][COL] = false;
                    }
                }
            }
        }
    }

    private void checkBigBox() {
        byte[] boxToCheck = new byte[10];
        int x;
        int y;
        resetArray(boxToCheck);
        int bigX = j / 3;
        int bigY = i / 3;
        for (x = 0; x < 3; x++) {
            for (y = 0; y < 3; y++) {
                boxToCheck[board[bigY * 3 + y][bigX * 3 + x].value] += 1;
                errorBoard[bigY * 3 + y][bigX * 3 + x][SQR] = false; //Reset the values
            }

        }
        for (y = 1; y <= 9; y++) { //9 include because it is valours
            if (boxToCheck[y] > 1) {
                for (int boxX = 0; boxX < 3; boxX++) {
                    for (int boxY = 0; boxY < 3; boxY++) {
                        if (board[bigY * 3 + boxY][bigX * 3 + boxX].value == y) { //Then set this like error
                            errorBoard[bigY * 3 + boxY][bigX * 3 + boxX][SQR] = true;
                        } else {
                            errorBoard[bigY * 3 + boxY][bigX * 3 + boxX][SQR] = false;
                        }
                    }
                }
            }
        }
    }

    /*
     * checkFinal
     * method that only check if in each box there is no error and there is number != 0
     */
    private void checkFinal() {
        int flag = 0;
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {
                if ((board[x][y].value == 0) ||
                		(errorBoard[x][y][ROW] == true) || 
                		(errorBoard[x][y][COL] == true) || 
                		(errorBoard[x][y][SQR] == true)) {
                    flag = 1;
                    break;
                }
            }
            if (flag == 1)//Sudoku is not finished
            {
                break;
            }
        }
        if (flag == 0) {
            JFrame dialog = new JFrame("Pascuallll");
            JOptionPane.showMessageDialog(dialog, "Sudoku completed!!!!!");
        }

    }
}

