package edu.unl.consystlab.sudokuSolver;

import javax.swing.JOptionPane;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.NumberFormat;
import java.util.*;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRootPane;
import javax.swing.JTextField;

import java.awt.Color;
import java.awt.Component;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.PopupMenu;
import java.awt.PrintJob;

import javax.swing.border.*;
import javax.swing.JPanel;
import javax.swing.JButton;

import javax.swing.JRadioButton;
import java.awt.Checkbox;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

//import sun.awt.motif.MPopupMenuPeer;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.event.ChangeListener;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class sudokuInterface extends JApplet implements ActionListener, ItemListener, Printable, KeyListener, MouseListener, ListSelectionListener{

	private final String LIBRARY_LOCATION = "http://consystlab.unl.edu/SudokuLibrary/";
	private final int PLAYING_BOARD_X_POS = 40;
	private final int PLAYING_BOARD_Y_POS = 40;
	private sudokuBoard playingBoard;
	private constraintProblem myProblem;
	private String autoPropogationType;
	private boolean showDomains;
	private String problemLocation;
	private int counter = 0;
	
	private JLabel numSolutions;
	private JLabel numberEliminatedLabel;
	private JMenu useless;
	//private hintButtonHandler myHintHandler;
	JButton findHintButton;
	private JPanel hintPanel;
    private JButton fromdb;
    private JTextField popupField;
    private JButton popupButton;
    private JPanel popupPanel;
    private JLabel popupLabel;
    private int popupNumber;
    private JComboBox popupTypeList;
    private JComboBox popupList;
    private JFrame aboutBox;
    private JButton cancelButton;

//Angelo's new private variables	
    private JLabel inputNumLabel;
    private JLabel defaultLabel;
    private JTextField inputNumField;
    private JButton chooser;
    private String batchFile;
    private int FileLineNumber;

    private Component maincomponent;
    private int puzzlesInDB = 0;
    private String[] puzzleNumbers;
    private String[][] results;
    private JComboBox puzzNumList;
    private JLabel dbDefaultLabel;
    private JLabel dbDefaultLabel2;
    private JButton goButton;
	private JButton goButton2;
    private JPanel problemPanel;
    private JPanel appearancePanel;
    private JPanel interactiveModePanel;
    private JPanel binaryPanel = new JPanel();
    private int numCols;
    private int numLines;
    private JButton[] btnAllDifConsis;
    private JButton[] btnBinConsis;
    private JButton[] btnAllDifUnitConsis;
    private JButton[] btnBinUnitConsis;
    private int unitsHigh;
    private int unitsWide;
    private JComboBox puzzTypeBox;
    private JList queryResults;
	private JList list1;
    private DefaultListModel listModel;
    private JButton selectButton;
    private JScrollPane scroller;
	private JScrollPane scroller2;
    private JLabel dbDefaultLabel3;
    private JLabel dbDefaultLabel4;
    private int matches;
    private JComboBox maxDiffBox;
    private JTextField matchesBox;
    private JComboBox diffBox;
    private int dbpuzzle;
    private Thread thread;
    private JLabel working;
    private JLabel dbDefaultLabel5;
    private JComboBox numSolBox;
    private JLabel dbDefaultLabel8;
    private JLabel dbDefaultLabel6;
    private JLabel dbDefaultLabel7;
    private JLabel dbDefaultLabel10;
    private JLabel dbDefaultLabel11;
    private JLabel dbDefaultLabel9;
    private JLabel dbDefaultLabel12;
    private JLabel dbDefaultLabel13;
    private JButton dbDefaultBtn1;
    private JComboBox consisBox;
    private JButton dbDefaultBtn5;
    private JButton dbDefaultBtn2;
    private JButton dbDefaultBtn6;
    private JButton dbDefaultBtn4;
    private JButton dbDefaultBtn3;
    private boolean queried;
    private String orderBy;
    private String puzzleType;
    private String maxLevel;
    private String level;
    private int numSol;
    private String consistency;
    JLabel description = new JLabel("Description");
    JLabel description2 = new JLabel("Description");
    
    //create the handler for the consistency buttons.
    consistencyButtonHandler cbh = new consistencyButtonHandler();

    //JButton btnPropBinaryMAC = new JButton();
    //JButton btnPropNonBinaryGAC = new JButton();
    //JButton btnPropShavingMAC = new JButton();
    //JButton btnPropShavingGAC = new JButton();
	DefaultTableModel model = new DefaultTableModel();
	
    JTextArea jta = new JTextArea();
    JTextArea jta2 = new JTextArea();
    //JScrollPane jScrollPane11 = new JScrollPane(jta);

    private constructorInterface constructorPanel;
    
     private javax.swing.JPanel algorithmPanel;
    private JPanel createPanel;
    private JPanel databasePanel;
    private JPanel instancePanel;
    private JLabel jLabel10;
    private JLabel jLabel11;
    private JLabel jLabel12;
    private JLabel jLabel13;
    private JLabel jLabel3;
    private JLabel jLabel6;
    private JLabel jLabel7;
    private JLabel jLabel8;
    private JLabel jLabel9;
    private JScrollPane jScrollPane1;
    private javax.swing.JTabbedPane jTabbedPane1;
    private JRadioButton optDatabase;
    private JRadioButton optInstance;
    private ButtonGroup selectGroup;
    private JPanel playPanel;
    private JPanel selectPanel;
//    private javax.swing.JSlider sldSpeed;
    private javax.swing.JTable tbPuzzles;
	ActionListener fileOpener = new fileLoadHandler(this);

        private Thread t;
        private solBoard[] solBoards;
	private int solIndex;
	private JButton back;
	private JButton prev;
	private JButton next;

            //Amanda
    private JTextField timeField;
    private int m;
    private int h;
    private int s;
    private int have_used_algs = 0;
    private JLabel haveused;
    javax.swing.Timer timer = new javax.swing.Timer(1000, new ClockListener());

    private static int numElim = 0;


    public int getHours(){
        return h;
    }

    public int getMinutes(){
        return m;

    }

    public int getSeconds(){
        return s;
    }

    //Amanda
    public void stopTimer(){
        timer.stop();
    }

    public int getHaveUsed(){
        return have_used_algs;
    }

    public void init() {

	//we can make the menubar very first because it is independent of everything else
	JMenuBar mb = new JMenuBar();
	//JMenu mainMenu = new JMenu("Load Instance");

    System.out.println("Codebase: " + this.getCodeBase());
    maincomponent = this;

    ActionListener dbListener = new ShowDatabaseListener(mb);
	ActionListener intListener=new ShowInstanceListener(mb);
    ActionListener aboutMenu = new showAboutMenu(mb);

    fromdb = new JButton("From DataBase");
    fromdb.setText("From DataBase");
    fromdb.addActionListener(dbListener);
    fromdb.setActionCommand("fromdb");

    aboutBox = new AboutBox();
    JMenu about = new JMenu("About");
    JMenuItem aboutselect = new JMenuItem("About");
    about.add(aboutselect);
    aboutselect.addActionListener(aboutMenu);
    addKeyListener(this);

	//ActionListener fileOpener = new fileLoadHandler(this);
	//createLoadMenu(LIBRARY_LOCATION + "libraryIndex.xml", mainMenu, fileOpener);

//	mb.add(mainMenu);
//    mb.add(fromdb);
//    mb.add(about);
//	setJMenuBar(mb);
		
	myProblem = loadProblem();
	initialize();
    }
	
    public void initialize()
    {
    
    Font standardbutton = new Font("Times Unicode", Font.PLAIN, 10);
    Font standardlabel = new Font("Times Unicode", Font.PLAIN, 12);

	numCols = myProblem.totalColumns;  //these two should always be equal
	numLines = myProblem.totalLines;

	unitsWide = (int)(numCols/myProblem.columnsPerUnit);
	unitsHigh = (int)(numLines/myProblem.linesPerUnit);

		
	//set up the display window
	this.setBackground(Color.WHITE);
	this.setSize(1000, 650);
	this.setLayout(null);

        
	//make the board first because it decides some of its own dimensions..
	// or at least it should in the future.		
	playingBoard = new sudokuBoard(myProblem, this);
	playingBoard.setLayout(null);
	playingBoard.setBackground(Color.WHITE);
	playingBoard.setLocation(PLAYING_BOARD_X_POS, PLAYING_BOARD_Y_POS);
	//sudokuBoard.setUndecorated(true);
	this.add(playingBoard);
        
	//		PopupMenu pumModel = new PopupMenu("Model");
	//		pumModel.add("binary");
	//		pumModel.insert("hi",2);
	//		pumModel.setEnabled(true);
	//		//pumModel.show(this,500,400);
	//		problemPanel.add(pumModel);
		
	//RIGHT PANEL ++++++++++++++++++++++++++++++++++++++++++++++ //

        createTabs();
        
	problemPanel = new JPanel();
	problemPanel.setSize(470,500);
	problemPanel.setLocation(15,20);
	problemPanel.setBackground(Color.WHITE);
	problemPanel.setLayout(null);

        Border etchedBdr2 = BorderFactory.createEtchedBorder();
         JLabel instr = new JLabel("Instructions");
        instr.setSize(100,15);
        instr.setLocation(35,190);
       JTextArea jta = new JTextArea();
        jta.setEditable(false);
        jta.setBorder(etchedBdr2);
        jta.setLineWrap(true);
        jta.setWrapStyleWord(true);
        jta.setText("Board Instructions: \n\nTo enter in a number, hover over the cell you would like and use the top numbers on the keyboard to enter.\n"+
                "\nTo remove a mini number, hover over the cell and use the numpad to remove the number you would like.\n " +
                "\nTo eliminate the mini numbers horizontally or vertically adjacent to a cell that correspond to that cell, hover over the cell and use the space bar.\n" +
                "\nGame Instructions:\n\nThe aim of the puzzle is to enter a numerical digit from 1 through 9 in each cell of a 9×9 grid made up of 3×3 subgrids (called 'regions'), starting with various digits given in some cells (the 'givens''). " +
                "\nEach row, column, and region must contain only one instance of each numeral");
        
        JScrollPane instr_scroll = new JScrollPane(jta);
        instr_scroll.setSize(400,200);
        instr_scroll.setLocation(35,210);
       

        problemPanel.add(instr);
        problemPanel.add(instr_scroll);



            String used_text = "Sorry, you have used the algorithms. You cannot compete for a high score.";
            haveused = new JLabel(used_text);
            haveused.setSize(450,15);
            haveused.setLocation(10,105);

             JButton btnHighScores = new JButton();
	btnHighScores.setBorder(null);
	btnHighScores.setFont(standardbutton);
	btnHighScores.setText("High Scores");
	btnHighScores.addActionListener(this);
	btnHighScores.setActionCommand("highscores");
	btnHighScores.setLocation(128,150);
	btnHighScores.setSize(100,30);
	problemPanel.add(btnHighScores);


        JButton playNew = new JButton();
	playNew.setBorder(null);
	playNew.setFont(standardbutton);
	playNew.setText("Play a new puzzle");
	playNew.addActionListener(this);
	playNew.setActionCommand("playnew");
	playNew.setLocation(242,150);
	playNew.setSize(100,30);
	problemPanel.add(playNew);



		
	//strip down the problem location to just be the name
	//String problemName = problemLocation.substring(problemLocation.lastIndexOf("/")+1);
	//System.out.println(problemName);
    //problemName = problemName.substring(0,problemName.indexOf("."));
	//load the problem name into the label
   
		
	
	
		

//	problemPanel.add(btnAutoAssign);

		
		
	//add a field for the number of solutions
	JButton numSolutionsButton = new JButton();
	numSolutionsButton.setActionCommand("findSolutions");
	numSolutionsButton.setBorder(null);
	numSolutionsButton.setFont(standardbutton);
	numSolutionsButton.addActionListener(this);
        numSolutionsButton.setText("# Solutions:");
	numSolutionsButton.setLocation(135,450);
	numSolutionsButton.setSize(100, 30);
	problemPanel.add(numSolutionsButton);

        working = new JLabel("Working...");
	working.setLocation(25,200);
	working.setSize(150, 15);
        working.setVisible(false);
	problemPanel.add(working);


//	JButton stopButton = new JButton();
//	stopButton.setActionCommand("stop!");
//	stopButton.setBorder(null);
//	stopButton.setFont(standardbutton);
//	stopButton.addActionListener(this);
//        stopButton.setText("Stop Process");
//	stopButton.setLocation(242,450);
//	stopButton.setSize(100,30);
        //stopButton.setVisible(false);
//	problemPanel.add(stopButton);
		
	numSolutions = new JLabel("");
	numSolutions.setLocation(180,420);
	numSolutions.setSize(70, 30);
	problemPanel.add(numSolutions);
	//		//which type of propogation you want to preform.
	//		hintPanel = new JPanel();
	//		hintPanel.setSize(180,140);
	//		hintPanel.setLocation(5,125);
	//		hintPanel.setBackground(Color.WHITE);
	//		hintPanel.setLayout(null);
	//		problemPanel.add(hintPanel);
	//		
	//		myHintHandler = new hintButtonHandler();
	//		
	//		findHintButton = new JButton("Find Hints");
	//		findHintButton.setActionCommand("hintFind");
	//		findHintButton.setName("hintFind");
	//		findHintButton.setBorder(null);
	//		//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	//		findHintButton.addActionListener(myHintHandler);
	//		findHintButton.setLocation(0,0);
	//		findHintButton.setSize(90, 15);
	//		hintPanel.add(findHintButton);
	//		
	//		JLabel numHintsLabel = new JLabel();
	//		numHintsLabel.setName("hintNumberLabel");
	//		numHintsLabel.setLocation(0,20);
	//		numHintsLabel.setSize(150, 15);
	//		numHintsLabel.setEnabled(false);
	//		hintPanel.add(numHintsLabel);
	//		
	//		JButton displayHintButton = new JButton("Display");
	//		displayHintButton.setActionCommand("hintDisplay");
	//		displayHintButton.setName("hintDisplay");
	//		displayHintButton.setBorder(null);
	//		//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	//		displayHintButton.addMouseListener(myHintHandler);
	//		displayHintButton.setLocation(0,40);
	//		displayHintButton.setSize(45, 15);
	//		displayHintButton.setEnabled(false);
	//		hintPanel.add(displayHintButton);
	//		
	//		JButton nextHintButton = new JButton("Next");
	//		nextHintButton.setName("hintNext");
	//		nextHintButton.setActionCommand("hintNext");
	//		nextHintButton.setBorder(null);
	//		//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	//		nextHintButton.addActionListener(myHintHandler);
	//		nextHintButton.setLocation(50,40);
	//		nextHintButton.setSize(40, 15);
	//		nextHintButton.setEnabled(false);
	//		hintPanel.add(nextHintButton);
	//		
	//		JButton nextLevelHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nextarrow.GIF")));
	//		nextLevelHintButton.setName("hintLevelNext");
	//		nextLevelHintButton.setActionCommand("hintLevelNext");
	//		nextLevelHintButton.setBorder(null);
	//		nextLevelHintButton.addActionListener(myHintHandler);
	//		nextLevelHintButton.setLocation(0,60);
	//		nextLevelHintButton.setSize(14, 17);
	//		nextLevelHintButton.setEnabled(false);
	//		hintPanel.add(nextLevelHintButton);
	//		
	//		JLabel levelHintsLabel = new JLabel("Level:");
	//		levelHintsLabel.setName("hintLevelLabel");
	//		levelHintsLabel.setLocation(45,60);
	//		levelHintsLabel.setSize(50, 15);
	//		levelHintsLabel.setEnabled(false);
	//		hintPanel.add(levelHintsLabel);
	//		
	//		JLabel levelDisplayLabel = new JLabel();
	//		levelDisplayLabel.setName("hintLevelDisplayLabel");
	//		levelDisplayLabel.setLocation(0,80);
	//		levelDisplayLabel.setSize(150, 15);
	//		levelDisplayLabel.setEnabled(false);
	//		hintPanel.add(levelDisplayLabel);
	//		
	//		JButton switchTypeHintButton = new JButton("Switch");
	//		switchTypeHintButton.setName("hintSwitchType");
	//		switchTypeHintButton.setActionCommand("hintSwitchType");
	//		switchTypeHintButton.setBorder(null);
	//		//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	//		switchTypeHintButton.addActionListener(myHintHandler);
	//		switchTypeHintButton.setLocation(0,100);
	//		switchTypeHintButton.setSize(40, 15);
	//		switchTypeHintButton.setEnabled(false);
	//		hintPanel.add(switchTypeHintButton);
	//		
	//		JLabel typeHintsLabel = new JLabel("Type:");
	//		typeHintsLabel.setName("hintTypeLabel");
	//		typeHintsLabel.setLocation(45,100);
	//		typeHintsLabel.setSize(50, 15);
	//		typeHintsLabel.setEnabled(false);
	//		hintPanel.add(typeHintsLabel);
	//		
	//		JLabel typeDisplayLabel = new JLabel();
	//		typeDisplayLabel.setName("hintTypeDisplayLabel");
	//		typeDisplayLabel.setLocation(0,120);
	//		typeDisplayLabel.setSize(150, 15);
	//		typeDisplayLabel.setEnabled(false);
	//		hintPanel.add(typeDisplayLabel);
		
	JButton btnResetProblem = new JButton();
	btnResetProblem.setBorder(null);
	btnResetProblem.setFont(standardbutton);
	btnResetProblem.setText("Reset Problem");
	btnResetProblem.addActionListener(this);
	btnResetProblem.setActionCommand("resetProblem");
	btnResetProblem.setLocation(249, 450);
	btnResetProblem.setSize(100,30);
	problemPanel.add(btnResetProblem);

         timeField = new JTextField(5);
                    timeField.setEditable(false);
                    timeField.setFont(new Font("sansserif", Font.PLAIN, 36));
                    timeField.setLocation(160,50);
                    timeField.setSize(150,50);
                    timeField.setText("00:00:00");
                    problemPanel.add(timeField);
//	this.add(problemPanel);

        playPanel.add(problemPanel);
		
//	this.add(problemPanel);

       
	//END RIGHT PANEL ++++++++++++++++++++++++++++++++++++++++++ //
		
	//create the handler for the consistency buttons.
	//consistencyButtonHandler cbh = new consistencyButtonHandler();
		
	btnAllDifConsis = new JButton[numCols+numLines];
	btnBinConsis = new JButton[numCols+numLines];
	///Button[] btnAllDifConsis = btnAllDifConsis [18];

		
	int cellWidth = playingBoard.getCellWidth();
	int cellHeight = playingBoard.getCellHeight();
	int cellBorderWidth = playingBoard.getUnitBorderWidth();
		
	//make the buttons accross the top.
	for(int i=0; i < numCols; i++)
	    {
		btnAllDifConsis[i] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nonBinaryCol.GIF")));
		btnAllDifConsis[i].setBorder(null);
		btnAllDifConsis[i].setText("");
		btnAllDifConsis[i].setActionCommand("a;c;"+(i+1));
		btnAllDifConsis[i].addActionListener(cbh);
		btnAllDifConsis[i].addMouseListener(cbh);
		btnAllDifConsis[i].setLocation((i*cellWidth)+PLAYING_BOARD_Y_POS+(i/unitsWide)*cellBorderWidth+5, 5);
		btnAllDifConsis[i].setSize((cellWidth-10),10);
		btnAllDifConsis[i].setToolTipText("Removes all values that " +
                        "cannot appear in a solution to the cells in the column " +
                        "(i.e., enforces Generalized Arc Consistency on the column)");
                btnAllDifConsis[i].setEnabled(false);
		this.add(btnAllDifConsis[i]);
			
		btnBinConsis[i] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "binaryCol.GIF")));
		btnBinConsis[i].setBorder(null);
		btnBinConsis[i].setText("");
		//btnBinConsis[i].setBackground(new Color(23,45,156));
		btnBinConsis[i].setActionCommand("b;c;"+(i+1));
		btnBinConsis[i].addActionListener(cbh);
		btnBinConsis[i].addMouseListener(cbh);
		btnBinConsis[i].setLocation((i*cellWidth)+PLAYING_BOARD_Y_POS+(i/unitsWide)*cellBorderWidth+5, 25);
		btnBinConsis[i].setSize((cellWidth-10),10);
		btnBinConsis[i].setToolTipText("Removes a value that is assigned " +
                        "to a cell from all other cells in the column (i.e., " +
                        "enforces Arc Consistency on the column)");
                btnBinConsis[i].setEnabled(false);
		this.add(btnBinConsis[i]);
	    }

	//make buttons along the left
	for(int i=0; i < numLines; i++)
	    {
		//btnAllDifConsis[i+numCols] = new JButton(new ImageIcon(this.getCodeBase()+"1.GIF"));
		btnAllDifConsis[i+numCols] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nonBinaryLine.GIF")));
		btnAllDifConsis[i+numCols].setBorder(null);
		btnAllDifConsis[i+numCols].setText("");
		btnAllDifConsis[i+numCols].setActionCommand("a;l;"+(i+1));
		btnAllDifConsis[i+numCols].addActionListener(cbh);
		btnAllDifConsis[i+numCols].addMouseListener(cbh);
		btnAllDifConsis[i+numCols].setLocation(5, (i*cellHeight)+PLAYING_BOARD_X_POS+(i/unitsHigh)*cellBorderWidth+5);
		btnAllDifConsis[i+numCols].setSize(10, (cellHeight-10));
		btnAllDifConsis[i+numCols].setToolTipText("Removes all values " +
                        "that cannot appear in a solution to the cells in the " +
                        "row (i.e., enforces Generalized Arc Consistency on the row)");
                btnAllDifConsis[i+numCols].setEnabled(false);
		this.add(btnAllDifConsis[i+numCols]);
			
		btnBinConsis[i+numCols] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "binaryLine.GIF")));
		btnBinConsis[i+numCols].setBorder(null);
		btnBinConsis[i+numCols].setText("");
		//btnBinConsis[i+numCols].setBackground(new Color(23,45,156));
		btnBinConsis[i+numCols].setActionCommand("b;l;"+(i+1));
		btnBinConsis[i+numCols].addActionListener(cbh);
		btnBinConsis[i+numCols].addMouseListener(cbh);
		btnBinConsis[i+numCols].setLocation(25, (i*cellHeight)+PLAYING_BOARD_X_POS+(i/unitsHigh)*cellBorderWidth+5);
		btnBinConsis[i+numCols].setSize(10, (cellHeight-10));
		btnBinConsis[i+numCols].setToolTipText("Removes a value that is " +
                        "assigned to a cell from all other cells in the row " +
                        "(i.e., enforces Arc Consistency on the row)");
                btnBinConsis[i+numCols].setEnabled(false);
		this.add(btnBinConsis[i+numCols]);
	    }
	
	//make the unit buttons
	btnAllDifUnitConsis = new JButton[unitsHigh*unitsWide];
	btnBinUnitConsis = new JButton[unitsHigh*unitsWide];
