package sudoku;
import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Before;
import org.junit.Test;

import junit.framework.TestCase;


/**
 * This is file SudokuTest.java in project Sudoku2009.
 */
public class DavesSudokuModelTest {
    private SudokuModel s;
    private int[][] problem;
    private int[][] solution;
    private int[][] box02;
    private int[][] box21;

    @Before
    public void setUp() throws Exception {
        problem =
            new int[][]
                      { { 0, 1, 0,   0, 0, 0,   4, 0, 6 },
                        { 4, 0, 7,   6, 0, 0,   0, 9, 5 },
                        { 6, 0, 0,   1, 7, 0,   0, 2, 0 },

                        { 0, 0, 4,   0, 0, 1,   6, 8, 0 },
                        { 0, 0, 8,   0, 0, 6,   3, 0, 0 },
                        { 0, 5, 6,   8, 0, 0,   0, 0, 0 },

                        { 0, 7, 0,   0, 2, 5,   0, 0, 1 },
                        { 5, 4, 0,   0, 0, 8,   2, 0, 7 },
                        { 2, 0, 9,   0, 0, 0,   5, 4, 0 } };
        box02 =
            new int[][] { { 4, 0, 6 },
                          { 0, 9, 5 },
                          { 0, 2, 0 } };
        box21 =
            new int[][]
                      { { 0, 2, 5 },
                        { 0, 0, 8 },
                        { 0, 0, 0 } };
      solution =
          new int[][]
                { { 3, 1, 2,   5, 8, 9,   4, 7, 6 },
                  { 4, 8, 7,   6, 3, 2,   1, 9, 5 },
                  { 6, 9, 5,   1, 7, 4,   8, 2, 3 },

                  { 7, 3, 4,   2, 5, 1,   6, 8, 9 },
                  { 1, 2, 8,   7, 9, 6,   3, 5, 4 },
                  { 9, 5, 6,   8, 4, 3,   7, 1, 2 },

                  { 8, 7, 3,   4, 2, 5,   9, 6, 1 },
                  { 5, 4, 1,   9, 6, 8,   2, 3, 7 },
                  { 2, 6, 9,   3, 1, 7,   5, 4, 8 } };
        s = new SudokuModel(problem);
    }

    @Test
    public void testGetBox() {
        int[][] expectedBox02 =
            new int[][] { { 4, 0, 6 },
                          { 0, 9, 5 },
                          { 0, 2, 0 } };
        int[][] expectedBox21 =
            new int[][] { { 0, 2, 5 },
                          { 0, 0, 8 },
                          { 0, 0, 0 } };
        assertTrue(Arrays.deepEquals(expectedBox02, s.getBox(0, 2)));
        assertTrue(Arrays.deepEquals(expectedBox21, s.getBox(2, 1)));
    }

    @Test
    public void testOccursInRow() {
        assertTrue(s.occursInRow(1, 0));
        assertTrue(s.occursInRow(8, 5));
        assertTrue(s.occursInRow(4, 8));
        assertFalse(s.occursInRow(2, 0));
        assertFalse(s.occursInRow(4, 5));
        assertFalse(s.occursInRow(3, 8));
    }

    @Test
    public void testOccursInColumn() {
        assertTrue(s.occursInColumn(2, 0));
        assertTrue(s.occursInColumn(6, 5));
        assertTrue(s.occursInColumn(1, 8));
        assertFalse(s.occursInColumn(3, 0));
        assertFalse(s.occursInColumn(2, 5));
        assertFalse(s.occursInColumn(9, 8));
    }

    @Test
    public void testOccursInBoxIntIntInt() {
        assertTrue(s.occursInBox(1, 0, 0));
        assertTrue(s.occursInBox(1, 1, 1));
        assertTrue(s.occursInBox(1, 2, 2));
        assertFalse(s.occursInBox(3, 0, 2));
        assertFalse(s.occursInBox(3, 1, 1));
        assertFalse(s.occursInBox(3, 2, 0));
    }

    @Test
    public void testOccursInBoxIntIntArrayArray() {
        assertTrue(s.occursInBox(4, box02));
        assertFalse(s.occursInBox(4, box21));
        assertTrue(s.occursInBox(8, box21));
        assertFalse(s.occursInBox(8, box02));
        assertTrue(s.occursInBox(5, box02));
        assertTrue(s.occursInBox(5, box21));
        assertFalse(s.occursInBox(7, box02));
        assertFalse(s.occursInBox(7, box02));
    }

    @Test
    public void testIsLegalDigit() {
        assertTrue(s.isLegalDigit(3, 0, 0));
        assertTrue(s.isLegalDigit(8, 0, 0));
        assertTrue(s.isLegalDigit(9, 0, 0));
        assertFalse(s.isLegalDigit(2, 2, 2));
        assertFalse(s.isLegalDigit(8, 2, 2));
        assertFalse(s.isLegalDigit(1, 2, 2));

        assertTrue(s.isLegalDigit(1, 5, 7));
        assertFalse(s.isLegalDigit(9, 5, 7));
        assertFalse(s.isLegalDigit(5, 5, 7));
        assertFalse(s.isLegalDigit(3, 5, 7));
        
        assertTrue(s.isLegalDigit(3, 8, 8));
        assertFalse(s.isLegalDigit(2, 8, 8));
    }
    
    @Test
    public void testIsSolved() {
        s = new SudokuModel(problem);
        assertFalse(s.isSolved());
        
        s = new SudokuModel(solution);
        assertTrue(s.isSolved());
        
        int temp = solution[5][5];
        solution[5][5] = 0;
        assertFalse(s.isSolved());
        
        solution[5][5] = solution[4][4];
        solution[4][4] = temp;
        assertFalse(s.isSolved());
    }
}
