/* Useful imports */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.codec.*;
import edu.neu.ccs.console.*;
import edu.neu.ccs.filter.*;
import edu.neu.ccs.jpf.*;
import edu.neu.ccs.parser.*;
import edu.neu.ccs.pedagogy.*;
import edu.neu.ccs.quick.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import java.math.*;
import java.beans.*;
import java.lang.reflect.*;
import java.net.URL;
import java.util.regex.*;
import java.text.ParseException;


public class SudokuTable
    extends TablePanel
{
    // Static definitions //
    
    /** The table background color. */
    private static final Color backcolor = Colors.black;
    
    /** The tiny gap. */
    protected static final int gaptiny = 2;
    
    /** The small gap. */
    protected static final int gapsmall = 6;
    
    
    // Member definitions //
    
    /** The Sudoku model. */
    private SudokuModel model = null;
    
    /** The Sudoku blocks within the table. */
    private SudokuBlock[][] blocks = new SudokuBlock[10][10];
    
    /** The 3-by-3 tables within the main table. */
    private TablePanel[][]  tables = new TablePanel[4][4];
    
    
    // Constructors //
    
    /** The default constructor with no Sudoku model. */
    public SudokuTable() {
        super(4, 4, gapsmall, gapsmall, CENTER);
        
        initialize();
    }
    
    
    /** The constructor using a Sudoku model. */
    public SudokuTable(SudokuModel model) {
        super(4, 4, gapsmall, gapsmall, CENTER);
        
        this.model = model;
        
        initialize();
    }
    
    
    // Methods //
    
    /** Orchestrates the initialization steps. */
    private void initialize() {
        initializeMain();
        initializeBlocks();
        initializeTables();
    }
    
    
    /** Sets the main table border and background color. */
    private void initializeMain() {
        int g = gapsmall;
        Border border = BorderFactory.createEmptyBorder(g, g, g, g);
        setBorder(border);
        
        setBackground(backcolor);
    }
    
    
    /** Creates the Sudoku blocks that form the heart of the table. */
    private void initializeBlocks() {
        for (int row = 1; row <= 9; row++)
            for (int col = 1; col <= 9; col++)
                blocks[row][col] =
                    new SudokuBlock(this, row, col);
    }
    
    
    /** Creates the 3-by-3 tables within the main table. */
    private void initializeTables() {
        for (int r = 1; r <= 3; r++)
            for (int c = 1; c <= 3; c++)
                initializeTable(r, c);
    }
    
    
    /** Creates one 3-by-3 table. */
    private void initializeTable(int r, int c) {
        int s = gaptiny;
        
        TablePanel panel =
            new TablePanel(4, 4, s, s, CENTER);
        
        panel.setBackground(backcolor);
        
        int rowbase = 3 * (r - 1);
        int colbase = 3 * (c - 1);
        
        for (int rr = 1; rr <= 3; rr++)
            for (int cc = 1; cc <= 3; cc++) {
                int row = rowbase + rr;
                int col = colbase + cc;
                
                panel.addObject(blocks[row][col], rr, cc);
            }
        
        addObject(panel, r, c);
    }
    
    
    /** Returns the Sudoku model behind this table. */
    public SudokuModel getSudokuModel() {
        return model;
    }
    
    
    /** Returns the Sudoku block in the given row and col. */
    public SudokuBlock getSudokuBlock(int row, int col) {
        if ((row >= 1) && (row <= 9))
            if ((col >= 1) && (col <= 9))
                return blocks[row][col];
        
        return null;
    }
    
    
    public SudokuBlock getSudokuBlock(CellPosition position) {
        if (position == null)
            return null;
        
        int row = position.row;
        int col = position.col;
        
        return getSudokuBlock(row, col);
    }
    
    
    /** Finds and unselects any selected blocks. */
    public void unselectBlocks() {
        for (int row = 1; row <= 9; row++)
            for (int col = 1; col <= 9; col++)
                if (blocks[row][col].isSelected())
                    blocks[row][col].unselect();
    }
    
    
    public static void main(String[] args) {
        SudokuTable table = new SudokuTable();
        table.frame("Sudoku Table");
    }
    
}
