/*
 * File: BlankClass.java
 * ---------------------
 * This class is a blank one that you can change at will. Remember, if you
 * change the class name, you'll need to change the filename so that it matches.
 */

import java.awt.event.*;
import java.util.Arrays;

import javax.swing.JButton;

import acm.graphics.*;
import acm.program.*;
import acm.util.RandomGenerator;

public class SudokuChecker extends ConsoleProgram {

	// CONSTANTS AND INSTANCE FIELDS GO HERE!
	public static final int BOARD_SIZE = 9;
	public static final int SECTOR_SIZE = 3;

	/**
	 * This program will eventually check whether a given Sudoku
	 * board is a valid Sudoku solution or not.
	 */
	public void run() {
		
		// Validates incorrect boards five times.
		for (int i = 0; i < 5; i++) {
			println("Checking INCORRECT sudoku board number " + i + "...");
			SudokuBoard board = new SudokuBoard(false, BOARD_SIZE);
			println("The board looks like:\n" + board);
			boolean result = checkRows(board) && checkCols(board) && checkSectors(board, SECTOR_SIZE);
			println("Result: " + result + "\n");
			if (result) {
				println("Check failed!");
			} else {
				println("Check passed!");
			}
		}

		// Validates single correct board once.
		println("Checking CORRECT sudoku board...");
		SudokuBoard board = new SudokuBoard(true, BOARD_SIZE);
		println("The board looks like:\n" + board);
		boolean result = checkRows(board) && checkCols(board) && checkSectors(board, SECTOR_SIZE);
		println("Result: " + result + "\n");
		if (!result) {
			println("Check failed!");
		} else {
			println("Check passed!");
		}
	}
	
	
	private boolean checkRows(SudokuBoard board) {
		int [][] boardArr = board.getBoard();
		return false;
	}
	
	
	private boolean checkCols(SudokuBoard board) {
		int [][] boardArr = board.getBoard();
		return false;
	}
	
	
	private boolean checkSectors(SudokuBoard board, int sectorSize) {
		int [][] boardArr = board.getBoard();
		return false;
	}
	
	
	/**
	 * A simple wrapper class for a Sudoku Board representation.
	 */
	private class SudokuBoard {
		
		private int boardSize;
		private int[][] boardRepr;
		private RandomGenerator rgen;
		
		private SudokuBoard(boolean correct, int boardSize) {
			this.boardSize = boardSize;
			this.boardRepr = new int[boardSize][boardSize];
			this.rgen = RandomGenerator.getInstance();
			if (correct) {
				generateCorrectBoard();
			} else {
				generateRandomIncorrectBoard();
			}
		}
		
		
		/**
		 * A hard-coded valid Sudoku solution.
		 */
		private void generateCorrectBoard() {
			int[][] temp = {
				{7, 3, 5, 6, 1, 4, 8, 9, 2},
				{8, 4, 2, 9, 7, 3, 5, 6, 1},
				{9, 6, 1, 2, 8, 5, 3, 7, 4},
				{2, 8, 6, 3, 4, 9, 1, 5, 7},
				{4, 1, 3, 8, 5, 7, 9, 2, 6},
				{5, 7, 9, 1, 2, 6, 4, 3, 8},
				{1, 5, 7, 4, 9, 2, 6, 8, 3},
				{6, 9, 4, 7, 3, 8, 2, 1, 5},
				{3, 2, 8, 5, 6, 1, 7, 4, 9}
			};
			this.boardRepr = temp;
		}
		
		
		/**
		 * Always generates a board with at least one duplicate pair somewhere.
		 */
		private void generateRandomIncorrectBoard() {
			
			// Fill entire board randomly
			for (int row = 0; row < this.boardRepr.length; ++row) {
				for (int col = 0; col < this.boardRepr[row].length; ++col) {
					this.boardRepr[row][col] = rgen.nextInt(boardSize - 1);
				}
			}
			
			// A lot of random numbers
			int duplicate = rgen.nextInt(boardSize - 1);
			int where = rgen.nextInt(boardSize - 1);
			int loc1 = rgen.nextInt(boardSize - 1);
			int loc2 = rgen.nextInt(boardSize - 1);
			
			// Whether to choose same row or column
			boolean which = rgen.nextBoolean();
			if (which) {
				this.boardRepr[where][loc1] = duplicate;
				this.boardRepr[where][loc2] = duplicate;
			} else {
				this.boardRepr[loc1][where] = duplicate;
				this.boardRepr[loc2][where] = duplicate;
			}
		}
		
		
		/**
		 * Safely returns the int[][] board representation.
		 */
		public int[][] getBoard() {
			return this.boardRepr.clone();
		}
		
		
		/**
		 * Returns a nice representation of the SudokuBoard. 
		 */
		public String toString() {
			String ret = "";
			for (int i = 0; i < this.boardRepr.length; i++) {
				ret += Arrays.toString(this.boardRepr[i]) + "\n";
			}
			ret = ret.substring(0, ret.length() - 1);
			return ret;
		}
	}
}