/*
	for(int colIndex=0; colIndex < unitsWide; colIndex++)
	    {
		for(int rowIndex=0; rowIndex < unitsHigh; rowIndex++)
		    {
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nonBinaryUnit.GIF")));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setBorder(null);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setText("");
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setActionCommand("a;u;"+(rowIndex+1)+";"+(colIndex+1));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].addActionListener(cbh);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].addMouseListener(cbh);
			//TODO: need to make its location and possibly size more dynamic
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setLocation(440+((cellWidth/2) * colIndex), ((cellHeight/2) * rowIndex) + 10);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setSize(((cellWidth/2)-1),((cellHeight/2)-1));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setToolTipText("Nonbinary unit "+(rowIndex+1)+","+(colIndex+1));
			this.add(btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex]);
				
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "binaryUnit.GIF")));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setBorder(null);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setText("");
			//btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setBackground(new Color(23,45,156));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setActionCommand("b;u;"+(rowIndex+1)+";"+(colIndex+1));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].addActionListener(cbh);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].addMouseListener(cbh);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setLocation(510+((cellWidth/2) * colIndex), ((cellHeight/2) * rowIndex) + 10);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setSize(((cellWidth/2)-1),((cellHeight/2)-1));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setToolTipText("Binary unit "+(rowIndex+1)+","+(colIndex+1));
			this.add(btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex]);
		    }
	    }
*/
	//this panel contains all the controls at the bottom of the page

	interactiveModePanel = new JPanel();
	interactiveModePanel.setSize(440,200);
	interactiveModePanel.setLocation(10,420);
	interactiveModePanel.setBackground(Color.WHITE);
	interactiveModePanel.setLayout(null);
        
        //draw a border
	Border etchedBdr = BorderFactory.createEtchedBorder();
	Border titleBdr = BorderFactory.createTitledBorder(etchedBdr, "General Help");
	Border emptyBdr = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr = BorderFactory.createCompoundBorder(titleBdr, emptyBdr);
	interactiveModePanel.setBorder(compoundBdr);
	//interactiveModePanel.setBorder(titleBdr);
	/*
	//this panel is for appearence.
	appearancePanel = new JPanel();
	appearancePanel.setSize(150,130);
	appearancePanel.setLocation(5,15);
	appearancePanel.setBackground(Color.WHITE);
	appearancePanel.setLayout(null);
	//draw a border
	Border etchedBdr3 = BorderFactory.createEtchedBorder();
	Border titleBdr3 = BorderFactory.createTitledBorder(etchedBdr3, "Appearance");
	Border emptyBdr3 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr3 = BorderFactory.createCompoundBorder(titleBdr3, emptyBdr3);
	appearancePanel.setBorder(compoundBdr3);
		
	showDomains = true;
	JCheckBox domainBox = new JCheckBox("Show domains", true);
	domainBox.setActionCommand("showDomains");
	domainBox.setSize(120,20);
        domainBox.setFont(standardlabel);
	domainBox.setLocation(10,20);
	domainBox.setBackground(Color.WHITE);
	domainBox.addItemListener(this);
	appearancePanel.add(domainBox);
		
		
		
	JLabel leftMouseLabel = new JLabel("Left click:\nAssign");
	leftMouseLabel.setSize(100,15);
        leftMouseLabel.setFont(standardlabel);
	leftMouseLabel.setLocation(15, 45);
	appearancePanel.add(leftMouseLabel);
	JLabel rightMouseLabel = new JLabel("Right click:\nRemove");
	rightMouseLabel.setSize(130,30);
        rightMouseLabel.setFont(standardlabel);
	rightMouseLabel.setLocation(15, 60);
	appearancePanel.add(rightMouseLabel);
 		
	//		JCheckBox errorBox = new JCheckBox("Show errors", true);
	//		errorBox.setSize(120,20);
	//		errorBox.setLocation(20,85);
	//		errorBox.setBackground(Color.WHITE);
	//		errorBox.addItemListener(this);
	//		appearancePanel.add(errorBox);
	*/
	//this section adds all the things for the buttons that let you select
	//which type of propogation you want to preform.
	JPanel propogationPanel = new JPanel();
	propogationPanel.setSize(0,0);
	propogationPanel.setLocation(145,15);
	propogationPanel.setBackground(Color.WHITE);
	propogationPanel.setLayout(null);
	//draw a border
	etchedBdr2 = BorderFactory.createEtchedBorder();
	Border titleBdr2 = BorderFactory.createTitledBorder(etchedBdr2, "Propagation");
	Border emptyBdr2 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr2 = BorderFactory.createCompoundBorder(titleBdr2, emptyBdr2);
	//propogationPanel.setBorder(titleBdr2);
	propogationPanel.setBorder(compoundBdr2);
		
/*
	JLabel numElimLabelLabel = new JLabel("Values eliminated:");
	numElimLabelLabel.setLocation(10,25);
        numElimLabelLabel.setFont(standardlabel);
	numElimLabelLabel.setSize(0,0);
	propogationPanel.add(numElimLabelLabel);
		
	numberEliminatedLabel = new JLabel("");
	numberEliminatedLabel.setLocation(115,25);
	numberEliminatedLabel.setSize(0,0);
	propogationPanel.add(numberEliminatedLabel);
	*/

//	JLabel binaryLabel = new JLabel("Binary");
//	binaryLabel.setLocation(10,30);
//	binaryLabel.setSize(60, 15);
//	propogationPanel.add(binaryLabel);
		
//	JLabel nonBinaryLabel = new JLabel("Non-Binary");
//	nonBinaryLabel.setLocation(85,30);
//	nonBinaryLabel.setSize(65, 15);
//	propogationPanel.add(nonBinaryLabel);
		
	JButton btnPropBinaryMAC = new JButton();
        btnPropBinaryMAC.setText("AC");
	//btnPropBinaryMAC.setBorder(null);
        btnPropBinaryMAC.setFont(standardbutton);
	btnPropBinaryMAC.setActionCommand("propBinaryMAC");
	btnPropBinaryMAC.setLocation(45, 40);
	//btnPropBinaryMAC.setLocation(10,45);
	btnPropBinaryMAC.setSize(0,0);
	btnPropBinaryMAC.addActionListener(this);
        btnPropBinaryMAC.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                System.out.println("Hello");
            }
        });
	propogationPanel.add(btnPropBinaryMAC);
		
	JButton btnPropNonBinaryGAC = new JButton();
        btnPropNonBinaryGAC.setText("GAC");
	//btnPropNonBinaryGAC.setBorder(null);
        btnPropNonBinaryGAC.setFont(standardbutton);
	btnPropNonBinaryGAC.setActionCommand("propNonBinaryGAC");
	btnPropNonBinaryGAC.setLocation(85,60);
	//	btnPropNonBinaryGAC.setLocation(85,45);
	btnPropNonBinaryGAC.setSize(0,0);
	btnPropNonBinaryGAC.addActionListener(this);
	propogationPanel.add(btnPropNonBinaryGAC);
		
	JButton btnPropShavingMAC = new JButton();
        btnPropShavingMAC.setText("SAC");
	//btnPropShavingMAC.setBorder(null);
        btnPropShavingMAC.setFont(standardbutton);
	btnPropShavingMAC.setActionCommand("propShavingMAC");
	btnPropShavingMAC.setLocation(10,60);
	//btnPropShavingMAC.setLocation(10,65);
	btnPropShavingMAC.setSize(0,0);
	btnPropShavingMAC.addActionListener(this);
	propogationPanel.add(btnPropShavingMAC);
		
	JButton btnPropShavingGAC = new JButton();
        btnPropShavingGAC.setText("SGAC");
	//btnPropShavingGAC.setBorder(null);
        btnPropShavingGAC.setFont(standardlabel);
	btnPropShavingGAC.setActionCommand("propShavingGAC");
	btnPropShavingGAC.setLocation(40,80);
	//btnPropShavingGAC.setLocation(85,65);
	btnPropShavingGAC.setSize(0,0);
	btnPropShavingGAC.addActionListener(this);
	propogationPanel.add(btnPropShavingGAC);
		
		
		
	//INTERACTIVE SEARCH PANEL ++++++++++++++++++++++++++++++++++++++++++++++ //
	//this section adds all the things for the radio buttons that let you select
	//which type of propogation you want to be done automatically.
	JPanel searchPanel = new JPanel();
	//searchPanel.setSize(290,130);
        searchPanel.setSize(0,0);
	searchPanel.setLocation(140,15);
	searchPanel.setBackground(Color.WHITE);
	searchPanel.setLayout(null);
	//draw a border
	Border etchedBdr4 = BorderFactory.createEtchedBorder();
	Border titleBdr4 = BorderFactory.createTitledBorder(etchedBdr4, "Click on the \"Hints\" button for help");
	Border emptyBdr4 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr4 = BorderFactory.createCompoundBorder(titleBdr4, emptyBdr4);
	searchPanel.setBorder(compoundBdr4);		
		
	final int FNLsearchYCoord = 30;
		
	JRadioButton autoPropNone = new JRadioButton("None");
	autoPropNone.setActionCommand("propNone");
	autoPropNone.setLocation(10,35);
        autoPropNone.setFont(standardlabel);
	autoPropNone.setBackground(Color.WHITE);
	autoPropNone.setSize(70,20);
	//.setSelected(true);
	//searchPanel.add(autoPropNone);
        binaryPanel.add(autoPropNone);
		
	JLabel searchBinaryLabel = new JLabel("Search method");
        searchBinaryLabel.setLocation(10,FNLsearchYCoord-10);
	//searchBinaryLabel.setLocation(10,FNLsearchYCoord+5);
	searchBinaryLabel.setSize(120,15);
	//searchPanel.add(searchBinaryLabel);
        binaryPanel.add(searchBinaryLabel);
		
	//		JLabel searchNonBinaryLabel = new JLabel("Non-Binary");
	//		searchNonBinaryLabel.setLocation(105,FNLsearchYCoord);
	//		searchNonBinaryLabel.setSize(65, 15);
	//		searchPanel.add(searchNonBinaryLabel);
		
	JRadioButton autoPropBackchecking = new JRadioButton("Backward Chaining");
	autoPropBackchecking.setActionCommand("propBackChecking");
        autoPropBackchecking.setFont(standardlabel);
	autoPropBackchecking.setLocation(10,FNLsearchYCoord + 25);
	autoPropBackchecking.setBackground(Color.WHITE);
	autoPropBackchecking.setSize(150,15);
	autoPropBackchecking.setSelected(true);
        autoPropBackchecking.setToolTipText("Backward Chaining: All current decisions (i.e., " +
                "assignments) are correct.  Every new assignment is checked " +
                "against past ones.  If it is not consistent, the broken " +
                "constraint is highlighted in red.");
        autoPropBackchecking.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta2.setText("Backward Chaining: All current decisions (i.e., " +
                        "assignments) are correct.  Every new assignment is " +
                        "checked against past ones.  If it is not consistent, " +
                        "the broken constraint is highlighted in red.");
                description2.setText("Description: Backward Chaining");
            }
        });
	//searchPanel.add(autoPropBackchecking);
        binaryPanel.add(autoPropBackchecking);
	autoPropogationType = "propBackChecking";
		
	JRadioButton fcSearch = new JRadioButton("Forward Chaining");
	fcSearch.setActionCommand("propBinaryFC");
        fcSearch.setFont(standardlabel);
	fcSearch.setLocation(10,FNLsearchYCoord+40);
	fcSearch.setBackground(Color.WHITE);
	fcSearch.setSize(150,15);
        fcSearch.setToolTipText("Forward Chaining: After every decision (i.e., assignment), the " +
                "assigned value is removed from all cells in the same row, " +
                "column and block as the assigned cell.  FC stands for " +
                "forward checking, which is a weak form of look-ahead.");
	//searchPanel.add(fcSearch);
        fcSearch.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta2.setText("Forward Chaining: After every decision (i.e., assignment), the " +
                "assigned value is removed from all cells in the same row, " +
                "column and block as the assigned cell.  FC stands for " +
                "forward checking, which is a weak form of look-ahead.");
                description2.setText("Description: Forward Chaining");
            }
        });
        binaryPanel.add(fcSearch);

		
	JRadioButton macSearch = new JRadioButton("Maintaining Arc Consistency");
	macSearch.setActionCommand("propBinaryMAC");
        macSearch.setFont(standardlabel);
	macSearch.setLocation(10,FNLsearchYCoord+55);
	macSearch.setBackground(Color.WHITE);
	macSearch.setSize(200,15);
        macSearch.setToolTipText("Maintaining Arc Consistency: After every decision (i.e., assignment), FC " +
                "is enforced, then AC is enforced.  At the end of the process, " +
                "every combination of two cells have consistent combinations of " +
                "values.  MAC stands for Maintaining Arc Consistency, which is " +
                "a full look-ahead schema and is restricted to combinations of " +
                "two cells.");
        macSearch.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta2.setText("Maintaining Arc Consistency: After every decision (i.e., assignment), FC " +
                "is enforced, then AC is enforced.  At the end of the process, " +
                "every combination of two cells have consistent combinations of " +
                "values.  MAC stands for Maintaining Arc Consistency, which is " +
                "a full look-ahead schema and is restricted to combinations of " +
                "two cells.");
                description2.setText("Description: Maintaining Arc Consistency");
            }
        });
	//searchPanel.add(macSearch);
        binaryPanel.add(macSearch);
		
	//which type of propogation you want to preform.
	hintPanel = new JPanel();
	hintPanel.setSize(215,110);
	//min x = 71
	hintPanel.setLocation(180,10);
	hintPanel.setBackground(Color.WHITE);
	hintPanel.setLayout(null);

        Border etchedBdr5 = BorderFactory.createEtchedBorder();
	Border titleBdr5 = BorderFactory.createTitledBorder(etchedBdr5, "Hints");
	Border emptyBdr5 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr5 = BorderFactory.createCompoundBorder(titleBdr5, emptyBdr5);
	//propogationPanel.setBorder(titleBdr2);
	hintPanel.setBorder(compoundBdr5);
		
	hintButtonHandler myHintHandler = new hintButtonHandler();
	final int FNL_HINT_X_OFST = 3;
	final int FNL_HINT_Y_OFST = 3;
		
	findHintButton = new JButton();
        findHintButton.setText("Hint:");
	findHintButton.setActionCommand("hintFind");
	findHintButton.setName("hintFind");
	//findHintButton.setBorder(null);
        findHintButton.setFont(standardbutton);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	findHintButton.addActionListener(myHintHandler);
	findHintButton.setLocation(FNL_HINT_X_OFST+5,FNL_HINT_Y_OFST+15);
	findHintButton.setSize(80, 20);
	hintPanel.add(findHintButton);
		
	JButton displayHintButton = new JButton("Display");
	displayHintButton.setActionCommand("hintDisplay");
	displayHintButton.setName("hintDisplay");
	displayHintButton.setBorder(null);
	displayHintButton.setFont(standardbutton);
	displayHintButton.addMouseListener(myHintHandler);
	displayHintButton.setLocation(FNL_HINT_X_OFST+105,FNL_HINT_Y_OFST+15);
	displayHintButton.setSize(70, 15);
	displayHintButton.setEnabled(false);
	hintPanel.add(displayHintButton);
		
	JButton prevHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "prevarrow.GIF")));
	prevHintButton.setName("hintPrev");
	prevHintButton.setActionCommand("hintPrev");
	prevHintButton.setBorder(null);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	prevHintButton.addActionListener(myHintHandler);
	prevHintButton.setLocation(FNL_HINT_X_OFST+90,FNL_HINT_Y_OFST+15);
	prevHintButton.setSize(14, 15);
	prevHintButton.setEnabled(false);
	hintPanel.add(prevHintButton);

        JButton nextHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nextarrow.GIF")));
	nextHintButton.setName("hintNext");
	nextHintButton.setActionCommand("hintNext");
	nextHintButton.setBorder(null);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	nextHintButton.addActionListener(myHintHandler);
	nextHintButton.setLocation(FNL_HINT_X_OFST+175,FNL_HINT_Y_OFST+15);
	nextHintButton.setSize(14, 15);
	nextHintButton.setEnabled(false);
	hintPanel.add(nextHintButton);
		
	JLabel levelHintsLabel = new JLabel("Algorithm:");
	levelHintsLabel.setName("hintLevelLabel");
	levelHintsLabel.setLocation(FNL_HINT_X_OFST+5,FNL_HINT_Y_OFST+35);
	levelHintsLabel.setSize(70, 15);
	levelHintsLabel.setEnabled(false);
	hintPanel.add(levelHintsLabel);
		
	JLabel levelDisplayLabel = new JLabel("");
	levelDisplayLabel.setName("hintLevelDisplayLabel");
	levelDisplayLabel.setLocation(FNL_HINT_X_OFST+90,FNL_HINT_Y_OFST+35);
	levelDisplayLabel.setSize(75, 15);
	levelDisplayLabel.setEnabled(false);
        levelDisplayLabel.setFont(standardlabel);
	hintPanel.add(levelDisplayLabel);		
		
	JButton prevLevelHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "prevarrow.GIF")));
	prevLevelHintButton.setName("hintLevelPrev");
	prevLevelHintButton.setActionCommand("hintLevelPrev");
	prevLevelHintButton.setBorder(null);
	prevLevelHintButton.addActionListener(myHintHandler);
	prevLevelHintButton.setLocation(FNL_HINT_X_OFST+75,FNL_HINT_Y_OFST+35);
	prevLevelHintButton.setSize(14, 15);
	prevLevelHintButton.setEnabled(false);
	hintPanel.add(prevLevelHintButton);

        JButton nextLevelHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nextarrow.GIF")));
	nextLevelHintButton.setName("hintLevelNext");
	nextLevelHintButton.setActionCommand("hintLevelNext");
	nextLevelHintButton.setBorder(null);
	nextLevelHintButton.addActionListener(myHintHandler);
	nextLevelHintButton.setLocation(FNL_HINT_X_OFST+185,FNL_HINT_Y_OFST+35);
	nextLevelHintButton.setSize(14, 15);
	nextLevelHintButton.setEnabled(false);
	hintPanel.add(nextLevelHintButton);
		
	JLabel typeHintsLabel = new JLabel("Type:");
	typeHintsLabel.setName("hintTypeLabel");
	typeHintsLabel.setLocation(FNL_HINT_X_OFST+5,FNL_HINT_Y_OFST+55);
	typeHintsLabel.setSize(50, 15);
	typeHintsLabel.setEnabled(false);
	hintPanel.add(typeHintsLabel);
		
	JRadioButton typeSingleton = new JRadioButton("Singleton");
	typeSingleton.setActionCommand("hintTypeSingleton");
        typeSingleton.setFont(standardlabel);
	typeSingleton.addActionListener(myHintHandler);
	typeSingleton.setName("hintTypeSingleton");
	typeSingleton.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+75);
	typeSingleton.setBackground(Color.WHITE);
	typeSingleton.setSize(100,15);
	typeSingleton.setEnabled(false);
	hintPanel.add(typeSingleton);
		
	JRadioButton typeVital = new JRadioButton("Vital");
        typeVital.setFont(standardlabel);
	typeVital.setName("hintTypeVital");
	typeVital.setActionCommand("hintTypeVital");
	typeVital.addActionListener(myHintHandler);
	typeVital.setLocation(FNL_HINT_X_OFST+100,FNL_HINT_Y_OFST+75);
	typeVital.setBackground(Color.WHITE);
	typeVital.setSize(80,15);
	typeVital.setEnabled(false);
	hintPanel.add(typeVital);
		
	ButtonGroup hintGroup = new ButtonGroup();
	hintGroup.add(typeVital);
	hintGroup.add(typeSingleton);
	appearancePanel.add(hintPanel);
		
	//nonbinary column
	//		JRadioButton nfc1 = new JRadioButton("nFC-1");
	//		nfc1.setActionCommand("propNFC1");
	//		nfc1.setLocation(105,FNLsearchYCoord+15);
	//		nfc1.setBackground(Color.WHITE);
	//		nfc1.setSize(60,15);
	//		searchPanel.add(nfc1);
	//		
	//		JRadioButton nfc2 = new JRadioButton("nFC-2");
	//		nfc2.setActionCommand("propNFC2");
	//		nfc2.setLocation(105,FNLsearchYCoord+30);
	//		nfc2.setBackground(Color.WHITE);
	//		nfc2.setSize(60,15);
	//		searchPanel.add(nfc2);
	//		
	//		JRadioButton nfc3 = new JRadioButton("nFC-3");
	//		nfc3.setActionCommand("propNFC3");
	//		nfc3.setLocation(105,FNLsearchYCoord+45);
	//		nfc3.setBackground(Color.WHITE);
	//		nfc3.setSize(60,15);
	//		searchPanel.add(nfc3);
	//		
	//		JRadioButton nfc4 = new JRadioButton("nFC-4");
	//		nfc4.setActionCommand("propNFC4");
	//		nfc4.setLocation(105,FNLsearchYCoord+60);
	//		nfc4.setBackground(Color.WHITE);
	//		nfc4.setSize(60,15);
	//		searchPanel.add(nfc4);
	//		
	//		JRadioButton nfc5 = new JRadioButton("nFC-5");
	//		nfc5.setActionCommand("propNFC5");
	//		nfc5.setLocation(105,FNLsearchYCoord+75);
	//		nfc5.setBackground(Color.WHITE);
	//		nfc5.setSize(60,15);
	//		searchPanel.add(nfc5);
		
	ButtonGroup propogationGroup = new ButtonGroup();
	propogationGroup.add(macSearch);
	propogationGroup.add(fcSearch);
	//		propogationGroup.add(nfc1);
	//		propogationGroup.add(nfc2);
	//		propogationGroup.add(nfc3);
	//		propogationGroup.add(nfc4);
	//		propogationGroup.add(nfc5);
	propogationGroup.add(autoPropBackchecking);
        propogationGroup.add(autoPropNone);
        macSearch.setSelected(false);
        fcSearch.setSelected(false);
        autoPropBackchecking.setSelected(false);
        autoPropNone.setSelected(true);
        
	//END INTERACTIVE SEARCH PANEL ++++++++++++++++++++++++++++++++++++++++++++++ //
		
	//add everything in reverse order so everything is there
	//when it displays
	interactiveModePanel.add(searchPanel);
	interactiveModePanel.add(appearancePanel);
	interactiveModePanel.add(propogationPanel);

        JButton stopButton = new JButton();
	stopButton.setActionCommand("stop!");
	stopButton.setBorder(null);
	stopButton.setFont(standardbutton);
	stopButton.addActionListener(this);
        stopButton.setText("Stop Process");
	stopButton.setSize(100,30);
        stopButton.setLocation(20,155);

        interactiveModePanel.add(stopButton);

        JButton btnAutoAssign = new JButton();
	btnAutoAssign.setBorder(null);
	btnAutoAssign.setFont(standardbutton);
	btnAutoAssign.setText("Assign Singletons");
	btnAutoAssign.addActionListener(this);
	btnAutoAssign.setActionCommand("assignSingletons");
	btnAutoAssign.setLocation(130,155);
	btnAutoAssign.setSize(100,30);

        interactiveModePanel.add(btnAutoAssign);
        
	this.add(interactiveModePanel);
		
	propogationButtonHandler pbh = new propogationButtonHandler();
	macSearch.addActionListener(pbh);
	fcSearch.addActionListener(pbh);
	autoPropBackchecking.addActionListener(pbh);
	//		nfc1.addActionListener(pbh);
	//		nfc2.addActionListener(pbh);
	//		nfc3.addActionListener(pbh);
	//		nfc4.addActionListener(pbh);
	//		nfc5.addActionListener(pbh);
	autoPropNone.addActionListener(pbh);
        
	this.doAutoPropogation();
	this.repaint();
        optInstance.doClick();
    }


    public void createTabs(){
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jTabbedPane1.addChangeListener(new tabChangeListener() );
//        jTabbedPane1.setSize(1000, 2000);
        selectPanel = new javax.swing.JPanel();
        optInstance = new javax.swing.JRadioButton();
        optDatabase = new javax.swing.JRadioButton();
        databasePanel = new javax.swing.JPanel();
        instancePanel = new javax.swing.JPanel();
        selectGroup = new javax.swing.ButtonGroup();

        jScrollPane1 = new javax.swing.JScrollPane();
        tbPuzzles = new javax.swing.JTable();
        playPanel = new javax.swing.JPanel();

        createPanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();

        algorithmPanel = new javax.swing.JPanel();
        selectPanel.setLocation(0, 0);
        //Build the Select a Puzzle tab
        selectPanel.setLayout(null);

        ActionListener dbListener = new ShowDatabaseListener(this);
		ActionListener intListener = new ShowInstanceListener(this);
                ChangeListener stl = new SelectedTabListener(this);
        optDatabase.setText("From Database");
        optDatabase.setSize(120,23);
        optDatabase.setLocation(280,20);
        optDatabase.addActionListener(dbListener);
        selectGroup.add(optDatabase);
        selectPanel.add(optDatabase);

        optInstance.setText("From File");
        optInstance.setSize(120,23);
        optInstance.setLocation(150, 20);
	optInstance.addActionListener(intListener);
		
        selectGroup.add(optInstance);
        selectPanel.add(optInstance);

        jTabbedPane1.addTab("Select a Puzzle", selectPanel);

        //Build the Play tab
        playPanel.setLayout(null);

        jTabbedPane1.addTab("Play", playPanel);

        //Build the Create a Puzzle tab
        createPanel.setLayout(null);
        
        jLabel3.setText("Sudoku Type");
        jLabel3.setSize(82,14);
        jLabel3.setLocation(30,15);
        createPanel.add(jLabel3);
        
        jLabel6.setText("Min");
        jLabel6.setSize(25,14);
        jLabel6.setLocation(30,150);
        createPanel.add(jLabel6);

        jLabel7.setText("This Puzzle");
        jLabel7.setSize(65,14);
        jLabel7.setLocation(70,150);
        createPanel.add(jLabel7);

        jLabel11.setText("Max");
        jLabel11.setSize(25,14);
        jLabel11.setLocation(150,150);
        createPanel.add(jLabel11);
        
        jLabel8.setText("Difficulty Level");
        jLabel8.setSize(90,14);
        jLabel8.setLocation(30,125);
        createPanel.add(jLabel8);
        
        jLabel9.setText("Source (e.g. URL, your name)");
        jLabel9.setSize(200,14);
        jLabel9.setLocation(30,90);
        createPanel.add(jLabel9);

        jLabel10.setText("Name of Puzzle");
        jLabel10.setSize(90,14);
        jLabel10.setLocation(30,200);
        createPanel.add(jLabel10);

        jLabel12.setText("Name of Puzzle in Original Source");
        jLabel12.setSize(250,14);
        jLabel12.setLocation(30,250);
        createPanel.add(jLabel12);

        jLabel13.setText("Enter Description");
        jLabel13.setSize(125,14);
        jLabel13.setLocation(30,300);
        createPanel.add(jLabel13);

//        jTabbedPane1.addTab("Create a Puzzle", createPanel);
        constructorPanel = new constructorInterface(this);
        jTabbedPane1.addTab("Create a Puzzle", constructorPanel);
        
        //Build the Solve with Algorithms Tab
        algorithmPanel.setLayout(null);

        JPanel consistencyPanel = new JPanel();
	consistencyPanel.setSize(475,160);
	consistencyPanel.setLocation(15,145);
	consistencyPanel.setBackground(Color.WHITE);
	consistencyPanel.setLayout(null);

        Border etchedBdr2 = BorderFactory.createEtchedBorder();
	Border titleBdr2 = BorderFactory.createTitledBorder(etchedBdr2, "Consistency");
	Border emptyBdr2 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr2 = BorderFactory.createCompoundBorder(titleBdr2, emptyBdr2);
	//propogationPanel.setBorder(titleBdr2);
	consistencyPanel.setBorder(compoundBdr2);

        JLabel consInstruction = new JLabel("The buttons below and the set of " +
                "buttons surrounding the board perform a ");
        JLabel consInstruction2 = new JLabel("check and " +
                "removes any inconsistent values from the corresponding cell.");
        JTextArea consInstruction3 = new JTextArea("Removes all values that cannot appear in a solution to the cells in the block.");
        //JScrollPane jsp3 = new JScrollPane(consInstruction3);
        JTextArea consInstruction4 = new JTextArea("Removes a value that is assigned to " +
                "a cell from all other cells in the block .");
        //JScrollPane jsp4 = new JScrollPane(consInstruction4);

        consInstruction.setSize(460,17);
        consInstruction.setLocation(10,20);
        consistencyPanel.add(consInstruction);

        consInstruction2.setSize(460,17);
        consInstruction2.setLocation(10,35);
        consistencyPanel.add(consInstruction2);

        consInstruction3.setLineWrap(true);
        consInstruction3.setWrapStyleWord(true);
        consInstruction3.setSize(130,70);
        consInstruction3.setLocation(100,65);
        consInstruction3.setBorder(BorderFactory.createLineBorder(Color.WHITE));
        //jsp3.setSize(130,70);
        //jsp3.setLocation(100,65);
        consistencyPanel.add(consInstruction3);

        consInstruction4.setLineWrap(true);
        consInstruction4.setWrapStyleWord(true);
        consInstruction4.setSize(130,70);
        consInstruction4.setLocation(320,65);
        consInstruction3.setBorder(BorderFactory.createLineBorder(Color.WHITE));
        //jsp4.setSize(130,70);
        //jsp4.setLocation(320,65);
        consistencyPanel.add(consInstruction4);

        //JPanel binaryPanel = new JPanel();
	binaryPanel.setSize(475,120);
	binaryPanel.setLocation(15,305);
	binaryPanel.setBackground(Color.WHITE);
	binaryPanel.setLayout(null);

        Border etchedBdr4 = BorderFactory.createEtchedBorder();
	Border titleBdr4 = BorderFactory.createTitledBorder(etchedBdr4, "Binary");
	Border emptyBdr4 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr4 = BorderFactory.createCompoundBorder(titleBdr4, emptyBdr4);
	//propogationPanel.setBorder(titleBdr2);
	binaryPanel.setBorder(compoundBdr4);

        algorithmPanel.add(binaryPanel);

//        consistencyButtonHandler cbh = new consistencyButtonHandler();
        int cellWidth = playingBoard.getCellWidth();
	int cellHeight = playingBoard.getCellHeight();
        
        //make the unit buttons
	btnAllDifUnitConsis = new JButton[unitsHigh*unitsWide];
	btnBinUnitConsis = new JButton[unitsHigh*unitsWide];

	for(int colIndex=0; colIndex < unitsWide; colIndex++)
	    {
		for(int rowIndex=0; rowIndex < unitsHigh; rowIndex++)
		    {
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nonBinaryUnit.GIF")));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setBorder(null);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setText("");
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setActionCommand("a;u;"+(rowIndex+1)+";"+(colIndex+1));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].addActionListener(cbh);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].addMouseListener(cbh);
			//TODO: need to make its location and possibly size more dynamic
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setLocation(40+((cellWidth/2) * colIndex), ((cellHeight/2) * rowIndex) + 215);
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setSize(((cellWidth/2)-1),((cellHeight/2)-1));
			btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex].setToolTipText("Nonbinary unit "+(rowIndex+1)+","+(colIndex+1));
			algorithmPanel.add(btnAllDifUnitConsis[(colIndex * unitsHigh) + rowIndex]);

			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex] = new JButton(new ImageIcon(getImage(this.getCodeBase(), "binaryUnit.GIF")));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setBorder(null);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setText("");
			//btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setBackground(new Color(23,45,156));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setActionCommand("b;u;"+(rowIndex+1)+";"+(colIndex+1));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].addActionListener(cbh);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].addMouseListener(cbh);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setLocation(260+((cellWidth/2) * colIndex), ((cellHeight/2) * rowIndex) + 215);
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setSize(((cellWidth/2)-1),((cellHeight/2)-1));
			btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex].setToolTipText("Binary unit "+(rowIndex+1)+","+(colIndex+1));
			algorithmPanel.add(btnBinUnitConsis[(colIndex * unitsHigh) + rowIndex]);
		    }
	    }

        appearancePanel = new JPanel();
	appearancePanel.setSize(400,130);
        //appearancePanel.setSize(0,0);
	appearancePanel.setLocation(15,20);
	appearancePanel.setBackground(Color.WHITE);
	appearancePanel.setLayout(null);
        Font standardbutton = new Font("Times Unicode", Font.PLAIN, 10);
        Font standardlabel = new Font("Times Unicode", Font.PLAIN, 12);
        //draw a border
	Border etchedBdr3 = BorderFactory.createEtchedBorder();
	Border titleBdr3 = BorderFactory.createTitledBorder(etchedBdr3, "Board features");
	Border emptyBdr3 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr3 = BorderFactory.createCompoundBorder(titleBdr3, emptyBdr3);
	appearancePanel.setBorder(compoundBdr3);

        JLabel numElimLabelLabel1 = new JLabel("Values eliminated:");
	numElimLabelLabel1.setLocation(15,55);
        numElimLabelLabel1.setFont(standardlabel);
	numElimLabelLabel1.setSize(150,20);
	appearancePanel.add(numElimLabelLabel1);

	numberEliminatedLabel = new JLabel("");
	numberEliminatedLabel.setLocation(135,55);
	numberEliminatedLabel.setSize(100,20);
	appearancePanel.add(numberEliminatedLabel);

	showDomains = false;
	JCheckBox domainBox = new JCheckBox("Display mini numbers", false);
	domainBox.setActionCommand("showDomains");
	domainBox.setSize(160,20);
        domainBox.setFont(standardlabel);
	domainBox.setLocation(15,80);
	domainBox.setBackground(Color.WHITE);
	domainBox.addItemListener(this);
	appearancePanel.add(domainBox);
        /*
	JLabel leftMouseLabel = new JLabel("Insert undo Button");
	leftMouseLabel.setSize(120,15);
        leftMouseLabel.setFont(standardlabel);
	leftMouseLabel.setLocation(15, 45);
	appearancePanel.add(leftMouseLabel);
	JLabel rightMouseLabel = new JLabel("Insert redo button");
	rightMouseLabel.setSize(120,15);
        rightMouseLabel.setFont(standardlabel);
	rightMouseLabel.setLocation(15, 75);
	appearancePanel.add(rightMouseLabel);
        */
        
        JButton btnUndo = new JButton();
	btnUndo.setBorder(null);
	btnUndo.setFont(standardbutton);
	btnUndo.setText("Undo");
	btnUndo.addActionListener(this);
	btnUndo.setActionCommand("undo");
	btnUndo.setLocation(15,25);
	btnUndo.setSize(70,20);
	appearancePanel.add(btnUndo);
        
        JButton btnRedo = new JButton();
	btnRedo.setBorder(null);
	btnRedo.setText("Redo");
        btnRedo.setFont(standardbutton);
	btnRedo.addActionListener(this);
	btnRedo.setActionCommand("redo");
	btnRedo.setLocation(95, 25);
	btnRedo.setSize(70,20);
	appearancePanel.add(btnRedo);
        
        JPanel propogationPanel = new JPanel();
	propogationPanel.setSize(475,130);
	propogationPanel.setLocation(15,15);
	propogationPanel.setBackground(Color.WHITE);
	propogationPanel.setLayout(null);
	//draw a border
	//Border etchedBdr5 = BorderFactory.createEtchedBorder();
	//Border titleBdr5 = BorderFactory.createTitledBorder(etchedBdr5, "Propagation");
	//Border emptyBdr5 = BorderFactory.createEmptyBorder(10,10,10,10);
	//Border compoundBdr5 = BorderFactory.createCompoundBorder(titleBdr5, emptyBdr5);
	//propogationPanel.setBorder(titleBdr2);
	propogationPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"Propagation"), BorderFactory.createEmptyBorder(10,10,10,10)));

        //JLabel description = new JLabel("Description");
        description.setSize(300,15);
        description.setLocation(150,20);

        description2.setSize(200,15);
        description2.setLocation(210,20);
        
        //JTextArea jta = new JTextArea();
        jta.setEditable(false);
        jta.setSize(300,80);
        jta.setLocation(150,40);
        jta.setBorder(etchedBdr2);
        jta.setLineWrap(true);
        jta.setWrapStyleWord(true);

        JScrollPane jsp = new JScrollPane(jta);
        //jsp.setPreferredSize(new Dimension(100,100));

        jsp.setSize(300, 80);
        jsp.setLocation(150,40);

        //JTextArea jta = new JTextArea();
        jta2.setEditable(false);
        jta2.setSize(300,80);
        jta2.setLocation(150,40);
        jta2.setBorder(etchedBdr2);
        jta2.setLineWrap(true);
        jta2.setWrapStyleWord(true);

        JScrollPane jsp2 = new JScrollPane(jta2);
        //jsp.setPreferredSize(new Dimension(100,100));

        jsp2.setSize(250, 70);
        jsp2.setLocation(210,40);

        propogationPanel.add(description);
        propogationPanel.add(jsp);

        binaryPanel.add(description2);
        binaryPanel.add(jsp2);

	JLabel numElimLabelLabel = new JLabel("Algorithm Types");
	numElimLabelLabel.setLocation(10,20);
        //numElimLabelLabel.setFont(standardlabel);
	numElimLabelLabel.setSize(155, 15);
	propogationPanel.add(numElimLabelLabel);
/*
        this.numberEliminatedLabel = new JLabel("123");
	this.numberEliminatedLabel.setLocation(115,25);
	this.numberEliminatedLabel.setSize(60, 15);
	propogationPanel.add(numberEliminatedLabel);
*/
        JButton btnPropBinaryMAC = new JButton();
        btnPropBinaryMAC.setText("AC");
	//btnPropBinaryMAC.setBorder(null);
        btnPropBinaryMAC.setFont(standardbutton);
	btnPropBinaryMAC.setActionCommand("propBinaryMAC");
	btnPropBinaryMAC.setLocation(30, 40);
	//btnPropBinaryMAC.setLocation(10,45);
	btnPropBinaryMAC.setSize(75,15);
	btnPropBinaryMAC.addActionListener(this);
        btnPropBinaryMAC.addKeyListener(this);
        btnPropBinaryMAC.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta.setText("Arc Consistency: Considering every combination of " +
                        "two cells, a value for a given cell that is not " +
                        "consistent with any other possible value for the other " +
                        "cell is removed.  Combinations of two cells are " +
                        "considered over and over again until no value is removed");
                description.setText("Description: Arc Consistency");
            }
        });
	propogationPanel.add(btnPropBinaryMAC);

	JButton btnPropNonBinaryGAC = new JButton();
        btnPropNonBinaryGAC.setText("GAC");
	//btnPropNonBinaryGAC.setBorder(null);
        btnPropNonBinaryGAC.setFont(standardbutton);
	btnPropNonBinaryGAC.setActionCommand("propNonBinaryGAC");
	btnPropNonBinaryGAC.setLocation(30,60);
	//	btnPropNonBinaryGAC.setLocation(85,45);
	btnPropNonBinaryGAC.setSize(75,15);
	btnPropNonBinaryGAC.addActionListener(this);
        btnPropNonBinaryGAC.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta.setText("Generalized Arc Consistency: Considering every " +
                        "combination of nine cells in a row, column, and block, " +
                        "values for cells that cannot possibly participate in a " +
                        "consistent solution for the row, column or block are " +
                        "removed.  The process is repeated for each of the 27 " +
                        "combinations until no value is removed.  " +
                        "GAC is strictly stronger than AC.  However, SAC and " +
                        "GAC are not comparable, that is, one may do more " +
                        "pruning than the other depending on the situation at hand.");
                description.setText("Description: Generalized Arc Consistency");
            }
        });
	propogationPanel.add(btnPropNonBinaryGAC);

	JButton btnPropShavingMAC = new JButton();
        btnPropShavingMAC.setText("SAC");
	//btnPropShavingMAC.setBorder(null);
        btnPropShavingMAC.setFont(standardbutton);
	btnPropShavingMAC.setActionCommand("propShavingMAC");
	btnPropShavingMAC.setLocation(30,80);
	//btnPropShavingMAC.setLocation(10,65);
	btnPropShavingMAC.setSize(75,15);
	btnPropShavingMAC.addActionListener(this);
        btnPropShavingMAC.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta.setText("Shaving Arc Consistency: Assuming that a given " +
                        "cell takes a fixed possible value, AC is enforced on " +
                        "the problem.  If AC does not remove all values from " +
                        "any other cell, the considered value is kept as " +
                        "possible for the considered variable.  Otherwise, the " +
                        "value is removed.  The mechanism is repeated for each " +
                        "possible value for each variable and no value is " +
                        "removed. SAC is strictly stronger than AC.  However, " +
                        "SAC and GAC are not comparable, that is, one may do " +
                        "more pruning than the other depending on the situation at hand.");
                description.setText("Description: Shaving Arc Consistency");
            }
        });
	propogationPanel.add(btnPropShavingMAC);

	JButton btnPropShavingGAC = new JButton();
        btnPropShavingGAC.setText("SGAC");
	//btnPropShavingGAC.setBorder(null);
        btnPropShavingGAC.setFont(standardlabel);
	btnPropShavingGAC.setActionCommand("propShavingGAC");
	btnPropShavingGAC.setLocation(30,100);
	//btnPropShavingGAC.setLocation(85,65);
	btnPropShavingGAC.setSize(75,15);
	btnPropShavingGAC.addActionListener(this);
        btnPropShavingGAC.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                jta.setText("Shaving Generalized Arc Consistency: Assuming that " +
                        "a given cell takes a fixed possible value, GAC is " +
                        "enforced on the problem.  If GAC does not remove all " +
                        "values from any other cell, the considered value is " +
                        "kept as possible for the considered variable.  " +
                        "Otherwise, the value is removed.  " +
                        "The mechanism is repeated for each possible value for " +
                        "each variable and no value is removed. SGAC is " +
                        "strictly stronger than GAC and SAC. It solves all " +
                        "known hardest Sudoku instances except three of them.");
                description.setText("Description: Shaving Generalized Arc Consistency");
            }
        });
	propogationPanel.add(btnPropShavingGAC);
        

      
/*
        //INTERACTIVE SEARCH PANEL ++++++++++++++++++++++++++++++++++++++++++++++ //
	//this section adds all the things for the radio buttons that let you select
	//which type of propogation you want to be done automatically.
	JPanel searchPanel = new JPanel();
	searchPanel.setSize(290,130);
	searchPanel.setLocation(15,145);
	searchPanel.setBackground(Color.WHITE);
	searchPanel.setLayout(null);
	//draw a border
	Border etchedBdr4 = BorderFactory.createEtchedBorder();
	Border titleBdr4 = BorderFactory.createTitledBorder(etchedBdr4, "Interactive-Search");
	Border emptyBdr4 = BorderFactory.createEmptyBorder(10,10,10,10);
	Border compoundBdr4 = BorderFactory.createCompoundBorder(titleBdr4, emptyBdr4);
	searchPanel.setBorder(compoundBdr4);

	final int FNLsearchYCoord = 30;

	JRadioButton autoPropNone = new JRadioButton("None");
	autoPropNone.setActionCommand("propNone");
	autoPropNone.setLocation(10,15);
        autoPropNone.setFont(standardlabel);
	autoPropNone.setBackground(Color.WHITE);
	autoPropNone.setSize(70,20);
	//.setSelected(true);
	searchPanel.add(autoPropNone);

	JLabel searchBinaryLabel = new JLabel("Binary");
	searchBinaryLabel.setLocation(10,FNLsearchYCoord+5);
	searchBinaryLabel.setSize(60, 15);
	searchPanel.add(searchBinaryLabel);

	//		JLabel searchNonBinaryLabel = new JLabel("Non-Binary");
	//		searchNonBinaryLabel.setLocation(105,FNLsearchYCoord);
	//		searchNonBinaryLabel.setSize(65, 15);
	//		searchPanel.add(searchNonBinaryLabel);

	JRadioButton autoPropBackchecking = new JRadioButton("BC");
	autoPropBackchecking.setActionCommand("propBackChecking");
        autoPropBackchecking.setFont(standardlabel);
	autoPropBackchecking.setLocation(10,FNLsearchYCoord + 20);
	autoPropBackchecking.setBackground(Color.WHITE);
	autoPropBackchecking.setSize(60,15);
	autoPropBackchecking.setSelected(true);
	searchPanel.add(autoPropBackchecking);
	autoPropogationType = "propBackChecking";

	JRadioButton fcSearch = new JRadioButton("FC");
	fcSearch.setActionCommand("propBinaryFC");
        fcSearch.setFont(standardlabel);
	fcSearch.setLocation(10,FNLsearchYCoord+35);
	fcSearch.setBackground(Color.WHITE);
	fcSearch.setSize(60,15);
	searchPanel.add(fcSearch);

	JRadioButton macSearch = new JRadioButton("MAC");
	macSearch.setActionCommand("propBinaryMAC");
        macSearch.setFont(standardlabel);
	macSearch.setLocation(10,FNLsearchYCoord+50);
	macSearch.setBackground(Color.WHITE);
	macSearch.setSize(60,15);
	searchPanel.add(macSearch);

	//which type of propogation you want to preform.
	hintPanel = new JPanel();
	hintPanel.setSize(195,105);
	//min x = 71
	hintPanel.setLocation(90,15);
	hintPanel.setBackground(Color.WHITE);
	hintPanel.setLayout(null);
	hintPanel.setBorder(BorderFactory.createEtchedBorder());

	hintButtonHandler myHintHandler = new hintButtonHandler();
	final int FNL_HINT_X_OFST = 3;
	final int FNL_HINT_Y_OFST = 3;

	findHintButton = new JButton();
        findHintButton.setText("Hint:");
	findHintButton.setActionCommand("hintFind");
	findHintButton.setName("hintFind");
	//findHintButton.setBorder(null);
        findHintButton.setFont(standardbutton);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	findHintButton.addActionListener(myHintHandler);
	findHintButton.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+0);
	findHintButton.setSize(70, 15);
	hintPanel.add(findHintButton);

	JButton displayHintButton = new JButton("Display");
	displayHintButton.setActionCommand("hintDisplay");
	displayHintButton.setName("hintDisplay");
	displayHintButton.setBorder(null);
	displayHintButton.setFont(standardbutton);
	displayHintButton.addMouseListener(myHintHandler);
	displayHintButton.setLocation(FNL_HINT_X_OFST+85,FNL_HINT_Y_OFST+0);
	displayHintButton.setSize(70, 15);
	displayHintButton.setEnabled(false);
	hintPanel.add(displayHintButton);

	JButton prevHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "prevarrow.GIF")));
	prevHintButton.setName("hintPrev");
	prevHintButton.setActionCommand("hintPrev");
	prevHintButton.setBorder(null);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	prevHintButton.addActionListener(myHintHandler);
	prevHintButton.setLocation(FNL_HINT_X_OFST+70,FNL_HINT_Y_OFST+0);
	prevHintButton.setSize(14, 15);
	prevHintButton.setEnabled(false);
	hintPanel.add(prevHintButton);

        JButton nextHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nextarrow.GIF")));
	nextHintButton.setName("hintNext");
	nextHintButton.setActionCommand("hintNext");
	nextHintButton.setBorder(null);
	//findHintButton.setFont(new Font("Sarif",Font.PLAIN,10));
	nextHintButton.addActionListener(myHintHandler);
	nextHintButton.setLocation(FNL_HINT_X_OFST+155,FNL_HINT_Y_OFST+0);
	nextHintButton.setSize(14, 15);
	nextHintButton.setEnabled(false);
	hintPanel.add(nextHintButton);

	JLabel levelHintsLabel = new JLabel("Level:");
	levelHintsLabel.setName("hintLevelLabel");
	levelHintsLabel.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+20);
	levelHintsLabel.setSize(40, 15);
	levelHintsLabel.setEnabled(false);
	hintPanel.add(levelHintsLabel);

	JLabel levelDisplayLabel = new JLabel("");
	levelDisplayLabel.setName("hintLevelDisplayLabel");
	levelDisplayLabel.setLocation(FNL_HINT_X_OFST+60,FNL_HINT_Y_OFST+20);
	levelDisplayLabel.setSize(75, 15);
	levelDisplayLabel.setEnabled(false);
        levelDisplayLabel.setFont(standardlabel);
	hintPanel.add(levelDisplayLabel);

	JButton prevLevelHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "prevarrow.GIF")));
	prevLevelHintButton.setName("hintLevelPrev");
	prevLevelHintButton.setActionCommand("hintLevelPrev");
	prevLevelHintButton.setBorder(null);
	prevLevelHintButton.addActionListener(myHintHandler);
	prevLevelHintButton.setLocation(FNL_HINT_X_OFST+45,FNL_HINT_Y_OFST+20);
	prevLevelHintButton.setSize(14, 15);
	prevLevelHintButton.setEnabled(false);
	hintPanel.add(prevLevelHintButton);

        JButton nextLevelHintButton = new JButton(new ImageIcon(getImage(this.getCodeBase(), "nextarrow.GIF")));
	nextLevelHintButton.setName("hintLevelNext");
	nextLevelHintButton.setActionCommand("hintLevelNext");
	nextLevelHintButton.setBorder(null);
	nextLevelHintButton.addActionListener(myHintHandler);
	nextLevelHintButton.setLocation(FNL_HINT_X_OFST+155,FNL_HINT_Y_OFST+20);
	nextLevelHintButton.setSize(14, 15);
	nextLevelHintButton.setEnabled(false);
	hintPanel.add(nextLevelHintButton);

	JLabel typeHintsLabel = new JLabel("Type:");
	typeHintsLabel.setName("hintTypeLabel");
	typeHintsLabel.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+40);
	typeHintsLabel.setSize(50, 15);
	typeHintsLabel.setEnabled(false);
	hintPanel.add(typeHintsLabel);

	JRadioButton typeSingleton = new JRadioButton("Singleton");
	typeSingleton.setActionCommand("hintTypeSingleton");
        typeSingleton.setFont(standardlabel);
	typeSingleton.addActionListener(myHintHandler);
	typeSingleton.setName("hintTypeSingleton");
	typeSingleton.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+60);
	typeSingleton.setBackground(Color.WHITE);
	typeSingleton.setSize(100,15);
	typeSingleton.setEnabled(false);
	hintPanel.add(typeSingleton);

	JRadioButton typeVital = new JRadioButton("Vital");
        typeVital.setFont(standardlabel);
	typeVital.setName("hintTypeVital");
	typeVital.setActionCommand("hintTypeVital");
	typeVital.addActionListener(myHintHandler);
	typeVital.setLocation(FNL_HINT_X_OFST+0,FNL_HINT_Y_OFST+80);
	typeVital.setBackground(Color.WHITE);
	typeVital.setSize(80,15);
	typeVital.setEnabled(false);
	hintPanel.add(typeVital);

	ButtonGroup hintGroup = new ButtonGroup();
	hintGroup.add(typeVital);
	hintGroup.add(typeSingleton);
	searchPanel.add(hintPanel);

        ButtonGroup propogationGroup = new ButtonGroup();
	propogationGroup.add(macSearch);
	propogationGroup.add(fcSearch);

	propogationGroup.add(autoPropNone);
	propogationGroup.add(autoPropBackchecking);
        */
        
        jTabbedPane1.addTab("Solve with Algorithms", algorithmPanel);
        algorithmPanel.add(propogationPanel);
        algorithmPanel.add(consistencyPanel);
        //algorithmPanel.add(searchPanel);
        /*
        propogationPanel.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(true);
                    btnBinConsis[i].setEnabled(true);
                }
            }

            public void mouseExited(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(false);
                    btnBinConsis[i].setEnabled(false);
                }
            }
        });

        consistencyPanel.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(true);
                    btnBinConsis[i].setEnabled(true);
                }
            }

            public void mouseExited(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(false);
                    btnBinConsis[i].setEnabled(false);
                }
            }
        });
        
        algorithmPanel.addMouseListener(new MouseAdapter(){
            public void mouseEntered(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(true);
                    btnBinConsis[i].setEnabled(true);
                }
            }

            public void mouseExited(MouseEvent e){
                for(int i =0; i < 18; i++){
                    btnAllDifConsis[i].setEnabled(false);
                    btnBinConsis[i].setEnabled(false);
                }
            }
        });
*/
        jTabbedPane1.setLocation(460, 10);
        jTabbedPane1.setSize(500, 610);
        jTabbedPane1.addChangeListener(new SelectedTabListener(this));
        this.add(jTabbedPane1);

    }


    public void fromDatabase() throws Exception
	{
			ActionListener filter = new FilterListener(this);
            dbmysql database = new dbmysql();

            databasePanel = new javax.swing.JPanel();
            databasePanel.setSize(480,418);
            databasePanel.setLocation(15,50);
            databasePanel.setLayout(null);
            
            Font standard = new Font("Times Unicode", Font.PLAIN, 12);

            selectPanel.remove(instancePanel);

			

            String lbltxt4 =  "No. of Matches";
            dbDefaultLabel4 = new JLabel();
			dbDefaultLabel4.setLocation(350, 20);
			dbDefaultLabel4.setSize(250, 20);
            dbDefaultLabel4.setFont(standard);
			dbDefaultLabel4.setText(lbltxt4);
//			this.add(dbDefaultLabel4);
                        databasePanel.add(dbDefaultLabel4);

            String lbltxt6 = "Puzzle Name";
			dbDefaultBtn1 = new JButton(lbltxt6);
			dbDefaultBtn1.setLocation(5, 230);
			dbDefaultBtn1.setSize(150, 20);
            dbDefaultBtn1.setFont(standard);
            dbDefaultBtn1.setBorder(null);
			//dbDefaultBtn1.setText(lbltxt6);
            dbDefaultBtn1.addActionListener(this);
            dbDefaultBtn1.setActionCommand("orderby1");
//			this.add(dbDefaultBtn1);
            databasePanel.add(dbDefaultBtn1);

            String lbltxt10 = "Max Level";
			dbDefaultBtn2 = new JButton(lbltxt10);
			dbDefaultBtn2.setLocation(195, 230);
			dbDefaultBtn2.setSize(55, 20);
            dbDefaultBtn2.setFont(standard);
            dbDefaultBtn2.setBorder(null);
			//dbDefaultBtn2.setText(lbltxt10);
            dbDefaultBtn2.setActionCommand("orderby2");
            dbDefaultBtn2.addActionListener(this);
//			this.add(dbDefaultBtn2);
            databasePanel.add(dbDefaultBtn2);

            String lbltxt7 = "Level";
            dbDefaultBtn3 = new JButton(lbltxt7);
            dbDefaultBtn3.setLocation(260, 230);
            dbDefaultBtn3.setSize(55, 20);
            dbDefaultBtn3.setFont(standard);
            dbDefaultBtn3.setBorder(null);
			//dbDefaultBtn2.setText(lbltxt10);
            dbDefaultBtn3.setActionCommand("orderby3");
            dbDefaultBtn3.addActionListener(this);
//			this.add(dbDefaultBtn3);
            databasePanel.add(dbDefaultBtn3);

            String lbltxt8 = "Source";
            dbDefaultBtn4 = new JButton(lbltxt8);
            dbDefaultBtn4.setLocation(330, 230);
            dbDefaultBtn4.setSize(70, 20);
            dbDefaultBtn4.setFont(standard);
            dbDefaultBtn4.setBorder(null);
			//dbDefaultBtn2.setText(lbltxt10);
            dbDefaultBtn4.setActionCommand("orderby4");
            dbDefaultBtn4.addActionListener(this);
//			this.add(dbDefaultBtn4);
            databasePanel.add(dbDefaultBtn4);

            String lbltxt11 = "Solutions";
            dbDefaultBtn5 = new JButton(lbltxt11);
            dbDefaultBtn5.setLocation(510, 230);
            dbDefaultBtn5.setSize(50, 20);
            dbDefaultBtn5.setFont(standard);
            dbDefaultBtn5.setBorder(null);
			//dbDefaultBtn2.setText(lbltxt10);
            dbDefaultBtn5.setActionCommand("orderby5");
            dbDefaultBtn5.addActionListener(this);
//			this.add(dbDefaultBtn5);
            databasePanel.add(dbDefaultBtn5);

            String lbltxt12 = "Consistency";
			dbDefaultBtn6 = new JButton(lbltxt12);
			dbDefaultBtn6.setLocation(555, 200);
			dbDefaultBtn6.setSize(100, 230);
            dbDefaultBtn6.setFont(standard);
            dbDefaultBtn6.setBorder(null);
			//dbDefaultBtn2.setText(lbltxt10);
            dbDefaultBtn6.setActionCommand("orderby6");
            dbDefaultBtn6.addActionListener(this);
//			this.add(dbDefaultBtn6);
            databasePanel.add(dbDefaultBtn6);

            matchesBox = new JTextField();
            matchesBox.setText(database.numOfPuzzInDB() + "");
            matchesBox.setEditable(false);
            matchesBox.setSize(80,25);
            matchesBox.setLocation(350,50);
//            this.add(matchesBox);
            databasePanel.add(matchesBox);



            goButton = new JButton("Go!");
            goButton.setActionCommand("query");
            goButton.setFont(standard);
            goButton.addActionListener(this);
            goButton.setLocation(350,85);
            goButton.setSize(75, 20);
//			this.add(goButton);
            databasePanel.add(goButton);

            selectButton = new JButton("Select Puzzle");
			selectButton.setActionCommand("fromdb");
            selectButton.setFont(standard);
			selectButton.addActionListener(this);
			selectButton.setLocation(10,200);
			selectButton.setSize(130, 20);
//			this.add(selectButton);
                        databasePanel.add(selectButton);

            cancelButton = new JButton("Back");
			cancelButton.setActionCommand("canceldb");
            cancelButton.setFont(standard);
			cancelButton.addActionListener(this);
			cancelButton.setLocation(100,170);
			cancelButton.setSize(90, 20);
//			this.add(cancelButton);


            String lbltxt3 =  "Type";
            dbDefaultLabel3 = new JLabel();
			dbDefaultLabel3.setLocation(30, 20);
			dbDefaultLabel3.setSize(40, 20);
            dbDefaultLabel3.setFont(standard);
			dbDefaultLabel3.setText(lbltxt3);
//			this.add(dbDefaultLabel3);
                        databasePanel.add(dbDefaultLabel3);

            String[] puzzTypes = {"Base"};
            puzzTypeBox = new JComboBox(puzzTypes);
            puzzTypeBox.setSelectedIndex(0);
            puzzTypeBox.setLocation(135, 20);
            puzzTypeBox.setFont(standard);
            puzzTypeBox.setSize(85, 20);
            puzzTypeBox.addActionListener(filter);
            puzzTypeBox.setVisible(true);
            puzzTypeBox.setEnabled(true);
//            this.add(puzzTypeBox);
            databasePanel.add(puzzTypeBox);


            String lbltxt2 =  "Max Level";
            dbDefaultLabel2 = new JLabel();
			dbDefaultLabel2.setLocation(30, 60);
			dbDefaultLabel2.setSize(80, 20);
            dbDefaultLabel2.setFont(standard);
			dbDefaultLabel2.setText(lbltxt2);
//			this.add(dbDefaultLabel2);
                        databasePanel.add(dbDefaultLabel2);

            String[] MaxDiffs = database.getMaxDiffs();
            maxDiffBox = new JComboBox(MaxDiffs);
            maxDiffBox.setSelectedIndex(0);
            maxDiffBox.setLocation(135, 60);
            maxDiffBox.setFont(standard);
            maxDiffBox.setSize(85, 20);
            maxDiffBox.addActionListener(filter);
//            this.add(maxDiffBox);
            databasePanel.add(maxDiffBox);


            String lbltxt1 =  "Level";
            dbDefaultLabel = new JLabel();
			dbDefaultLabel.setLocation(30, 90);
			dbDefaultLabel.setSize(80, 20);
            dbDefaultLabel.setFont(standard);
			dbDefaultLabel.setText(lbltxt1);
//			this.add(dbDefaultLabel);
                        databasePanel.add(dbDefaultLabel);

            String[] Diffs = {"ALL","1","2","3","4","5","6"};
            diffBox = new JComboBox(Diffs);
            diffBox.setSelectedIndex(0);
            diffBox.setLocation(135, 90);
            diffBox.setSize(85,20);
            diffBox.addActionListener(filter);
//            this.add(diffBox);
            databasePanel.add(diffBox);

            String lbltxt9 =  "No. of Solutions";
            dbDefaultLabel9 = new JLabel();
			dbDefaultLabel9.setLocation(30, 120);
			dbDefaultLabel9.setSize(100, 20);
            dbDefaultLabel9.setFont(standard);
			dbDefaultLabel9.setText(lbltxt9);
//			this.add(dbDefaultLabel9);
                        databasePanel.add(dbDefaultLabel9);

            String[] NumSol = {"ALL", "1", ">1"};
            numSolBox = new JComboBox(NumSol);
            numSolBox.setSelectedIndex(0);
            numSolBox.setLocation(135, 120);
            numSolBox.setFont(standard);
            numSolBox.setSize(85, 20);
            numSolBox.addActionListener(filter);
//            this.add(numSolBox);
            databasePanel.add(numSolBox);

            String lbltxt13 = "Consistency";
			dbDefaultLabel13 = new JLabel();
			dbDefaultLabel13.setLocation(30, 150);
			dbDefaultLabel13.setSize(95, 20);
            dbDefaultLabel13.setFont(standard);
			dbDefaultLabel13.setText(lbltxt13);
//			this.add(dbDefaultLabel13);
                        databasePanel.add(dbDefaultLabel13);

            String[] ConsistencyBox = {"ALL", "AC", "SAC", "GAC", "SAC + GAC", "SGAC", "Unsolved"};
            consisBox = new JComboBox(ConsistencyBox);
            consisBox.setSelectedIndex(0);
            consisBox.setLocation(135, 150);
            consisBox.setFont(standard);
            consisBox.setSize(85, 20);
            consisBox.addActionListener(filter);
//            this.add(consisBox);
            databasePanel.add(consisBox);

            queryResults = new JList();
            queryResults.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            queryResults.setCellRenderer(new MyCellRenderer());
//            this.add(queryResults);
            databasePanel.add(queryResults);

            scroller = new JScrollPane(queryResults , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS ,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            scroller.setLocation(5, 260);
            scroller.setSize(460,230);
//            this.add(scroller);
            databasePanel.add(scroller);

			instancePanel.setVisible(false);
//            this.validate();
//            this.repaint();
			databasePanel.setVisible(true);
            databasePanel.validate();
            databasePanel.repaint();
            selectPanel.add(databasePanel);
            selectPanel.validate();
            selectPanel.repaint();

	}

	public void fromInstance() throws Exception
    {

            instancePanel = new javax.swing.JPanel();
            instancePanel.setSize(480,418);
            instancePanel.setLocation(15,50);
            instancePanel.setLayout(null);
            Font standard = new Font("Times Unicode", Font.PLAIN, 12);

            goButton2 = new JButton("Go!");
            goButton2.setActionCommand("GOGO");
            goButton2.setFont(standard);
            goButton2.addActionListener(this);
            goButton2.setLocation(230,20);
            goButton2.setSize(75, 20);

            instancePanel.add(goButton2);
            
            selectButton = new JButton("Select Puzzle");
	    selectButton.setActionCommand("GOGOGO");
            selectButton.setFont(standard);
	    selectButton.addActionListener(this);
            selectButton.setLocation(5,80);
            selectButton.setSize(130, 20);
//			this.add(selectButton);
                        instancePanel.add(selectButton);

 
           // JComboBox combo1 = new javax.swing.JComboBox();
           listModel= new DefaultListModel();

           // ActionListener fileOpener = new fileLoadHandler(this);
          //  JMenu mainMenu = new JMenu();
	   // createLoadMenu(LIBRARY_LOCATION + "libraryIndex.xml", mainMenu, fileOpener,listModel);
            selectPanel.remove(databasePanel);
           // instancePanel.add(combo1);
             String lbltxt3 =  "Type";
           dbDefaultLabel3 = new JLabel();
            dbDefaultLabel3.setLocation(10, 20);
            dbDefaultLabel3.setSize(40, 20);
            dbDefaultLabel3.setFont(standard);
            dbDefaultLabel3.setText(lbltxt3);

              instancePanel.add(dbDefaultLabel3);
            list1 = new JList(listModel);


            String[] puzzTypes = {"BigBookOfSudoku","DailyNebraskan","LATimes","MephamMichael","Sudocue","SudokuSolverByLogic","UsersInput","FromFiles"};
            puzzTypeBox = new JComboBox(puzzTypes);
            puzzTypeBox.setSelectedIndex(0);
            puzzTypeBox.setLocation(50, 20);
            puzzTypeBox.setFont(standard);
            puzzTypeBox.setSize(140, 20);
            puzzTypeBox.addActionListener(this);
            puzzTypeBox.setVisible(true);
            puzzTypeBox.setEnabled(true);
//            this.add(puzzTypeBox);
            instancePanel.add(puzzTypeBox);


            scroller2 = new JScrollPane(list1 , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS ,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            scroller2.setLocation(5, 130);
            scroller2.setSize(450,230);

            instancePanel.add(scroller2);


             databasePanel.setVisible(false);


            instancePanel.validate();
            instancePanel.repaint();
            instancePanel.setVisible(true);
            selectPanel.add(instancePanel);
            selectPanel.validate();
            selectPanel.repaint();
            


    }
	
    public void mouseClicked(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mousePressed(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseReleased(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseEntered(MouseEvent e) {
        System.out.println("Hello");
    }

    public void mouseExited(MouseEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

	public void valueChanged(ListSelectionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
	
                //source for cell code
              //http://www.tech-recipes.com/rx/1221/java-multi-column-jlist-swing/
    static class MyCellRenderer extends JPanel implements ListCellRenderer{
            JLabel column1, column2, column3,column4,column5,column6;

            MyCellRenderer() {
            GroupLayout layout = new GroupLayout(this);
            setLayout(layout);

            column1 = new JLabel();
            column2	= new JLabel();
            column3 = new JLabel();
            column4 = new JLabel();
            column5 = new JLabel();
            column6 = new JLabel();

            column1.setOpaque(true);
            column2.setOpaque(true);
            column3.setOpaque(true);
            column4.setOpaque(true);
            column5.setOpaque(true);
            column6.setOpaque(true);
            /*
            //add firstcolumn
            add(left);

            //add second column
            add(middle);

            //add third column
            add(right);
            */



            layout.setHorizontalGroup(
                    layout.createSequentialGroup()
                    .addComponent(column1, 210, 210, 210)
                    .addComponent(column2, 50, 50, 50)
                    .addComponent(column3, 50, 50, 50)
                    .addComponent(column4, 200, 200, 200)
                    .addComponent(column5, 50, 50, 50)
                    .addComponent(column6, 75, 75, 75));

            layout.setVerticalGroup(
                    layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE, false)
                        .addComponent(column1,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(column2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(column3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(column4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(column5, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(column6, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));


            }

            public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus){
            String col1data = ((String[])value)[0];
            String col2data = ((String[])value)[1];
            String col3data = ((String[])value)[2];
            String col4data = ((String[])value)[3];
            String col5data = ((String[])value)[4];
            String col6data = ((String[])value)[5];
            
            column1.setText(col1data);
            column2.setText(col2data);
            column3.setText(col3data);
            column4.setText(col4data);
            column5.setText(col5data);
            column6.setText(col6data);
            if(isSelected){
            column1.setBackground(list.getSelectionBackground());
            column1.setForeground(list.getSelectionForeground());
            column2.setBackground(list.getSelectionBackground());
            column2.setForeground(list.getSelectionForeground());
            column3.setBackground(list.getSelectionBackground());
            column3.setForeground(list.getSelectionForeground());
            column4.setBackground(list.getSelectionBackground());
            column4.setForeground(list.getSelectionForeground());
            column5.setBackground(list.getSelectionBackground());
            column5.setForeground(list.getSelectionForeground());
            column6.setBackground(list.getSelectionBackground());
            column6.setForeground(list.getSelectionForeground());
            }
            else{
            column1.setBackground(list.getBackground());
            column1.setForeground(list.getForeground());
            column2.setBackground(list.getBackground());
            column2.setForeground(list.getForeground());
            column3.setBackground(list.getBackground());
            column3.setForeground(list.getForeground());
            column4.setBackground(list.getBackground());
            column4.setForeground(list.getForeground());
            column5.setBackground(list.getBackground());
            column5.setForeground(list.getForeground());
            column6.setBackground(list.getBackground());
            column6.setForeground(list.getForeground());
            }
            setEnabled(list.isEnabled());
            setFont(list.getFont());
            return this;

            }
    }

    public void keyReleased(KeyEvent e){
        System.out.println("Hello");
        displayInfo(e,"Key Released: ");
    }

    public void keyPressed(KeyEvent e){
        System.out.println("Hello");
        displayInfo(e,"Key Pressed: ");
    }

    public void keyTyped(KeyEvent e){
        System.out.println("Hello");
        displayInfo(e,"Key Typed: ");
    }

    private void displayInfo(KeyEvent e, String keyStatus){

        //You should only rely on the key char if the event
        //is a key typed event.
        int id = e.getID();
        String keyString;
        if (id == KeyEvent.KEY_TYPED) {
            char c = e.getKeyChar();
            keyString = "key character = '" + c + "'";
        } else {
            int keyCode = e.getKeyCode();
            keyString = "key code = " + keyCode
                + " ("
                + KeyEvent.getKeyText(keyCode)
                + ")";
        }

        int modifiersEx = e.getModifiersEx();
        String modString = "extended modifiers = " + modifiersEx;
        String tmpString = KeyEvent.getModifiersExText(modifiersEx);
        if (tmpString.length() > 0) {
            modString += " (" + tmpString + ")";
        } else {
            modString += " (no extended modifiers)";
        }

        String actionString = "action key? ";
        if (e.isActionKey()) {
            actionString += "YES";
        } else {
            actionString += "NO";
        }

        String locationString = "key location: ";
        int location = e.getKeyLocation();
        if (location == KeyEvent.KEY_LOCATION_STANDARD) {
            locationString += "standard";
        } else if (location == KeyEvent.KEY_LOCATION_LEFT) {
            locationString += "left";
        } else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
            locationString += "right";
        } else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
            locationString += "numpad";
        } else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
            locationString += "unknown";
        }

    }
    
	public void loadNewProblem(String absoluteAddress)
    {
	myProblem = this.loadProblem(absoluteAddress);
	myProblem.setName(constructorPanel.getNameField());
        dbpuzzle = 0;

	//delete all of the old problem stuff.
	this.rootPane.getContentPane().removeAll();

	initialize();

	constructorPanel.setsuTypeList(myProblem.getSuType());
	constructorPanel.setSourceField(myProblem.getSourceValue());
	constructorPanel.setLowerField(Integer.toString(myProblem.getLowerDiffValue()));
	constructorPanel.setUpperField(Integer.toString(myProblem.getUpperDiffValue()));
	constructorPanel.setLevelField(Integer.toString(myProblem.getLevelDiffValue()));
	constructorPanel.setNameField(myProblem.toString());
	constructorPanel.setOriginalField(myProblem.getOrigNameValue());
	constructorPanel.setDescriptionField(myProblem.getDescValue());
	//		this.removeAll();
	//		this.repaint();
	//		initialize();
    }

       public void loadNewProblemWithResetAll(String absoluteAddress)
	{
		myProblem = this.LoadProblemNoPreassign();
		this.rootPane.getContentPane().remove(playingBoard);
		initialize_reset();

////		controlPanel.removeAll();
		playingBoard.setMouseAction("assign");

		constructorPanel.setsuTypeList("Base");
		constructorPanel.setSourceField("");
		constructorPanel.setLowerField("1");
		constructorPanel.setUpperField("5");
		constructorPanel.setLevelField("1");

		Calendar cal = Calendar.getInstance(TimeZone.getDefault());

                String DATE_FORMAT = "MM-dd-yyyy-hhmmss";
                java.text.SimpleDateFormat sdf =
                new java.text.SimpleDateFormat(DATE_FORMAT);

                constructorPanel.setNameField(sdf.format(cal.getTime()));
		constructorPanel.setOriginalField("");
		constructorPanel.setDescriptionField("Sudoku Instance");

		myProblem.setName(constructorPanel.getNameField());

	}

	/* private void optInstanceActionPerformed(java.awt.event.ActionEvent evt) {

      sudokuInterface.this.fromInstance();

       tbPuzzles.setEnabled(false);

    }*/
	
    public void actionPerformed(ActionEvent e) 
    {
		
	if(e.getActionCommand().equals("undo"))
	    {
		//tell the board to preform an undo.
		playingBoard.preform_undo();
	    }
	else if(e.getActionCommand().equals("redo"))
	    {
		//tell the board to preform an undo.
		playingBoard.preform_redo();
	    }
	else if(e.getActionCommand().equals("propBinaryMAC"))
	    {
        if(thread != null && thread.isAlive()) {
            try {
                thread.interrupt();
                thread.join();
            } catch (InterruptedException ex) {
                // Bad things happen if we get here...
            }
        }
		thread = playingBoard.preformArcConsistency();
        thread.start();
	    }
	else if(e.getActionCommand().equals("propNonBinaryGAC"))
	    {
        if(thread != null && thread.isAlive()) {
            try {
                thread.interrupt();
                thread.join();
            } catch (InterruptedException ex) {
                // Bad things happen if we get here...
            }
        }
		thread = playingBoard.preformNonBinaryMAC();
        thread.start();
	    }
	else if(e.getActionCommand().equals("propShavingMAC"))
	    {
        if(thread != null && thread.isAlive()) {
            try {
                thread.interrupt();
                thread.join();
            } catch (InterruptedException ex) {
                // Bad things happen if we get here...
            }
        }
		thread = playingBoard.preformShavingMAC();
        thread.start();
	    }
	else if(e.getActionCommand().equals("propShavingGAC"))
	    {
        if(thread != null && thread.isAlive()) {
            try {
                thread.interrupt();
                thread.join();
            } catch (InterruptedException ex) {
                // Bad things happen if we get here...
            }
        }
		thread = playingBoard.preformShavingGAC();
        thread.start();
    }
	else if(e.getActionCommand().equals("assignSingletons"))
	    {
		playingBoard.preformAutoAssign();
	    }
	else if(e.getActionCommand().equals("resetProblem"))
	{
        String format = testXMLFormat(problemLocation);
        if(format==null)
	    {
            if(problemLocation.substring(56).startsWith("V"))
            {
                loadNewProblemFromFileTypeTwo(FileLineNumber);
            }
            else
                loadNewProblemFromFile(FileLineNumber);
	    }
        else if (dbpuzzle > 0)
        {
                dbmysql database;
                try {
                    database = new dbmysql();
                    database.upload(dbpuzzle);
                    myProblem = loadProblemFromArray(database.getArray());
                    myProblem.setName(database.getName());
                    this.rootPane.getContentPane().removeAll();
                    initialize();
                } catch (Exception ex) {
                    Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
                }

        }
         else{
                    loadNewProblem(problemLocation);
                }
        //Amanda
        have_used_algs = 0;
        timer.start();
        int selIndex = jTabbedPane1.getTabCount()-3;
                    jTabbedPane1.setSelectedIndex(selIndex);


	}
	else if(e.getActionCommand().equals("findSolutions"))
	    {
		numSolutions.setText("...");
		//make a thread to calculate the number of solutions
			
		solverThread mySolverThread = new solverThread(myProblem.copy(), numSolutions);
		thread = new Thread(mySolverThread);
		thread.start();
		//mySolverThread.run();
	    }
    else if(e.getActionCommand().equals("stop!"))
	    {
                if(thread != null){
                    thread.interrupt();
                }

                if(t != null){
                    t.interrupt();
                }
	    }
	else if(e.getActionCommand().equals("printInterface"))
	    {
		PrinterJob newJob = PrinterJob.getPrinterJob();
		newJob.setPrintable(this);
		if(newJob.printDialog())
		    {
			try
			    {
				newJob.print();
			    }
			catch(Exception excpt)
			    {
			    }
		    }
	    }
//	Angelo's clauses
	else if(e.getActionCommand().equals("Choose"))
		{
			int num = Integer.parseInt(inputNumField.getText());
			FileLineNumber = Integer.parseInt(inputNumField.getText());
			loadNewProblemFromFile(num);			
		} 
		else if (e.getActionCommand().equals("Open"))
		{
			int num = Integer.parseInt(inputNumField.getText());
            FileLineNumber = Integer.parseInt(inputNumField.getText());
		    if (num <= 0 || num > 100) {
		    	num = 1;
		    }
			NumberFormat nf=NumberFormat.getInstance(); // Get Instance of NumberFormat
			nf.setMinimumIntegerDigits(3);  // The minimum Digits required is 5
			nf.setMaximumIntegerDigits(3); // The maximum Digits required is 5
			String sb=(nf.format((long)num));			
			this.batchFile = this.batchFile + sb;
			loadNewProblemFromFileTypeTwo(num);
		}
    else if(e.getActionCommand().equals("fromdb"))
        {

            int selected = queryResults.getSelectedIndex();
            dbpuzzle = Integer.parseInt(results[selected][6]);

            try{
                dbmysql database = new dbmysql();
                database.upload(dbpuzzle);
                myProblem = loadProblemFromArray(database.getArray());
                myProblem.setName(database.getName());
                this.rootPane.getContentPane().removeAll();
//                this.rootPane.getJMenuBar().setVisible(true);
                initialize();
                 have_used_algs = 0;
                startTimer();


            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
		else if(e.getActionCommand().equals("GOGO"))
        {
            listModel.clear();
             puzzleType=puzzTypeBox.getSelectedItem().toString();
                createLoadMenu(LIBRARY_LOCATION + "libraryIndex.xml", useless, fileOpener, listModel, puzzleType);
          
        }
       else if(e.getActionCommand().equals("playnew")){
            if(timer.isRunning()){
                stopTimer();
            }

             int selIndex = jTabbedPane1.getTabCount()-4;
                    jTabbedPane1.setSelectedIndex(selIndex);

        }


        else if(e.getActionCommand().equals("highscores")){

            try{
                boolean pause = false;

                if(timer.isRunning()){
                    timer.stop();
                    pause = true;
                }

            dbmysql mydb = new dbmysql();
            mydb.showAllHighScores();

                if(pause = true){
                    timer.start();
                    pause = false;
                }

            }
            catch(Exception f){
                System.out.println(f);
            }
        }
        else if(e.getActionCommand().equals("GOGOGO"))
        {
            int selected=list1.getSelectedIndex();
            String add = (String) list1.getModel().getElementAt(selected);
            String actionCode = LIBRARY_LOCATION+add;

		if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/GRoyle17min.txt")) {
			displayLineOfFile("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/GRoyle17min.txt");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/Stertenbrink+Meyrignac-Top100.txt")){
			displayLineOfFile("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/Stertenbrink+Meyrignac-Top100.txt");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_3")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_3.");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_4")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_4.");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_5")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_5.");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_6")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_6.");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_7")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_7.");
		} else if (actionCode.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen_8")){
			displayFileTypeTwo("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_8.");
		} else {
			loadNewProblem(actionCode);
		}

            //Start timer
             have_used_algs = 0;
                startTimer();


        }
		
        else if(e.getActionCommand().equals("query"))
        {
            orderBy = "PuzzleName";
            puzzleType = puzzTypeBox.getSelectedItem().toString();
            maxLevel = maxDiffBox.getSelectedItem().toString();
            level = diffBox.getSelectedItem().toString();
            numSol = numSolBox.getSelectedIndex();
            consistency = consisBox.getSelectedItem().toString();
            queried = true;
            try {
                dbmysql database = new dbmysql();
                results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);


                    queryResults.setListData(results);
            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }


        }
            else if(e.getActionCommand().equals("orderby1"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("PuzzleName"))
                    orderBy = "PuzzleName DESC";
                else
                    orderBy = "PuzzleName";

                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }

        else if(e.getActionCommand().equals("orderby2"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("MaxDiffLvl"))
                    orderBy = "MaxDiffLvl DESC";
                else
                    orderBy = "MaxDiffLvl";
                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }
        else if(e.getActionCommand().equals("orderby3"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("DiffLvl"))
                    orderBy = "DiffLvl DESC";
                else
                    orderBy = "DiffLvl";
                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }
        else if(e.getActionCommand().equals("orderby4"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("Source"))
                    orderBy = "Source DESC";
                else
                    orderBy = "Source";
                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }
        else if(e.getActionCommand().equals("orderby5"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("Solutions"))
                    orderBy = "Solutions DESC";
                else
                    orderBy = "Solutions";
                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }
        else if(e.getActionCommand().equals("orderby6"))
        {
            if(queried) {
                if(orderBy.equalsIgnoreCase("Consistency"))
                    orderBy = "Consistency DESC";
                else
                    orderBy = "Consistency";
                try {
                    dbmysql database = new dbmysql();
                    results = database.populateList(puzzleType, maxLevel, level, numSol,
                            consistency, orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {

                }
            }
        }



        else if(e.getActionCommand().equals("canceldb"))
        {
            this.rootPane.getContentPane().removeAll();
//            this.rootPane.getJMenuBar().setVisible(true);
            initialize();

        }
    }

    
    public void itemStateChanged(ItemEvent e)
    {
	if(((JCheckBox)e.getItem()).getActionCommand() == "showDomains")
	    {
		showDomains = (e.getStateChange() == ItemEvent.SELECTED);
		playingBoard.repaint();
	    }
    }
	
    //	public void runDomainColoring()
    //	{
    //		playingBoard.runDomainColoring();	
    //	}

	
    //this method accepts a line number where the ArcConsistencyAlgorithm should be implemented
    //it digs up all the variables affected and passes them to the board where they
    //are handled.
    //note the line is 1..maxlines it does not start at 0;
    public void binaryLineArcConsistency(int line)
    {
	List variablesAffected = new LinkedList();
	for(int colIndex =1; colIndex <= myProblem.totalColumns; colIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(line+","+colIndex));
	    }
	playingBoard.preformBinaryRestrictedArcConsistency(variablesAffected);
    }
	
    public void alldifLineArcConsistency(int line)
    {
	String location = "L" + line;
	playingBoard.preformNonBinaryRestrictedArcConsistency(location);
    }
	
    public void alldifColumnArcConsistency(int column)
    {
	String location = "C" + column;
	playingBoard.preformNonBinaryRestrictedArcConsistency(location);
    }
	
    public void alldifUnitArcConsistency(int line, int column)
    {
	String location = "U" + line + "," + column;
	playingBoard.preformNonBinaryRestrictedArcConsistency(location);
    }
	
    //this method accepts a column number where the ArcConsistencyAlgorithm should be implemented
    //it digs up all the variables affected and passes them to the board where they
    //are handled.
    //note the line is 1..maxcols it does not start at 0;
    public void binaryColArcConsistency(int col)
    {
	List variablesAffected = new LinkedList();
	for(int lineIndex =1; lineIndex <= myProblem.totalLines; lineIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(lineIndex+","+col));
	    }
	playingBoard.preformBinaryRestrictedArcConsistency(variablesAffected);
    }
	
    //this method accepts a column and line number of a unit where the 
    //ArcConsistencyAlgorithm should be implemented
    //it digs up all the variables affected and passes them to the board where they
    //are handled.
    //note the line is 1..unitsWide it does not start at 0;
    //note the column is 1..unitsHigh it does not start at 0;
    public void binaryUnitArcConsistency(int unitLine, int unitCol)
    {
	List variablesAffected = new LinkedList();
	int colsPerUnit = myProblem.columnsPerUnit;
	int linesPerUnit = myProblem.linesPerUnit;
		
	for(int lineIndex =1; lineIndex <= linesPerUnit; lineIndex++)
	    {
		for(int colIndex=1; colIndex <= colsPerUnit; colIndex++)
		    {
			variablesAffected.add(
					      myProblem.getVariable((((unitLine-1)*colsPerUnit)+lineIndex)+","+(((unitCol-1)*linesPerUnit)+colIndex)));				
		    }
	    }
	playingBoard.preformBinaryRestrictedArcConsistency(variablesAffected);
    }
	

        public class ShowPopupActionListener implements ActionListener {
        private Component component;

        ShowPopupActionListener(Component component) {
          this.component = component;
        }

        

       public synchronized void actionPerformed(ActionEvent actionEvent) {
          popupPanel = new JPanel();
          popupPanel.setSize(500,500);
            try {
                dbmysql database = new dbmysql();
                puzzlesInDB = database.numOfPuzzInDB();
            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

          if(puzzlesInDB != 0)
          {
              puzzleNumbers = new String[puzzlesInDB+2];
              puzzleNumbers[0] = "PUZZLE NUMBER";
              puzzleNumbers[1] = "-----";
              while(puzzlesInDB != 0)
              {
                  puzzleNumbers[puzzlesInDB+1] = puzzlesInDB + "";
                  puzzlesInDB--;
              }
          }
          else
          {
            //puzzleNumbers = {"Database not found.", "Sorry."};
          }

          popupList = new JComboBox(puzzleNumbers);
          popupList.setSelectedIndex(0);
          popupPanel.add(popupList);

          popupButton = new JButton("Go");
          popupButton.addActionListener((ActionListener)maincomponent);
          popupButton.setLocation(100,130);
          popupButton.setSize(40,40);
          popupButton.setActionCommand("fromdb");
          popupPanel.add(popupButton);

          cancelButton = new JButton("Cancel");
          popupPanel.add(cancelButton);



          PopupFactory factory = PopupFactory.getSharedInstance();
          final Popup popup = factory.getPopup(component, popupPanel, 200, 200);
          popup.show();

          ActionListener hider = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              popup.hide();
            }
          };

          cancelButton.addActionListener(hider);
          popupButton.addActionListener(hider);
        }
  }



    public void depressUnit(int unitLine, int unitCol)
    {
	List variablesAffected = new LinkedList();
	int colsPerUnit = myProblem.columnsPerUnit;
	int linesPerUnit = myProblem.linesPerUnit;
		
	for(int lineIndex =1; lineIndex <= linesPerUnit; lineIndex++)
	    {
		for(int colIndex=1; colIndex <= colsPerUnit; colIndex++)
		    {
			variablesAffected.add(
					      myProblem.getVariable((((unitLine-1)*colsPerUnit)+lineIndex)+","+(((unitCol-1)*linesPerUnit)+colIndex)));				
		    }
	    }
	playingBoard.depress(variablesAffected);
    }
	
    public void undepressUnit(int unitLine, int unitCol)
    {
	List variablesAffected = new LinkedList();
	int colsPerUnit = myProblem.columnsPerUnit;
	int linesPerUnit = myProblem.linesPerUnit;
		
	for(int lineIndex =1; lineIndex <= linesPerUnit; lineIndex++)
	    {
		for(int colIndex=1; colIndex <= colsPerUnit; colIndex++)
		    {
			variablesAffected.add(
					      myProblem.getVariable((((unitLine-1)*colsPerUnit)+lineIndex)+","+(((unitCol-1)*linesPerUnit)+colIndex)));				
		    }
	    }
	playingBoard.undepress(variablesAffected);
    }
	
    public void depressLine(int line)
    {
	List variablesAffected = new LinkedList();
	for(int colIndex =1; colIndex <= myProblem.totalColumns; colIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(line+","+colIndex));
	    }
	playingBoard.depress(variablesAffected);
    }
	
    public void undepressLine(int line)
    {
	List variablesAffected = new LinkedList();
	for(int colIndex =1; colIndex <= myProblem.totalColumns; colIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(line+","+colIndex));
	    }
	playingBoard.undepress(variablesAffected);
    }
	
    public void undepressColumn(int column)
    {
	List variablesAffected = new LinkedList();
	for(int rowIndex =1; rowIndex <= myProblem.totalColumns; rowIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(rowIndex+","+column));
	    }
	playingBoard.undepress(variablesAffected);
    }
	
    public void depressColumn(int column)
    {
	List variablesAffected = new LinkedList();
	for(int rowIndex =1; rowIndex <= myProblem.totalColumns; rowIndex++)
	    {
		variablesAffected.add(myProblem.getVariable(rowIndex+","+column));
	    }
	playingBoard.depress(variablesAffected);
    }
	
    public void doAutoPropogation()
    {

	if(autoPropogationType.equals("propBackChecking"))
	    {
		//check to see that all assigned variables are consistent
		// this will happen the first time you click this button
		playingBoard.preformBackChecking();
		return;
	    }
	else if(autoPropogationType.equals("propNone"))
	    {
		//do nothing
		return;
	    }
	else if(autoPropogationType.equals("propNonBinaryFC"))
	    {
		//TODO:This
	    }
	else if(autoPropogationType.equals("propBinaryFC"))
	    {
		playingBoard.preformBinaryForwardCheckAll();
	    }
	else if(autoPropogationType.equals("propBinaryMAC"))
	    {
		playingBoard.preformArcConsistency();
	    }
	else if(autoPropogationType.equals("propNonBinaryMAC"))
	    {
		//TODO:This
	    }
	else if(autoPropogationType.equals("prop2RC"))
	    {
		//TODO:This
	    }
    }
	
    public void doAutoPropogation(problemVariable originalVariable)
    {
	if(autoPropogationType.equals("propNone"))
	    {
		//do nothing
		return;
	    }
	else if(autoPropogationType.equals("propBinaryFC"))
	    {
	
		playingBoard.preformBinaryForwardCheckOnVariable(originalVariable);
		return;

	    }
	else if(autoPropogationType.equals("propBinaryMAC"))
	    {
		playingBoard.preformArcConsistency();
		return;
	    }
	else if(autoPropogationType.equals("propBackChecking"))
	    {
		playingBoard.preformBackCheckingOnVariable(originalVariable);
		return;
	    }
    }
		
    public void setAutoPropogationType(String new_type)
    {
	autoPropogationType = new_type;
	if(autoPropogationType.equals("propBinaryFC"))
	    {
		playingBoard.preformBinaryForwardCheckAll();
	    }
	else if(autoPropogationType.equals("propBinaryMAC"))
	    {
		//run MAC the first time it is clicked.
		playingBoard.preformArcConsistency();
	    }
	else if(autoPropogationType.equals("propBackChecking"))
	    {
		playingBoard.preformBackChecking();
	    }
    }
	
    public boolean showDomains()
    {
	if(showDomains)
	    {
		return true;
	    }
	else
	    {
		return false;
	    }
    }
	
    public void updateValuesRemoved(int numRemoved)
    {
	numberEliminatedLabel.setText(""+numRemoved);
//        sudokuInterface.numElim = numRemoved;
    }
    public void updateValuesRemoved(String numRemoved)
    {
	numberEliminatedLabel.setText(numRemoved);
//        sudokuInterface.numElim = Integer.parseInt(numRemoved);
    }
	
    public int print(Graphics g, PageFormat pf, int pi) throws PrinterException
    {
	//TODO:Make this work better
	//we want to resize and give one inch margins, we are assuming nonlandscape printing
	if(pi >= 1)
	    {
		return Printable.NO_SUCH_PAGE;
	    }

	this.print(g);
	return Printable.PAGE_EXISTS;
    }
	
    public void updateHintDisplay(hints currentHints)
    {
	return;
    }
	
    public void setEnableHints(boolean value)
    {
	findHintButton.setEnabled(value);
    }

    public void resetHintBoard()
    {
	for(int i =0; i<hintPanel.getComponentCount(); i++)
	    {
		Component currCompenent = hintPanel.getComponent(i);
		if(currCompenent.getName().equals("hintFind"))
		    {
			currCompenent.setEnabled(true);
		    }
		else if(currCompenent.getName().equals("hintDisplay"))
		    {
			((JButton)currCompenent).setText("Display");
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintNext"))
		    {
			currCompenent.setEnabled(false);
		    }
        else if(currCompenent.getName().equals("hintPrev"))
		    {
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintLevelLabel"))
		    {
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintLevelDisplayLabel"))
		    {
			currCompenent.setEnabled(false);
			((JLabel)currCompenent).setText("");
		    }
		else if(currCompenent.getName().equals("hintLevelNext"))
		    {
			currCompenent.setEnabled(false);
		    }
        else if(currCompenent.getName().equals("hintLevelPrev"))
		    {
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintTypeLabel"))
		    {
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintTypeSingleton"))
		    {
			((JRadioButton)currCompenent).setSelected(false);
			currCompenent.setEnabled(false);
		    }
		else if(currCompenent.getName().equals("hintTypeVital"))
		    {
			((JRadioButton)currCompenent).setSelected(false);
			currCompenent.setEnabled(false);
		    }
	    }
    }
	
	
    private void createLoadMenu(String indexLocation, JMenu menu, ActionListener myListener,DefaultListModel list1,String selected)
    {
	DocumentBuilderFactory factoryBuilder;
	DocumentBuilder builder;
	Document doc;
	Element docElement;
	//NodeList currentNodeList;

	try
	    {
		factoryBuilder  = DocumentBuilderFactory.newInstance( );
		builder = factoryBuilder.newDocumentBuilder();
		doc = builder.parse( indexLocation );
		docElement = doc.getDocumentElement();
			
		//build the menu depth first recursively
		createLoadMenu(docElement,menu, myListener,list1,selected);
		//			NodeList children = docElement.getChildNodes();
		//			
		//			for(int i =0; i < children.getLength(); i++)
		//			{
		//				if(children.item(i).getNodeType() == 1)
		//				{
		//					if((children.item(i).getNodeName()).equals("directory"))
		//					{
		//						JMenu tempMenu = new JMenu(
		//								children.item(i).getAttributes().getNamedItem("name").getNodeValue());
		//						mainMenu.add(tempMenu);
		//					}
		//					else if((children.item(i).getNodeName()).equals("file"))
		//					{
		//						JMenuItem tempItem = new JMenuItem(
		//								children.item(i).getAttributes().getNamedItem("name").getNodeValue());
		//						mainMenu.add(tempItem);							
		//					}
		//				}
		//			}

	    }
	catch (IOException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);
	    }
	catch (ParserConfigurationException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);
	    }
	catch (SAXException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);
	    }
	return;
    }
	
    //creates a menu depth first recursively
    private void createLoadMenu(Node currentNode, JMenu parentMenu, ActionListener myListener,DefaultListModel list1,String selected)
    {
		
	//make sure it is a node we care about
	if(currentNode.getNodeType() == 1)
	    {
		if((currentNode.getNodeName()).equals("directory"))
		    {
			JMenu tempMenu = new JMenu(
						   currentNode.getAttributes().getNamedItem("name").getNodeValue());
			//parentMenu.add(tempMenu);
			NodeList files = currentNode.getChildNodes();                        
			for(int fileIndex = 0; fileIndex < files.getLength(); fileIndex++)
			    {
				createLoadMenu(files.item(fileIndex), parentMenu, myListener,list1,selected);
			    }
		    }
		else if((currentNode.getNodeName()).equals("file"))
		    {
                        String[] splitter = null;
			//add it to the menu
			JMenuItem tempItem = new JMenuItem(
							   currentNode.getAttributes().getNamedItem("name").getNodeValue());

			//get the absolute location of the file
			String address = currentNode.getAttributes().getNamedItem("name").getNodeValue();
			Node parentNode = currentNode.getParentNode();
			while(! (parentNode.getAttributes().getNamedItem("name").getNodeValue()
				 .equals("SudokuLibrary")))
			    {
				//TODO: apparently using + with strings is slow
				address = parentNode.getAttributes().getNamedItem("name").getNodeValue() + "/" + address;
				parentNode = parentNode.getParentNode();
			    }
			tempItem.setActionCommand(LIBRARY_LOCATION + address);
			tempItem.addActionListener(myListener);    
                       splitter=address.split("/");

                        //list1.addElement(LIBRARY_LOCATION + address);
                       for(int i=0;i<splitter.length;i++)
                        {
                           if(splitter[i].equals(selected))
                           {
                               list1.addElement(address);
                           }
                        }                    
		    }
	    }
    }

    //	//creates a menu depth first recursively
    //	private void createLoadMenu(File currentLocation, JMenu parentMenu)
    //	{
    //		String files[];
    //		int size;
    //		
    //		if(currentLocation.isDirectory())
    //		{
    //			//add it to the menu
    //			JMenu tempMenu = new JMenu(currentLocation.getName());
    //			parentMenu.add(tempMenu);
    //			
    //			files = currentLocation.list();				
    //			size = files.length;
    //			for(int fileIndex = 0; fileIndex < size; fileIndex++)
    //			{
    //				//create a new file object
    //				File tempFile = new File(currentLocation, files[fileIndex]);
    //				createLoadMenu(tempFile, tempMenu);
    //			}
    //		}
    //		else if(currentLocation.isFile())
    //		{
    //			//add it to the menu
    //			JMenuItem tempItem = new JMenuItem(currentLocation.getName());
    //			parentMenu.add(tempItem);
    //		}
    //
    //	}


    private constraintProblem loadProblem()
    {
	parserXML myparser = new parserXML();
	parserXML3 myparser3 = new parserXML3();

	//myparser.parseXML("puzzles/BBS2-136.sudoku.xml");
	//System.err.println(this.getCodeBase());
	//myparser.parseXML(this.getCodeBase() + "puzzles/BBS2-136.sudoku.xml");
	//String format = testF.testXMLFormat(this.getCodeBase() + "puzzles/base-0227-1703.sudoku.xml");
    problemLocation = this.getCodeBase() + "puzzles/empty.sudoku.xml";
	String format = testXMLFormat(problemLocation);
	if (format.equals("Sudoku 3.0")) {
	    myparser3.parseXML3(problemLocation);
	    System.out.println("Load 3.0 File");			
	    return myparser3.getProblem();
	} else if (format.equals("Sudokuv2.0")) {
	    myparser.parseXML(problemLocation);
	    return myparser.getProblem();
	} else if (format.equals("Sudokuv1.0")) {
	    myparser.parseXML(problemLocation);
	    return myparser.getProblem();
	}
		
	//myparser.parseXML(this.getCodeBase() + "puzzles/BBS2-26.sudoku.xml");
		

	//System.out.print("Globals: " + Globals.allProblems.get(0).toString()+ "\n");
		
	//forwardCheckingSearch myForward = new forwardCheckingSearch((constraintProblem)Globals.allProblems.get(0));
	//myForward.solve();
	//myForward.printSolution();
	return null;
		
    }
	
    private constraintProblem loadProblem(String absoluteAddress)
    {
	parserXML myparser = new parserXML();
	parserXML3 myparser3 = new parserXML3();
	problemLocation = absoluteAddress;

	String format = testXMLFormat(problemLocation);
	if (format.equals("Sudoku 3.0")) {
	    myparser3.parseXML3(problemLocation);			
	    System.out.println("Load 3.0 File");			
	    return myparser3.getProblem();
	} else if (format.equals("Sudokuv2.0")) {
	    myparser.parseXML(problemLocation);
	    return myparser.getProblem();
	} else if (format.equals("Sudokuv1.0")) {
	    myparser.parseXML(problemLocation);
	    return myparser.getProblem();
	}

    
	return null;
		
    }

 private void startTimer(){

                
                  h = 0;
                    m = 0;
                    s = 0;


                     timer.start();

                    int selIndex = jTabbedPane1.getTabCount()-3;
                    jTabbedPane1.setSelectedIndex(selIndex);
    }


    private class hintButtonHandler implements MouseListener, ActionListener
    {
	hints boardHints;
		
	public hintButtonHandler()
	{
	}
		
	public void updateDisplay()
	{
	    for(int i =0; i<hintPanel.getComponentCount(); i++)
		{
		    Component currCompenent = hintPanel.getComponent(i);
		    if(currCompenent.getName().equals("hintFind"))
			{
			    currCompenent.setEnabled(false);
			}
		    else if(currCompenent.getName().equals("hintNumberLabel"))
			{
			    ((JLabel)currCompenent).setText("Hint "+(boardHints.getCurrentHintIndex()+1)+ " of " +(boardHints.getHintVariablesSize()));
			    currCompenent.setEnabled(true);
			}
		    else if(currCompenent.getName().equals("hintDisplay"))
			{
			    if(boardHints.getHintLevel() !=null)
				{
				    currCompenent.setEnabled(true);
				    if(boardHints.getErrorConstraint()!=null && boardHints.getHintType().equals("Error"))
					{
					    ((JButton)currCompenent).setText("Error");
					}
				    else if(boardHints.hasHint())
					{
					    ((JButton)currCompenent).setText((boardHints.getCurrentHintIndex()+1)+" of " + (boardHints.getHintVariablesSize()));
					}
				}
			    else
				{
				    ((JButton)currCompenent).setText("None");
				    currCompenent.setEnabled(false);
				}
			}
		    else if(currCompenent.getName().equals("hintNext"))
			{
			    if(boardHints.getHintLevel() !=null && boardHints.getHintType() != null
			       && !boardHints.getHintType().equals("Error"))
				{
				    currCompenent.setEnabled(true);	
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
            else if(currCompenent.getName().equals("hintPrev"))
			{
			    if(boardHints.getHintLevel() !=null && boardHints.getHintType() != null
			       && !boardHints.getHintType().equals("Error"))
				{
				    currCompenent.setEnabled(true);
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
		    else if(currCompenent.getName().equals("hintLevelNext"))
			{
			    if(boardHints.getHintLevel() !=null
			       && !boardHints.foundError())
				       //&& !boardHints.getHintLevel().equals("SGAC")
				{
				    currCompenent.setEnabled(true);	
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
            else if(currCompenent.getName().equals("hintLevelPrev"))
			{
			    if(boardHints.getHintLevel() !=null
			       && !boardHints.foundError())
				       //&& !boardHints.getHintLevel().equals("SGAC")
				{
				    currCompenent.setEnabled(true);
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
		    else if(currCompenent.getName().equals("hintLevelLabel"))
			{
			    currCompenent.setEnabled(true);
			}
		    else if(currCompenent.getName().equals("hintLevelDisplayLabel"))
			{
			    ((JLabel)currCompenent).setText(boardHints.getHintLevel());
			    currCompenent.setEnabled(true);
			}
		    else if(currCompenent.getName().equals("hintTypeSingleton"))
			{
			    if(boardHints.getHintLevel() !=null &&
			       boardHints.getHintType() !=null &&
			       !boardHints.getHintType().equals("Error")
			       && !boardHints.foundError())
				{
				    currCompenent.setEnabled(true);
				    if(boardHints.getHintType().equals("Singleton"))
					{
					    ((JRadioButton)currCompenent).setSelected(true);
					}
				    else
					{
					    ((JRadioButton)currCompenent).setSelected(false);
					}
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
		    else if(currCompenent.getName().equals("hintTypeVital"))
			{
			    if(boardHints.getHintLevel() !=null &&
			       boardHints.getHintType() !=null &&
			       !boardHints.getHintType().equals("Error")
			       && !boardHints.foundError())
				{
				    currCompenent.setEnabled(true);
				    if(boardHints.getHintType().equals("Vital"))
					{
					    ((JRadioButton)currCompenent).setSelected(true);
					}
				    else
					{
					    ((JRadioButton)currCompenent).setSelected(false);
					}
				}
			    else
				{
				    currCompenent.setEnabled(false);
				}
			}
		    else if(currCompenent.getName().equals("hintTypeLabel"))
			{
			    currCompenent.setEnabled(true);
			}
		    else if(currCompenent.getName().equals("hintTypeDisplayLabel"))
			{
			    ((JLabel)currCompenent).setText(boardHints.getHintType());
			    currCompenent.setEnabled(true);
			}
		}
	}
		
	public void actionPerformed(ActionEvent e) {
			
	    String actionCode = e.getActionCommand();
	    if(actionCode.equals("hintFind"))
		{
            boardHints = new hints(myProblem, myProblem.copy());
            boardHints.calculateHint();
                

		    updateDisplay();
			
		}
	    else if(actionCode.equals("hintNext"))
		{
		    boardHints.incrementHintIndex();
		    updateDisplay();
		}
        else if(actionCode.equals("hintPrev"))
		{
		    boardHints.decrementHintIndex();
		    updateDisplay();
		}
	    else if(actionCode.equals("hintLevelNext"))
		{
                try {
                    boardHints.incrementLevel();
                } catch (InterruptedException ex) {
                    Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
                }
		    updateDisplay();
		}
        else if(actionCode.equals("hintLevelPrev"))
		{
                try {
                    boardHints.decrementLevel();
                } catch (InterruptedException ex) {
                    Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
                }
		    updateDisplay();
		}
	    else if(actionCode.equals("hintTypeSingleton"))
		{
		    if(!boardHints.getHintType().equals("Singleton"))
			{
			    boardHints.switchType();
			    updateDisplay();
			}
		}
	    else if(actionCode.equals("hintTypeVital"))
		{
		    if(!boardHints.getHintType().equals("Vital"))
			{
			    boardHints.switchType();
			    updateDisplay();
			}
		}
	}
	
	public void mousePressed(MouseEvent e)
	{
	    playingBoard.displayHint(boardHints);
	}
	public void mouseReleased(MouseEvent e)
	{
	    playingBoard.hideHint(boardHints);
	}
	public void mouseEntered(MouseEvent e){

        }
	public void mouseExited(MouseEvent e){}
	public void mouseClicked(MouseEvent e){}
		
    }
//	replaced by Angelo's function
//    private class fileLoadHandler implements ActionListener{
//
//	public void actionPerformed(ActionEvent e) {
//			
//	    String actionCode = e.getActionCommand();
//	    loadNewProblem(actionCode);	
//	}
//    }
	
    private class consistencyButtonHandler implements ActionListener, MouseListener {
		
	public void mousePressed(MouseEvent e)
	{
	    String[] actionCode = new String[4];
	    //the format of the actionCommand is char;char;numeral[;numeral]
	    //the first char is either b for binary or a for all diff.
	    //the second char is either l for line c for column or u for unit
	    //the first numeral is the line or column the second optional numeral
	    //is used only if it is a unit then the two numerals give the line and column
	    //numbers respectively of the unit.
	    actionCode = ((JButton)e.getComponent()).getActionCommand().split(";");
			
	    //We dont care wether it is binary or not we are just highligting an area.
	    if(actionCode[1].equals("l"))
		{
		    depressLine(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("c"))
		{
		    depressColumn(Integer.parseInt(actionCode[2]));				
		}
	    else if (actionCode[1].equals("u"))
		{
		    depressUnit(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));				
		}
	}
	public void mouseReleased(MouseEvent e)
	{
	    String[] actionCode = new String[4];
	    //the format of the actionCommand is char;char;numeral[;numeral]
	    //the first char is either b for binary or a for all diff.
	    //the second char is either l for line c for column or u for unit
	    //the first numeral is the line or column the second optional numeral
	    //is used only if it is a unit then the two numerals give the line and column
	    //numbers respectively of the unit.
	    actionCode = ((JButton)e.getComponent()).getActionCommand().split(";");
			
	    //We dont care wether it is binary or not we are just highligting an area.
	    if(actionCode[1].equals("l"))
		{
		    undepressLine(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("c"))
		{
		    undepressColumn(Integer.parseInt(actionCode[2]));				
		}
	    else if (actionCode[1].equals("u"))
		{
		    undepressUnit(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));				
		}
	}
	public void mouseEntered(MouseEvent e){
        String[] actionCode = new String[4];
	    //the format of the actionCommand is char;char;numeral[;numeral]
	    //the first char is either b for binary or a for all diff.
	    //the second char is either l for line c for column or u for unit
	    //the first numeral is the line or column the second optional numeral
	    //is used only if it is a unit then the two numerals give the line and column
	    //numbers respectively of the unit.
	    actionCode = ((JButton)e.getComponent()).getActionCommand().split(";");

            if(sudokuInterface.this.btnAllDifConsis[0].isEnabled()){
	    //We dont care wether it is binary or not we are just highligting an area.
	    if(actionCode[1].equals("l"))
		{
		    depressLine(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("c"))
		{
		    depressColumn(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("u"))
		{
		    depressUnit(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));
		}
            }
        }
	public void mouseExited(MouseEvent e){
        String[] actionCode = new String[4];
	    //the format of the actionCommand is char;char;numeral[;numeral]
	    //the first char is either b for binary or a for all diff.
	    //the second char is either l for line c for column or u for unit
	    //the first numeral is the line or column the second optional numeral
	    //is used only if it is a unit then the two numerals give the line and column
	    //numbers respectively of the unit.
	    actionCode = ((JButton)e.getComponent()).getActionCommand().split(";");

	    //We dont care wether it is binary or not we are just highligting an area.
	    if(actionCode[1].equals("l"))
		{
		    undepressLine(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("c"))
		{
		    undepressColumn(Integer.parseInt(actionCode[2]));
		}
	    else if (actionCode[1].equals("u"))
		{
		    undepressUnit(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));
		}
        }
	public void mouseClicked(MouseEvent e){}
		
		
	//the format of the actionCommand is char;char;numeral[;numeral]
	//the first char is either b for binary or a for all diff.
	//the second char is either l for line c for column or u for unit
	//the first numeral is the line or column the second optional numeral
	//is used only if it is a unit then the two numerals give the line and column
	//numbers respectively of the unit.
	public void actionPerformed(ActionEvent e)
	{
	    String[] actionCode = new String[4];
	    actionCode = e.getActionCommand().split(";");
			
	    if(actionCode[0].equals("b"))
		{
		    if(actionCode[1].equals("l"))
			{
			    binaryLineArcConsistency(Integer.parseInt(actionCode[2]));
			}
		    else if (actionCode[1].equals("c"))
			{
			    binaryColArcConsistency(Integer.parseInt(actionCode[2]));				
			}
		    else if (actionCode[1].equals("u"))
			{
			    binaryUnitArcConsistency(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));				
			}
		}
	    else if(actionCode[0].equals("a"))
		{
		    if(actionCode[1].equals("l"))
			{
			    alldifLineArcConsistency(Integer.parseInt(actionCode[2]));
			}
		    else if (actionCode[1].equals("c"))
			{
			    alldifColumnArcConsistency(Integer.parseInt(actionCode[2]));				
			}
		    else if (actionCode[1].equals("u"))
			{
			    alldifUnitArcConsistency(Integer.parseInt(actionCode[2]),Integer.parseInt(actionCode[3]));				
			}
		}

	}
	public void buttonPressed(){}
    }
	
	
    private class propogationButtonHandler implements ActionListener
    {
	public void actionPerformed(ActionEvent e) 
	{
	    String actionCode = e.getActionCommand();
	    setAutoPropogationType(actionCode);
			
	    //preform the propogation immediately?
	    //yes, setAutoPropogationType will do it.
	    //parentInterface.runDomainColoring();
	    repaint();
	}
    }
	
    private String testXMLFormat(String fileName)
    {
	DocumentBuilderFactory factoryBuilder;
	DocumentBuilder builder;
	Document doc;
	Element docElement;
	NodeList currentNodeList;
	String format = null;
	try
	    {
		factoryBuilder  = DocumentBuilderFactory.newInstance( );
		builder = factoryBuilder.newDocumentBuilder();
		doc = builder.parse( fileName );
		docElement = doc.getDocumentElement();

		//Read the presentation properties like name
		currentNodeList = docElement.getElementsByTagName("presentation");			
		format = currentNodeList.item(0).getAttributes().getNamedItem("format").getNodeValue();
		//System.out.println(format);
	    }
	catch (IOException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);			
	    }
	catch (ParserConfigurationException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);			
	    }
	catch (SAXException e)
	    {
		System.out.println("IO ERROR");
		System.out.println(e);			
	    }
		
	return format;		
    }	

//Angelo's functions

public void displayLineOfFile(String address)
	{
			this.rootPane.getContentPane().removeAll();
			//this.batchFile = this.getCodeBase()+address;
			this.batchFile = address;
			
			int numOfLines = 0;
			try {
				numOfLines = count(batchFile);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			String rangeOfFile = "[1.." + numOfLines + "]";
			inputNumLabel = new JLabel();
			inputNumLabel.setLocation(10, 10);
			inputNumLabel.setSize(280, 20);
			inputNumLabel.setText("Please choose an instance in "+rangeOfFile + "?");			
			this.add(inputNumLabel);
			
			inputNumField = new JTextField();
			inputNumField.setLocation(290,10);
			inputNumField.setSize(100, 20);
			this.add(inputNumField);
			
			chooser = new JButton("Submit");		
			chooser.setActionCommand("Choose");
			//chooser.setBorder(null);
			chooser.addActionListener(this);		
			chooser.setLocation(10,35);
			chooser.setSize(100, 20);
			this.add(chooser);
			
			defaultLabel = new JLabel();
			defaultLabel.setLocation(260, 35);
			defaultLabel.setSize(250, 20);
			defaultLabel.setText("(Default/out of range =1)");
			this.add(defaultLabel);
			
			this.repaint();
	
	}
	
	public void displayFileTypeTwo(String address)
	{
			this.rootPane.getContentPane().removeAll();
			this.batchFile = address;					
			
			String rangeOfFile = "[1..100]";
			inputNumLabel = new JLabel();
			inputNumLabel.setLocation(10, 10);
			inputNumLabel.setSize(250, 20);
			inputNumLabel.setText("Please choose an instance in "+rangeOfFile + "?");			
			this.add(inputNumLabel);
			
			inputNumField = new JTextField();
			inputNumField.setLocation(260,10);
			inputNumField.setSize(100, 20);
			this.add(inputNumField);
			
			chooser = new JButton("Submit");		
			chooser.setActionCommand("Open");
			chooser.setBorder(null);
			chooser.addActionListener(this);		
			chooser.setLocation(10,35);
			chooser.setSize(100, 20);
			this.add(chooser);
			
			defaultLabel = new JLabel();
			defaultLabel.setLocation(260, 35);
			defaultLabel.setSize(250, 20);
			defaultLabel.setText("(Default/out of range =1)");
			this.add(defaultLabel);
			
			this.repaint();	
	}

//	 This function is used to count the number of lines in the file.
	public int count(String fileName) throws IOException {
		int numLines = 0;
		//FileReader fileReader = new FileReader("puzzles/Sudoku17.txt");
		//FileReader fileReader = new FileReader(fileName);
		URL source = new URL(fileName);
		//URL source = new URL(getCodeBase(), fileName);
	    BufferedReader br = new BufferedReader(new InputStreamReader(source.openStream()));
		//BufferedReader br = new BufferedReader(fileReader);
		String line;
		do {
			line = br.readLine();
			if (line != null)
			{
				numLines++;				
			}
		} while (line != null);
		
		return numLines;
	}
	
	public void loadNewProblemFromFile(int lineNum)
	{
		int numOfLines = 0;
		try {
			numOfLines = count(batchFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (lineNum > numOfLines || lineNum <= 0) {
			lineNum = 1;
		}
		BufferedReader in = null;
		String [] numbers = null;
		try {
			//URL source = new URL(getCodeBase(), batchFile);
			URL source = new URL(batchFile);
		    in =new BufferedReader(new InputStreamReader(source.openStream()));

            String curString = null;
		    //do nothing
			for (int lineCount = 0; lineCount < lineNum; lineCount++){

		    curString = in.readLine();
            }

            numbers = curString.split("");
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			if (in != null) {
			  try {
				in.close();
			  } catch (IOException ioe) {
		     	ioe.printStackTrace();
			  }
		    }
	    }
		if (numbers != null) {
			myProblem = loadProblemFromArray(numbers);
            if(batchFile.substring(56).startsWith("S"))
            {
                myProblem.setName("SMTop100-"+ lineNum);
            }
            else if(batchFile.substring(56).startsWith("G"))
            {
                myProblem.setName("GRoyle-" + lineNum);
            }
            problemLocation = batchFile;
		}

		if (constructorPanel.getSudokuType().equals("Extra-Regions")) {
			extraRegionsCells ec = extraRegionsCells.getInstance();
			ec.initRegionColor();
		} else 	if (constructorPanel.getSudokuType().equals("Even-Odd")) {
			constructorPanel.removeAllEvenOddCells();
		} else 	if (constructorPanel.getSudokuType().equals("Geometry")) {
			geometryCells gc = geometryCells.getInstance();
			gc.initRegionColor();
		}

                dbpuzzle = 0;
		// delete all of the old problem stuff.
		this.rootPane.getContentPane().removeAll();
		initialize();
		//String instName = myProblem.getOrigNameValue();

		String instName = myProblem.getOrigNameValue();
		if (this.batchFile.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/GRoyle17min.txt")) {
			instName = "GRoyle17min-" + lineNum;
		} else if (this.batchFile.equals("http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/Stertenbrink+Meyrignac-Top100.txt")) {
			instName = "Stertenbrink-" + lineNum;
		}

		constructorPanel.setsuTypeList(myProblem.getSuType());
		constructorPanel.setSourceField(instName);
		constructorPanel.setLowerField("1");
		constructorPanel.setUpperField("0");
		constructorPanel.setLevelField("0");
		constructorPanel.setNameField(instName);
		constructorPanel.setOriginalField(instName);
		constructorPanel.setDescriptionField(myProblem.getDescValue());

	}
	
	public void loadNewProblemFromFileTypeTwo(int fileNum)
	{
		
		BufferedReader in = null;
		
		String [] numbers = null;
		String [] numArray = new String[82];
		numArray[0] = "0";
		String line;
		int arrayIndex = 1;
		try {
			//URL source = new URL(getCodeBase(), batchFile);
			URL source = new URL(batchFile);
		    in =new BufferedReader(new InputStreamReader(source.openStream()));
			
		    do {
				line = in.readLine();
				if (line != null)
				{
					numbers = line.split("");
					for (int i = 1; i <= 18; i += 2){
						if (numbers[i].equals("1")){
							numArray[arrayIndex++] = numbers[i+1];
						} else {
							numArray[arrayIndex++] = "0";
						}
					}
				}
			} while (line != null);		    
								
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			if (in != null) {
			  try {
				in.close();
			  } catch (IOException ioe) {
		     	ioe.printStackTrace();
			  }
		    }			
	    }

        String instName = "VH-" + batchFile.substring(70);

		if (numArray != null) {			
			String [] tmpStr = this.batchFile.split("_");
			String [] tmpStr2 = tmpStr[1].split("\\.");
			
			int diff = Integer.parseInt(tmpStr2[0]);
			myProblem = loadProblemFromArray(numArray, diff);
            myProblem.setName(instName);
            System.out.println(instName);
            problemLocation = batchFile;
		}
		dbpuzzle = 0;

		// delete all of the old problem stuff.
		this.rootPane.getContentPane().removeAll();
		initialize();
	}
	
	
	
	private constraintProblem loadProblemFromArray(String [] numArray)
	{
		parserArray myparser = new parserArray();
		myparser.parseArray(numArray);			
		System.out.println("Load constraint from array");
		return myparser.getProblem();		
	}
	private constraintProblem loadProblemFromArray(String [] numArray, int diffLevel)
	{
		parserArray myparser = new parserArray();
		myparser.parseArray(numArray, diffLevel);			
		System.out.println("Load constraint from array");
		return myparser.getProblem();		
	}

    public class showAboutMenu implements ActionListener {
        private Component component;

        showAboutMenu(Component component) {
          this.component = component;
        }
        
        public void actionPerformed(ActionEvent e) {
            aboutBox.setVisible(true);
        }
        
    };

    public class FilterListener implements ActionListener {
        private Component component;

        FilterListener(Component component) {
          this.component = component;
        }

        public void actionPerformed(ActionEvent e) {
            dbmysql database;
            try {
                database = new dbmysql();
                matches = database.filter(puzzTypeBox.getSelectedItem().toString(),
                        maxDiffBox.getSelectedItem().toString(), diffBox.getSelectedItem().toString(),
                        numSolBox.getSelectedIndex(), consisBox.getSelectedItem().toString());
                matchesBox.setText(matches + "");

            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    };

	public class ShowInstanceListener implements ActionListener{
        private Component component;
        
        ShowInstanceListener(Component component)
        {
            this.component = component;
        }
        
         @SuppressWarnings("empty-statement")
        public synchronized void actionPerformed(ActionEvent actionEvent) {
            try {
                sudokuInterface.this.fromInstance();
                
            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }

    public class SelectedTabListener implements ChangeListener{
        private Component component;

        SelectedTabListener(Component component){
            this.component = component;
        }

        public void stateChanged(ChangeEvent e) {
            if(sudokuInterface.this.jTabbedPane1.getSelectedIndex() == 3){
                for(int i = 0; i < 18; i++){
                    sudokuInterface.this.btnAllDifConsis[i].setEnabled(true);
                    sudokuInterface.this.btnBinConsis[i].setEnabled(true);
                    
                }
            }
            else{
                for(int i = 0; i < 18; i++){
                    sudokuInterface.this.btnAllDifConsis[i].setEnabled(false);
                    sudokuInterface.this.btnBinConsis[i].setEnabled(false);
                }
            }
        }
    }
	
    public class ShowDatabaseListener implements ActionListener {
        private Component component;

        ShowDatabaseListener(Component component) {
          this.component = component;
		  //instancePanel.setVisible(false);
        }

        @SuppressWarnings("empty-statement")
        public synchronized void actionPerformed(ActionEvent actionEvent) {
            try {
                sudokuInterface.this.fromDatabase();
            } catch (Exception ex) {
                Logger.getLogger(sudokuInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    };
    
    class tabChangeListener implements ChangeListener {
        public void stateChanged(ChangeEvent e) {
                if(jTabbedPane1.getSelectedIndex()==3){
                    have_used_algs = 1;
                   stopTimer();
                }
                if(jTabbedPane1.getSelectedIndex()==1){
                    if(have_used_algs==1){
                        problemPanel.add(haveused);
                    }
                }
        }
    };

	public void loadNewProblemNoPreassign(String absoluteAddress)
	{
		myProblem = this.LoadProblemNoPreassign();
		myProblem.setName(constructorPanel.getNameField());
		//delete all of the old problem stuff.
		//this.rootPane.getContentPane().removeAll();

		this.rootPane.getContentPane().remove(playingBoard);

		//initialize();
		initialize_reset();

	}

	public constraintProblem LoadProblemNoPreassign()
	{
		parserXML myparser = new parserXML();
		parserXML3 myparser3 = new parserXML3();
		testXMLFormat testF = new testXMLFormat();

		myparser.parseXMLNoPreassign(this.getCodeBase()
				+ "puzzles/empty.sudoku.xml");
		problemLocation = this.getCodeBase() + "puzzles/empty.sudoku.xml";
		return myparser.getProblem();
	}

    public void resetGrid(){
            loadNewProblemNoPreassign(problemLocation);
            playingBoard.repaint();
    }

     public void backToOrigProblem()
	{
		myProblem.setName(constructorPanel.getNameField());
            myProblem.setOrigNameValue(constructorPanel.getOriginalField());
            myProblem.setDescValue(constructorPanel.getDescriptionField());
            myProblem.setLevelDiffValue(Integer.parseInt(constructorPanel.getLevelField()));
            myProblem.setLowerDiffValue(Integer.parseInt(constructorPanel.getLowerField()));
            myProblem.setUpperDiffValue(Integer.parseInt(constructorPanel.getUpperField()));
            myProblem.setSourceValue(constructorPanel.getSourceField());
//      myProblem.setSuType(suTypeList.getSelectedItem().toString());

		this.rootPane.getContentPane().removeAll();
		initialize();

		constructorPanel.setsuTypeList(myProblem.getSuType());
		constructorPanel.setSourceField(myProblem.getSourceValue());
		constructorPanel.setLowerField(Integer.toString(myProblem.getLowerDiffValue()));
		constructorPanel.setUpperField(Integer.toString(myProblem.getUpperDiffValue()));
		constructorPanel.setLevelField(Integer.toString(myProblem.getLevelDiffValue()));
		constructorPanel.setNameField(myProblem.toString());
		constructorPanel.setOriginalField(myProblem.getOrigNameValue());
		constructorPanel.setDescriptionField(myProblem.getDescValue());

                playingBoard.setVisible(true);
                playingBoard.validate();
	}

	public void displayNextSols(List solutions)
	{
		this.rootPane.getContentPane().removeAll();
		Font standard = new Font("Times Unicode", Font.PLAIN, 12);

		back = new JButton();
		back.setBorder(null);
		back.setText("Back to Constructor");
		back.addActionListener(constructorPanel);
		back.setActionCommand("back");
		back.setLocation(20, 450);
		back.setSize(170,20);
                back.setFont(standard);
		this.add(back);

		prev = new JButton();
		prev.setBorder(null);
		//btnResetProblem.setFont(new Font("Sarif",Font.PLAIN,10));
		prev.setText("<< Prev");
		prev.addActionListener(constructorPanel);
		prev.setActionCommand("prev");
                 prev.setFont(standard);
		prev.setLocation(395, 450);

		prev.setSize(120,20);
		this.add(prev);

		next = new JButton();
		next.setBorder(null);
		//btnResetProblem.setFont(new Font("Sarif",Font.PLAIN,10));
		next.setText("Next >>");
		next.addActionListener(constructorPanel);
		next.setActionCommand("next");
		next.setLocation(520, 450);
                next.setFont(standard);
		next.setSize(120,20);
		this.add(next);

		solBoards = null;
		int solSize = solutions.size();

		if ((solIndex + 5) <= solSize) {
			solBoards = new solBoard[6];

			for(int i = 0; i < 6; i++)
			{
				String [][] tmpSol = (String [][])solutions.get(solIndex - 1);
				solBoards[i] = new solBoard(tmpSol, myProblem, this);
				solBoards[i].setLocation((((i%3)*180) + ((i%3)*20) + 20),
						(((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));
				System.out.println("cords of solBoards of X");
				System.out.println((((i%3)*180) + 20));
				System.out.println("cords of solBoards of Y");
				System.out.println((((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));

				this.add(solBoards[i]);
				solIndex++;
			}

		}
		else if (solSize < 6)
		{
			solBoards = new solBoard[solSize];

			for(int i = 0; i < solSize; i++)
			{
				String [][] tmpSol = (String [][])solutions.get(i);
				solBoards[i] = new solBoard(tmpSol, myProblem, this);
				solBoards[i].setLocation((((i%3)*180) + ((i%3)*20) + 20),
						(((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));

				this.add(solBoards[i]);
				solIndex++;
			}
			prev.setEnabled(false);
			next.setEnabled(false);
		}
		else {
			int leftSize = solSize - solIndex + 1;
			solBoards = new solBoard[leftSize];

			for(int i = 0; i < leftSize; i++)
			{
				String [][] tmpSol = (String [][])solutions.get(solIndex - 1);
				solBoards[i] = new solBoard(tmpSol, myProblem, this);
				solBoards[i].setLocation((((i%3)*180) + ((i%3)*20) + 20),
						(((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));

				this.add(solBoards[i]);
				solIndex++;
			}

			next.setEnabled(false);
		}

		this.repaint();
	}

    public String generateArray() {
        String puzzlearray = "";
        int[][] array = new int[9][9];

        for (Iterator it=myProblem.getAllVariables().iterator(); it.hasNext( ); ) {
		        Object anObject = it.next( );
		        problemVariable pv = (problemVariable)anObject;
                System.out.println(pv.getColumnIndex() + "-" + pv.getLineIndex());
                if(pv.getAssigned() == null)
                {
                    array[pv.getLineIndex()-1][pv.getColumnIndex()-1] = 0;
                }
                else
                {
                    array[pv.getLineIndex()-1][pv.getColumnIndex()-1] = Integer.parseInt(pv.getAssigned());
                }
        }

        for(int i = 0; i <= 8; i++)
            for(int j= 0; j <= 8; j++)
            {
                puzzlearray = puzzlearray + array[j][i];
            }

        return puzzlearray;
    }

		public void displayPrevSols(List solutions)
	{
//		this.rootPane.getContentPane().remove(playingBoard);
//        this.rootPane.getContentPane().remove(inputPanel);
//        this.rootPane.getContentPane().remove(controlPanel);
		Font standard = new Font("Times Unicode", Font.PLAIN, 12);

		back = new JButton();
		back.setBorder(null);
		back.setText("Back to Constructor");
		back.addActionListener(constructorPanel);
		back.setActionCommand("back");
		back.setLocation(20, 450);
		back.setSize(170,20);
                back.setFont(standard);
		this.add(back);

		prev = new JButton();
		prev.setBorder(null);
		//btnResetProblem.setFont(new Font("Sarif",Font.PLAIN,10));
		prev.setText("<< Prev");
		prev.addActionListener(constructorPanel);
		prev.setActionCommand("prev");
		prev.setFont(standard);
		prev.setLocation(395, 450);

		prev.setSize(120,20);
		this.add(prev);

		next = new JButton();
		next.setBorder(null);
		//btnResetProblem.setFont(new Font("Sarif",Font.PLAIN,10));
		next.setText("Next >>");
		next.addActionListener(constructorPanel);
		next.setActionCommand("next");
		next.setLocation(520, 450);
                next.setFont(standard);
		next.setSize(120,20);
		this.add(next);

		solBoards = null;
		int solSize = solutions.size();
		solIndex--;

		if ((solIndex - 6) <= 0) {
			solBoards = new solBoard[6];

			for(int i = 0; i < 6; i++)
			{
				String [][] tmpSol = (String [][])solutions.get(i);
				solBoards[i] = new solBoard(tmpSol, myProblem, this);
				solBoards[i].setLocation((((i%3)*180) + ((i%3)*20) + 20),
						(((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));


				this.add(solBoards[i]);
				solIndex--;
			}
			prev.setEnabled(false);
		}
		else {
			int curIndex = solIndex - 5;
			solBoards = new solBoard[6];

			for(int i = 0; i < 6; i++)
			{
				String [][] tmpSol = (String [][])solutions.get(curIndex - 1);
				solBoards[i] = new solBoard(tmpSol, myProblem, this);
				//solBoards[i].setLocation((((i%3)*180) + 20),
				//		(((int)Math.floor(i/3)*180) + 20));

				solBoards[i].setLocation((((i%3)*180) + ((i%3)*20) + 20),
						(((int)Math.floor(i/3)*180) + ((int)Math.floor(i/3)*20) + 20));


				this.add(solBoards[i]);
				solIndex--;
			}
		}
		solIndex++;
		this.repaint();
	}

	public String generateSudokuXML() {
		String xmlStr = "";
		try {
		    // first of all we request out DOM-implementation:
		    javax.xml.parsers.DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		    // then we have to create document-loader:
		    javax.xml.parsers.DocumentBuilder loader = factory.newDocumentBuilder();


		    // createing a new DOM-document...
		    org.w3c.dom.Document document = loader.newDocument();

		    // create root-element
		    Element instance = document.createElement("instance");
		    Element presentation = document.createElement("presentation");
		    presentation.setAttribute("name", constructorPanel.getNameField());
		    presentation.setAttribute("originalname", constructorPanel.getOriginalField());
		    presentation.setAttribute("source", constructorPanel.getSourceField());
		    presentation.setAttribute("description", constructorPanel.getDescriptionField());
		    presentation.setAttribute("type", constructorPanel.getSelectedSuType());
		    presentation.setAttribute("sudokuformat", "");
		    presentation.setAttribute("difficultyScaleUpperBound", constructorPanel.getUpperField());
		    presentation.setAttribute("difficultyScaleLowerBound", constructorPanel.getLowerField());
		    presentation.setAttribute("difficultyLevel", constructorPanel.getLevelField());
		    presentation.setAttribute("nbSolutions", "");
		    presentation.setAttribute("maxConstraintArity", "9");
		    presentation.setAttribute("format", "Sudoku 3.0");

		    //add element under instance
		    instance.appendChild(presentation);

		    Element displayInfo = document.createElement("displayInfo");

		    Element rowSize = document.createElement("rowSize");
		    rowSize.setTextContent("9");

		    Element columnSize = document.createElement("columnSize");
		    columnSize.setTextContent("9");

		    Element nbOfOverlap = document.createElement("nbOfOverlap");
		    nbOfOverlap.setTextContent("0");

		    Element cellsOfOverlap = document.createElement("cellsOfOverlap");
		    cellsOfOverlap.setTextContent("0");
		    cellsOfOverlap.setAttribute("scope_One", "");
		    cellsOfOverlap.setAttribute("scope_Two", "");

		    Element coloredCells = document.createElement("coloredCells");
		    coloredCells.setTextContent("0");
		    coloredCells.setAttribute("color", "");
		    coloredCells.setAttribute("scope", "");

		    Element otherRegion = document.createElement("otherRegion");
		    otherRegion.setTextContent("1..9");
		    otherRegion.setAttribute("scope", "");

		    displayInfo.appendChild(rowSize);
		    displayInfo.appendChild(columnSize);
		    displayInfo.appendChild(nbOfOverlap);
		    displayInfo.appendChild(cellsOfOverlap);
		    displayInfo.appendChild(coloredCells);
		    displayInfo.appendChild(otherRegion);

		    //add element under instance
		    instance.appendChild(displayInfo);

		    Element domains = document.createElement("domains");
		    domains.setAttribute("nbDomains", "1");

		    Element domain = document.createElement("domain");
		    domain.setAttribute("name", "D0");
		    domain.setAttribute("nbValues", "9");
		    domain.setTextContent("1..9");
		    domains.appendChild(domain);

		    //add element under instance
		    instance.appendChild(domains);

		    Element variables = document.createElement("variables");
		    variables.setAttribute("nbVariables", "81");

		    for (int i = 1; i<= 9; i++ ){
		    	for (int j = 1; j <= 9; j++){
		    		Element variable = document.createElement("variable");
		    		variable.setAttribute("name", "V"+i+"-"+j);
		    		variable.setAttribute("domain", "D0");
		    		variables.appendChild(variable);
		    	}
		    }

		    //add element under instance
		    instance.appendChild(variables);

		    Element predicates = document.createElement("predicates");
		    predicates.setAttribute("nbPredicates", "1");

		    Element predicate = document.createElement("predicate");
		    predicate.setAttribute("name", "Preassigned");

		    Element parameters = document.createElement("parameters");
		    parameters.setTextContent("int X0 int X1");
		    predicate.appendChild(parameters);
		    Element expression = document.createElement("expression");
		    Element functional = document.createElement("functional");
		    functional.setTextContent("eq(X0,X1)");
		    expression.appendChild(functional);
		    predicate.appendChild(expression);
		    predicates.appendChild(predicate);

		    //add element under instance
		    instance.appendChild(predicates);


		    Element constraints = document.createElement("constraints");
		    constraints.setAttribute("nbConstraints", "");

		    int constraintIndex = 0;

		    for (int i = 1; i<= 9; i++ ){
		    	String scope = "";
		    	for (int j = 1; j <= 9; j++){
		    		String v = "V"+i+"-"+j;
		    		scope += v + " ";
		    	}
		    	constraintIndex++;
		    	Element constraint = document.createElement("constraint");
		    	constraint.setAttribute("name", "C"+constraintIndex);
		    	constraint.setAttribute("arity", "9");
		    	constraint.setAttribute("scope", scope);
		    	constraint.setAttribute("reference", "global:allDifferent");
		    	constraints.appendChild(constraint);
		    }

		    for (int i = 1; i<= 9; i++ ){
		    	String scope = "";
		    	for (int j = 1; j <= 9; j++){
		    		String v = "V"+j+"-"+i;
		    		scope += v + " ";
		    	}
		    	constraintIndex++;
		    	Element constraint = document.createElement("constraint");
		    	constraint.setAttribute("name", "C"+constraintIndex);
		    	constraint.setAttribute("arity", "9");
		    	constraint.setAttribute("scope", scope);
		    	constraint.setAttribute("reference", "global:allDifferent");
		    	constraints.appendChild(constraint);
		    }

		    // constraints for block constraint in Sudoku
		    String[] blockScope = {"V1-1 V1-2 V1-3 V2-1 V2-2 V2-3 V3-1 V3-2 V3-3",
		    		"V1-4 V1-5 V1-6 V2-4 V2-5 V2-6 V3-4 V3-5 V3-6",
		    		"V1-7 V1-8 V1-9 V2-7 V2-8 V2-9 V3-7 V3-8 V3-9",
		    		"V4-1 V4-2 V4-3 V5-1 V5-2 V5-3 V6-1 V6-2 V6-3",
		    		"V4-4 V4-5 V4-6 V5-4 V5-5 V5-6 V6-4 V6-5 V6-6",
		    		"V4-7 V4-8 V4-9 V5-7 V5-8 V5-9 V6-7 V6-8 V6-9",
		    		"V7-1 V7-2 V7-3 V8-1 V8-2 V8-3 V9-1 V9-2 V9-3",
		    		"V7-4 V7-5 V7-6 V8-4 V8-5 V8-6 V9-4 V9-5 V9-6",
		    		"V7-7 V7-8 V7-9 V8-7 V8-8 V8-9 V9-7 V9-8 V9-9"
		    		};
		    for (int i = 0; i<= 8; i++ ){
		    	String scope = blockScope[i];
		    	constraintIndex++;
		    	Element constraint = document.createElement("constraint");
		    	constraint.setAttribute("name", "C"+constraintIndex);
		    	constraint.setAttribute("arity", "9");
		    	constraint.setAttribute("scope", scope);
		    	constraint.setAttribute("reference", "global:allDifferent");
		    	constraints.appendChild(constraint);
		    }


		    for (Iterator it=myProblem.getAllVariables().iterator(); it.hasNext( ); ) {
		        Object anObject = it.next( );
		        problemVariable pv = (problemVariable)anObject;
		        if (pv.getAssigned() != null) {
		        	String vName = "V" + pv.getColumnIndex() + "-" + pv.getLineIndex();
		        	constraintIndex++;
		        	Element constraint_Preassigned = document.createElement("constraint");
		        	constraint_Preassigned.setAttribute("name", "C"+constraintIndex);
		        	constraint_Preassigned.setAttribute("arity", "1");
		        	constraint_Preassigned.setAttribute("scope", vName);
		        	constraint_Preassigned.setAttribute("reference", "Preassigned");
				    Element parameters_Preassigned = document.createElement("parameters");
				    parameters_Preassigned.setTextContent(vName + " " + pv.getAssigned());
				    constraint_Preassigned.appendChild(parameters_Preassigned);
				    constraints.appendChild(constraint_Preassigned);
		        }
		        //System.out.println( anObject );
		    }

		    String scopeExtraRegion = "";
		    if (constructorPanel.getSelectedSuType() == "extra regions") {
		    	if (constructorPanel.extraRegionCells.size() > 9) {

		    	} else {
		    		Set entries = constructorPanel.extraRegionCells.entrySet();
		    	    Iterator it = entries.iterator();

		    	    while (it.hasNext()) {
		    	    	Map.Entry entry = (Map.Entry) it.next();
		    	    	String cIndex = (String)entry.getKey();
		    	    	String[] variableIndexes;
		    	    	variableIndexes = cIndex.split(",");

		    	    	String vName = "V" + variableIndexes[0] + "-" + variableIndexes[1];
		    	    	scopeExtraRegion += vName + " ";

		    	    }

		    	    Element constraint = document.createElement("constraint");
		    	    constraint.setAttribute("name", "ExtraRegion");
			    	constraint.setAttribute("arity", "9");
			    	constraint.setAttribute("scope", scopeExtraRegion);
			    	constraint.setAttribute("reference", "global:allDifferent");
			    	constraints.appendChild(constraint);
		    	}
		    }

            //add element under instance
		    instance.appendChild(constraints);

		    document.appendChild(instance);

		    // ... compose the rest document content ...
		    //String xmlPath = this.getCodeBase() + "instances/sudoku.xml";
		    //this.writeXmlFile(document, xmlPath);
		    //String xmlPath = "instances/sudoku.xml";
		    //this.writeXmlFile(document, xmlPath);
		    //System.out.println(xmlPath);

		    xmlStr = constructorPanel.xmlToString(document);
		    return xmlStr;

		 } catch (Exception ex) {
		      ex.printStackTrace();
		      return null;
		 }
	}


       public void submitPuzzle(){
            			  //String str = this.generateSudokuXML();
              String array = generateArray();


              checkConsistencyNeeded solveit = new checkConsistencyNeeded(array);
              String levelNeeded = solveit.checkConsistency();

              String db = "puzzles";
              int answer = 0;

              constructorPanel.setNumSolutionsField("...");

              solverThread mySolverThread = new solverThread(myProblem.copy(), constructorPanel.getNumSolutions());
              t = new Thread(mySolverThread);
              t.start();

              while(t.isAlive())
              {
                  //wait
              }

              int sols = 0;

              try{
                  sols = Integer.parseInt(constructorPanel.getNumSolutionsField());
              }
              catch(Exception ex){
                  sols = 51;
              }

              if(sols == 0)
              {
                  JOptionPane.showMessageDialog(this,"Puzzle has no solutions.");
                  answer = 1;
              }
              else if(sols > 1 && sols <= 50)
              {
                  answer = JOptionPane.showOptionDialog(this,
                          "This puzzle has more than one solution. \n Would you still like to " +
                          "submit it?","Are you sure?",JOptionPane.YES_NO_OPTION,
                          JOptionPane.QUESTION_MESSAGE,null,null,null);


              }
              else if(sols > 50)
              {
                  JOptionPane.showMessageDialog(this, "This puzzle has more than 50 solutions and \n" +
                          "will not be submitted to the database. If you believe it should be \n" +
                          "submitted, please contact us at: sudoku AT cse.unl.edu");
                  answer = 1;
              }

              if(answer == 0)
              {
              try {

                  dbmysql database = new dbmysql();
                  int state = database.uploadPuzzle(db, constructorPanel.getSudoku_Type(), constructorPanel.getSourceField(),
                                                    constructorPanel.getLowerField(), constructorPanel.getLevelField(),
                                                    constructorPanel.getUpperField(), constructorPanel.getNameField(),
                                                    constructorPanel.getOriginalField(), constructorPanel.getDescriptionField(),
                                                    array, sols, levelNeeded);

                  if(state == 0)
                  {
                      JOptionPane.showMessageDialog(this, "Puzzle sumbitted successfully to database");
                  }
                  else if(state == 1)
                  {
                      JOptionPane.showMessageDialog(this, "Puzzle NOT submitted. \n" +
                              "Puzzle already exists in database.");
                  }
                  else
                  {
                      JOptionPane.showMessageDialog(this, "Error submitting puzzle.");
                  }
              }
              catch (Exception ex) {

              }

//			  mainMenu.removeAll();

              }
              else
              {
                  JOptionPane.showMessageDialog(this, "Puzzle NOT submitted.");
              }
        }

        public void findSolutions(){
                solverThread mySolverThread = new solverThread(myProblem.copy(), constructorPanel.getNumSolutions());
				t = new Thread(mySolverThread);
				t.start();
        }

	public void initialize_reset() {
		//int numCols = myProblem.totalColumns;  //these two should always be equal
		//int numLines = myProblem.totalLines;

		//make the board first because it decides some of its own dimensions..
		// or at least it should in the future.
		playingBoard = new sudokuBoard(myProblem, this);
//		playingBoard.runDomainColoring();
		playingBoard.setLayout(null);
		playingBoard.setBackground(Color.WHITE);
		playingBoard.setLocation(PLAYING_BOARD_X_POS, PLAYING_BOARD_Y_POS);
		//sudokuBoard.setUndecorated(true);
		this.add(playingBoard);

		playingBoard.setMouseAction("assign");

		showDomains = true;
		autoPropogationType = "propNone"; //TODO:FIX THIS

		//myProblem.resetDomainReductions();
                this.validate();
		this.repaint();
	}

        public void setSoluList(List newSoluList) {
		constructorPanel.setSoluList(newSoluList);
	}

      class ClockListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		//... Whenever this is called, get the current time and
    		//    display it in the textfield.

            String seconds;
            String hours;
            String minutes;


            s = s + 1;
            if(s==60){
            s = 0;
            m = m + 1;
            }

            if(m==60){
                m = 0;
                h = h + 1;
            }

            if(s < 10){
               seconds  = "0" + Integer.toString(s);

            }
            else{
                seconds = Integer.toString(s);
            }

            if(m < 10){
               minutes = "0" + Integer.toString(m);

            }
            else{
                minutes = Integer.toString(m);
            }

            if(h<10){
               hours = "0" + Integer.toString(h);
            }
            else {
                hours = Integer.toString(h);
            }


//            Calendar now = Calendar.getInstance();
//            int h = now.get(Calendar.HOUR_OF_DAY);
//            int m = now.get(Calendar.MINUTE);
//            int s = now.get(Calendar.SECOND);
            timeField.setText("" + hours + ":" + minutes + ":" + seconds);
            //... The following is an easier way to format the time,
            //    but requires knowing how to use the format method.
            //_timeField.setText(String.format("%1$tH:%1$tM:%1$tS", now));

            playingBoard.check_if_complete();
    	}
    }

}
