package edu.unl.consystlab.sudokuSolver;


import java.util.logging.Level;
import java.util.logging.Logger;
import edu.unl.consystlab.sudokuSolver.*;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.applet.Applet;
import java.awt.event.ActionListener;
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.JComboBox;
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 javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JCheckBox;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.PopupMenu;
import java.awt.Container;

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

import javax.swing.JRadioButton;
import java.awt.Checkbox;
import javax.swing.JCheckBox;
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 java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

import java.security.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import edu.unl.consystlab.sudokuSolver.solverThread;
import edu.unl.consystlab.ftp.FTPClient;
import edu.unl.consystlab.ftp.FTPException;
import edu.unl.consystlab.gui.Dialogs;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.lang.String;
import java.sql.ResultSet;
import java.text.NumberFormat;
import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.Timer;
import javax.swing.text.*;
//import sudoku.*;


import edu.unl.consystlab.sudokuSolver.constructorInterface;



public class constructorInterface extends JPanel implements ActionListener, ItemListener{

	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 String autoPropogationType;
	private boolean showDomains;
	private String sudoku_type;
	private String problemLocation;
	private JPanel controlPanel;
	private JPanel inputPanel;
	private JComboBox suTypeList;
	private ItemListener suTypeListListener;
	private JTextField sourceField;
	private JTextField lowerField;
	private JTextField upperField;
	private JTextField levelField;
	private JTextField nameField;
	private JTextField originalField;
	private JTextArea descriptionField;
	private JScrollPane scrollDescriptionField;
	public Map extraRegionCells;
	private Map evenOddCells;
	
	private JLabel inputNumLabel;
	private JLabel defaultLabel;
	private JTextField inputNumField;
	private JButton chooser;
	private String batchFile;
	private List soluList;
        private JFrame aboutBox;
        private JButton cancelButton;
        private int puzzlesInDB = 0;
        private String[] puzzleNumbers;

	private DocumentBuilderFactory factoryBuilder = null;
	private DocumentBuilder builder = null;
	private Document doc = null;

	private JLabel numberEliminatedLabel;
	private JLabel numSolutions;


    private JComboBox puzzTypeBox;
    private JComboBox diffBox;
    private JComboBox maxDiffBox;
    private JTextField matchesBox;
    private JList queryResults;
    private String[][] results;
    private Thread t;
    private JComboBox numSolBox;
    private String orderBy;
    private JComboBox consisBox;
    private String puzzleType;
    private String maxLevel;
    private String level;
    private int numSol;
    private String consistency;
    private boolean queried;
    private JButton dbDefaultBtn2;
    private JButton dbDefaultBtn3;
    private JButton dbDefaultBtn4;
    private JButton dbDefaultBtn5;
    private JButton dbDefaultBtn6;
    private sudokuInterface parentInterface;

    public constructorInterface(){
//	public void init() {

//        maincomponent = this;

        queried = false;


//		myProblem = LoadProblemNoPreassign();
		initialize();
	}

//    public constructorInterface(constraintProblem problem, sudokuBoard board, sudokuInterface parent)
    public constructorInterface(sudokuInterface parent)
    {

//        maincomponent = this;
        queried = false;
//        myProblem = problem;
//        playingBoard = board;
        parentInterface = parent;
        initialize();
    }

	public void initialize()
	{

//		int numCols = myProblem.totalColumns;  //these two should always be equal
//		int numLines = myProblem.totalLines;
//
//		int unitsWide = (int)(numCols/myProblem.columnsPerUnit);
//		int unitsHigh = (int)(numLines/myProblem.linesPerUnit);

//        Font standard = new Font("Times Unicode", Font.PLAIN, 11);
        Font standardbutton = new Font("Times Unicode", Font.PLAIN, 10);
        Font standardlabel = new Font("Times Unicode", Font.PLAIN, 12);
        int xloc = 80;

        //default type
        sudoku_type = "Base";

		//set up the display window
//		this.setBackground(Color.WHITE);
		this.setSize(499, 538);
		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.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");

//		int cellWidth = playingBoard.getCellWidth();
//		int cellHeight = playingBoard.getCellHeight();
//		int cellBorderWidth = playingBoard.getUnitBorderWidth();

//		PopupMenu pumModel = new PopupMenu("Model");
//		pumModel.add("binary");
//		pumModel.insert("hi",2);
//		pumModel.setEnabled(true);
//		//pumModel.show(this,500,400);
//		this.add(pumModel);


//		inputPanel = new JPanel();
//		inputPanel.setSize(260,480);
//                inputPanel.setFont(standard);
//		inputPanel.setLocation(430,10);
//		inputPanel.setBackground(Color.WHITE);
//		inputPanel.setLayout(null);

                this.setFont(standardlabel);

		//draw a border
//		Border etchedBdr = BorderFactory.createEtchedBorder();
//		Border titleBdr = BorderFactory.createTitledBorder(etchedBdr, "Input new instance");
//		Border emptyBdr = BorderFactory.createEmptyBorder(10,10,10,10);
//		Border compoundBdr = BorderFactory.createCompoundBorder(titleBdr, emptyBdr);
//		inputPanel.setBorder(compoundBdr);

		JLabel label1 = new JLabel("Sudoku Type");
                label1.setLocation(xloc, 15);
                label1.setSize(200, 20);
                label1.setFont(standardlabel);
                this.add(label1);
//                inputPanel.add(label1);

        String[] typeStrings = { "Base"};//, "Dodeka", "Monster", "Diagonal", "Extra-Regions", "Even-Odd", "Big-Small", "Geometry", "Magic", "Samurai" };
	    suTypeList = new JComboBox(typeStrings);
        suTypeList.setFont(standardlabel);
		suTypeList.setSelectedIndex(0);
		suTypeList.setActionCommand("type");
		suTypeList.addFocusListener(
				new java.awt.event.FocusAdapter(){
					int aux_selected;
					public void focusGained(java.awt.event.FocusEvent fe)
		        	{
						//get index value of selected element
		        	    aux_selected = suTypeList.getSelectedIndex();

		        	    //create a variable for storing de ItemListener
		        	    suTypeListListener = new java.awt.event.ItemListener() {
		        	    	public void itemStateChanged(java.awt.event.ItemEvent e) {
		        	    		if(e.getStateChange()==java.awt.event.ItemEvent.SELECTED) {
		        	    			//compares the selected value with the old one
		        	    			if (aux_selected!=suTypeList.getSelectedIndex()) {
		        	    				System.out.println("ComboBox Changed !");
		        	    				System.out.println("ItemListener has been started.");

		        	    				sudoku_type = (String)suTypeList.getSelectedItem();
		        	    				System.out.println(sudoku_type);
		        	    				if (sudoku_type == "Extra-Regions") {
//		        	    					playingBoard.setMouseAction("Extra-Regions");


		        	    					//set extraRegionCells
		        	    					//Create a hash table
		        	    					extraRegionCells = new HashMap();    // hash table
		        	    					extraRegionCells.put("2,3", new Integer(1));
		        	    					extraRegionCells.put("2,4", new Integer(2));
		        	    					extraRegionCells.put("2,5", new Integer(3));
		        	    					extraRegionCells.put("3,3", new Integer(4));
		        	    					extraRegionCells.put("3,4", new Integer(5));
		        	    					extraRegionCells.put("3,5", new Integer(6));
		        	    					extraRegionCells.put("4,3", new Integer(7));
		        	    					extraRegionCells.put("4,4", new Integer(8));
		        	    					extraRegionCells.put("4,5", new Integer(9));

		        	    					initialize_extra_region();


		        	    				} else if (sudoku_type == "Even-Odd") {
//		        	    					playingBoard.setMouseAction("Even-Odd");


		        	    					//set extraRegionCells
		        	    					//Create a hash table
		        	    					evenOddCells = new HashMap();    // hash table
		        	    					evenOddCells.put("2,3", new Integer(1));
		        	    					evenOddCells.put("2,4", new Integer(1));
		        	    					evenOddCells.put("2,5", new Integer(1));
		        	    					evenOddCells.put("3,3", new Integer(1));
		        	    					evenOddCells.put("3,4", new Integer(1));
		        	    					evenOddCells.put("3,5", new Integer(1));
		        	    					evenOddCells.put("4,3", new Integer(1));
		        	    					evenOddCells.put("4,4", new Integer(1));
		        	    					evenOddCells.put("4,5", new Integer(1));
		        	    					evenOddCells.put("5,3", new Integer(1));
		        	    					evenOddCells.put("6,1", new Integer(1));
		        	    					evenOddCells.put("6,7", new Integer(1));
		        	    					evenOddCells.put("8,7", new Integer(1));
		        	    					evenOddCells.put("9,2", new Integer(1));

		        	    					initialize_even_odd();
		        	    				}
//		        	    				playingBoard.repaint();
		        	    			}
		        	            }
		        	        }
		        	    };
		        	// add the variable Listener to your Combo
		        	suTypeList.addItemListener(suTypeListListener);
		        	}

		        	// if focus is lost
		        	public void focusLost(java.awt.event.FocusEvent fe)
		        	{
		        	// remove the itemListener from the combobox
		        		suTypeList.removeItemListener(suTypeListListener);
		        	}
		        }
		);
		//suTypeList.addItemListener(this);
		suTypeList.setLocation(xloc,36);
	    suTypeList.setSize(110, 23);
		this.add(suTypeList);
//		inputPanel.add(suTypeList);

		JLabel label2 = new JLabel("Source (e.g., URL, your name)");
		label2.setLocation(xloc, 67);
		label2.setSize(300, 20);
        label2.setFont(standardlabel);
		this.add(label2);
//		inputPanel.add(label2);

		sourceField = new JTextField(20);
		sourceField.addActionListener(this);
        sourceField.setDocument(new JTextFieldLimit(50));
		sourceField.setLocation(xloc,94);
		sourceField.setSize(250, 20);
        sourceField.setFont(standardlabel);
		this.add(sourceField);
//		inputPanel.add(sourceField);

		JLabel label3 = new JLabel("Difficulty level:");
		label3.setLocation(xloc, 120);
		label3.setSize(250, 20);
        label3.setFont(standardlabel);
		this.add(label3);
//		inputPanel.add(label3);

		JLabel label4 = new JLabel("Min         This Puzzle              Max");
		label4.setLocation(xloc, 144);
		label4.setSize(250, 20);
        label4.setFont(standardlabel);
		this.add(label4);
//		inputPanel.add(label4);

    	lowerField = new JTextField(10);
        lowerField.setFont(standardlabel);
        lowerField.setEditable(false);
        lowerField.setDocument(new JTextFieldLimit(2));
        lowerField.setText("1");
		lowerField.addActionListener(this);
		lowerField.setLocation(xloc,168);
		lowerField.setSize(25, 20);
		this.add(lowerField);
//		inputPanel.add(lowerField);

		levelField = new JTextField(10);
        levelField.setFont(standardlabel);
        levelField.setDocument(new JTextFieldLimit(2));
        levelField.setText("1");
	    levelField.addActionListener(this);
	    levelField.setLocation(xloc + 70,168);
	    levelField.setSize(25, 20);
	    this.add(levelField);
//	    inputPanel.add(levelField);

		upperField = new JTextField(10);
        upperField.setFont(standardlabel);
        upperField.setDocument(new JTextFieldLimit(2));
        upperField.setText("5");
		upperField.addActionListener(this);
		upperField.setLocation(xloc + 150,168);
		upperField.setSize(25, 20);
		this.add(upperField);
//		inputPanel.add(upperField);

	    JLabel label6 = new JLabel("Name of Puzzle");
	    label6.setLocation(xloc, 195);
	    label6.setSize(190, 20);
        label6.setFont(standardlabel);
		this.add(label6);
//		inputPanel.add(label6);

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

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

	    //sdf.setTimeZone(TimeZone.getDefault());

	    //System.out.println("Now : " + sdf.format(cal.getTime()));


		nameField = new JTextField(10);
		nameField.addActionListener(this);
        nameField.setDocument(new JTextFieldLimit(50));
		nameField.setLocation(xloc,219);
        nameField.setText(sdf.format(cal.getTime()));
        nameField.setFont(standardlabel);
		nameField.setSize(250, 20);
	    this.add(nameField);
//	    inputPanel.add(nameField);

	    JLabel label7 = new JLabel("Name of Puzzle in Original Source");
	    label7.setLocation(xloc, 246);
        label7.setFont(standardlabel);
	    label7.setSize(200, 20);
		this.add(label7);
//		inputPanel.add(label7);

		originalField = new JTextField(10);
        originalField.setFont(standardlabel);
		originalField.setText("");
		originalField.addActionListener(this);
		originalField.setLocation(xloc,270);
        originalField.setDocument(new JTextFieldLimit(50));
		originalField.setSize(320, 20);
	    this.add(originalField);
//	    inputPanel.add(originalField);

	    JLabel label8 = new JLabel("Enter Description");
	    label8.setLocation(xloc, 297);
        label8.setFont(standardlabel);
	    label8.setSize(200, 20);
		this.add(label8);
//		inputPanel.add(label8);

		descriptionField = new JTextArea("Sudoku Puzzle");
		//descriptionField.setSize(190, 50);
		//descriptionField.setLocation(10, 303);
		descriptionField.setLineWrap(true);
        descriptionField.setFont(standardlabel);
        descriptionField.setDocument(new JTextFieldLimit(150));
		descriptionField.setWrapStyleWord(true);
		//descriptionField.setBorder(BorderFactory.createLineBorder(Color.BLACK));

		scrollDescriptionField = new JScrollPane(descriptionField , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS ,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollDescriptionField.setLocation(xloc, 321);
		scrollDescriptionField.setSize(340, 62);
        scrollDescriptionField.setFont(standardlabel);
		scrollDescriptionField.setBorder(BorderFactory.createLineBorder(Color.BLACK));

//		inputPanel.add(scrollDescriptionField);
                this.add(scrollDescriptionField);
		//inputPanel.add(descriptionField);

		JButton displaySolutionsButton = new JButton("Display Solutions");
		displaySolutionsButton.setActionCommand("displaySolutions");
		displaySolutionsButton.addActionListener(this);
		displaySolutionsButton.setLocation(xloc,440);
		displaySolutionsButton.setSize(120, 30);
        displaySolutionsButton.setFont(standardbutton);
//		inputPanel.add(displaySolutionsButton);
//                displaySolutionsButton.setEnabled(false);
                this.add(displaySolutionsButton);

//        JButton stopButton = new JButton();
//        stopButton.setActionCommand("stop!");
//        stopButton.setBorder(null);
//        stopButton.setFont(standardbutton);
//        stopButton.addActionListener(this);
//        stopButton.setText("Stop");
//        stopButton.setLocation(170,390);
//        stopButton.setSize(70, 20);
//        //stopButton.setVisible(false);
////        inputPanel.add(stopButton);
//        this.add(stopButton);

//		add a field for the number of solutions
		JButton numSolutionsButton = new JButton("# Solutions:");
		numSolutionsButton.setActionCommand("findSolutions");
		numSolutionsButton.addActionListener(this);
		numSolutionsButton.setLocation(xloc,400);
		numSolutionsButton.setSize(100, 30);
        numSolutionsButton.setFont(standardbutton);
//		inputPanel.add(numSolutionsButton);
        this.add(numSolutionsButton);



		numSolutions = new JLabel("");
                numSolutions.setFont(standardlabel);
		numSolutions.setLocation(xloc + 130,410);
		numSolutions.setSize(60, 15);
//		inputPanel.add(numSolutions);
                this.add(numSolutions);

		JButton btnSubmit = new JButton();
		btnSubmit.setText("Submit Puzzle");
		btnSubmit.addActionListener(this);
		btnSubmit.setActionCommand("submit");
		btnSubmit.setLocation(xloc + 220, 480);
		btnSubmit.setSize(120,30);
        btnSubmit.setFont(standardbutton);
//		inputPanel.add(btnSubmit);
                this.add(btnSubmit);

		JButton btnResetGridProblem = new JButton();
		//btnResetProblem.setFont(new Font("Sarif",Font.PLAIN,10));
		btnResetGridProblem.setText("Reset Grid");
		btnResetGridProblem.addActionListener(this);
		btnResetGridProblem.setActionCommand("resetGrid");
		btnResetGridProblem.setLocation(xloc, 480);
		btnResetGridProblem.setSize(100,30);
        btnResetGridProblem.setFont(standardbutton);
//		inputPanel.add(btnResetGridProblem);
                this.add(btnResetGridProblem);

		JButton btnResetAllProblem = new JButton();
		//btnResetAllProblem.setBorder(null);
		btnResetAllProblem.setFont(standardbutton);
		btnResetAllProblem.setText("Reset All");
		btnResetAllProblem.addActionListener(this);
		btnResetAllProblem.setActionCommand("resetAll");
		btnResetAllProblem.setLocation(xloc + 110, 480);
		btnResetAllProblem.setSize(100,30);
//		inputPanel.add(btnResetAllProblem);
                this.add(btnResetAllProblem);

		JCheckBox domainBox = new JCheckBox("Show domains", true);
		domainBox.setActionCommand("showDomains");
		domainBox.setSize(110,20);
        domainBox.setFont(standardlabel);
		domainBox.setLocation(130,36);
		domainBox.setBackground(Color.WHITE);
		domainBox.addItemListener(this);
//		inputPanel.add(domainBox);
//                this.add(domainBox);

//		this.add(inputPanel);
		showDomains = true;
		autoPropogationType = "propNone"; //TODO:FIX THIS
		this.repaint();
	}



	public void initialize_extra_region() {

		//controlPanel
		JCheckBox extraRegionBox = new JCheckBox("Select Extra Region", true);
		extraRegionBox.setActionCommand("extra regions");
		extraRegionBox.setSize(200,20);
		extraRegionBox.setLocation(10,15);
		extraRegionBox.setBackground(Color.WHITE);
		extraRegionBox.addItemListener(this);
		controlPanel.add(extraRegionBox);

		//playingBoard.problemCells[tempCellNum].

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

	}

	public void initialize_even_odd() {

		//controlPanel
		JCheckBox evenOddBox = new JCheckBox("Select Odd Cells", true);
		evenOddBox.setActionCommand("even-odd");
		evenOddBox.setSize(200,20);
		evenOddBox.setLocation(10,15);
		evenOddBox.setBackground(Color.WHITE);
		evenOddBox.addItemListener(this);
		controlPanel.add(evenOddBox);

		//playingBoard.problemCells[tempCellNum].

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

	}



    public class ShowDatabaseListener implements ActionListener {
        private Component component;

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

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

        }
  }

   public class FilterListener implements ActionListener {
        private Component component;
        private int matches;

        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(constructorInterface.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }

   public void setsuTypeList(String suType){
       suTypeList.setSelectedItem(suType);
   }

   public void setSourceField(String source){
       sourceField.setText(source);
   }

   public void setLowerField(String lower){
       lowerField.setText(lower);
   }

   public void setUpperField(String upper){
       upperField.setText(upper);
   }

   public void setNameField(String name){
       nameField.setText(name);
   }

   public void setLevelField(String level){
       levelField.setText(level);
   }

   public void setOriginalField(String original){
       originalField.setText(original);
   }

   public void setDescriptionField(String description){
       descriptionField.setText(description);
   }

   public void setNumSolutionsField(String numSol){
        numSolutions.setText(numSol);
   }

   public String getNameField(){
       return nameField.getText();
   }


   public String getSourceField(){
       return sourceField.getText();
   }

   public String getLowerField(){
       return lowerField.getText();
   }

   public String getUpperField(){
       return upperField.getText();
   }

   public String getLevelField(){
       return levelField.getText();
   }

   public String getOriginalField(){
       return originalField.getText();
   }

   public String getDescriptionField(){
       return descriptionField.getText();
   }

   public String getSelectedSuType(){
       return (String)suTypeList.getSelectedItem();
   }

   public String getSudoku_Type(){
       return sudoku_type;
   }

   public String getNumSolutionsField(){
       return numSolutions.getText();
   }

   public JLabel getNumSolutions(){
       return numSolutions;
   }
   
                //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, 225, 225, 225)
                    .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;
            }
    }



    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 void writeXmlFile(Document doc, String filename) {
        try {
            // Prepare the DOM document for writing
            Source source = new DOMSource(doc);

            // Prepare the output file
            File file = new File(filename);
            Result result = new StreamResult(file);

            // Write the DOM document to the file
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
        } catch (TransformerException e) {
        }
    }

	public String xmlToString(Document doc) {
        try {
            Source source = new DOMSource(doc);
            StringWriter stringWriter = new StringWriter();
            Result result = new StreamResult(stringWriter);
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();
            transformer.transform(source, result);
            return stringWriter.getBuffer().toString();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return null;
    }


    //Used to limit the number of characters in fields, as not to create database errors
    public class JTextFieldLimit extends PlainDocument {
          private int limit;
          private boolean toUppercase = false;

          JTextFieldLimit(int limit) {
           super();
           this.limit = limit;
           }

          public void insertString
            (int offset, String  str, AttributeSet attr)
              throws BadLocationException {
           if (str == null) return;

           if ((getLength() + str.length()) <= limit) {
             if (toUppercase) str = str.toUpperCase();
             super.insertString(offset, str, attr);
             }
           }
        }


    public void displayLineOfFile(String address)
	{
			Font standard = new Font("Times Unicode", Font.PLAIN, 11);

//            this.rootPane.getContentPane().remove(playingBoard);
//            this.rootPane.getContentPane().remove(inputPanel);
//            this.rootPane.getContentPane().remove(controlPanel);
			//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(300, 20);
            inputNumLabel.setFont(standard);
			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("Choose");
			//chooser.setBorder(null);
            chooser.setFont(standard);
			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.setFont(standard);
			defaultLabel.setText("(Default/out of range =1)");
			this.add(defaultLabel);

			this.repaint();

	}

    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 displayFileTypeTwo(String address)
//	{
////			this.rootPane.getContentPane().remove(playingBoard);
////            this.rootPane.getContentPane().remove(inputPanel);
////            this.rootPane.getContentPane().remove(controlPanel);
//			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();
//	}



	public void writeLibraryIndex(String indexLocation, String fileName, String indexPath) {

		DocumentBuilderFactory factoryBuilder;
		DocumentBuilder builder;
		Document doc;
		Element docElement;


		try
		{
			factoryBuilder  = DocumentBuilderFactory.newInstance( );
			builder = factoryBuilder.newDocumentBuilder();
			doc = builder.parse( indexLocation );
			docElement = doc.getDocumentElement();

			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"))
					{
						if ((children.item(i).getAttributes().getNamedItem("name").getNodeValue()).equals("UsersInput")) {
							Node firstChild = findNodeItem(children.item(i), "Difficulty0.." + this.upperField.getText());
							Node secondChild = findNodeItem(firstChild, "Level" + this.levelField.getText());
							Node thirdChild = findNodeItem(secondChild, (String)suTypeList.getSelectedItem());
							Element newFile = doc.createElement("file");
							newFile.setAttribute("name", fileName);
							thirdChild.appendChild(newFile);
						}

					}
				}
			}

            /*
			SshParameters params = new SshParameters("sudoku.unl.edu", "consystlab","A/tutti");

            // create new Scp instance
            Scp scp = new Scp(params);

            // register event listener
            scp.addListener(this);

            // establish connection
            scp.connect();

			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StringWriter sw=new StringWriter();
			StreamResult result = new StreamResult(sw);
			transformer.transform(source, result);
			String xmlString=sw.toString();


            // upload file
    		scp.upload(xmlString.getBytes(), indexPath, "libraryIndex.xml");


        	// disconnect
            scp.disconnect();

		*/

		}
		catch (IOException e)
		{
			System.out.println("IO ERROR7");
			System.out.println(e);
		}
		catch (ParserConfigurationException e)
		{
			System.out.println("IO ERROR8");
			System.out.println(e);
		}
		catch (SAXException e)
		{
			System.out.println("IO ERROR9");
			System.out.println(e);
		}



		return;





	}

//		find a element iteratively
	private Node findNodeItem(Node currentNode, String nodeValue)
	{
		try {

			NodeList children = currentNode.getChildNodes();

			for (int i = 0; i < children.getLength(); i++) {
				if (children.item(i).getNodeType() == 1) {
					if ((children.item(i).getNodeName()).equals("directory")) {
						if ((children.item(i).getAttributes().getNamedItem(
								"name").getNodeValue()).equals(nodeValue)) {
							return children.item(i);
						}
					}
				}
			}
		}

		catch (Exception e) {
			System.out.println("IO ERROR");
			System.out.println(e);
			return null;
		}
		return null;
	}

	public void actionPerformed(ActionEvent e)
	{

		if(e.getActionCommand().equals("submit")) {

                      parentInterface.submitPuzzle();

        }

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

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

            try{
//                dbmysql database = new dbmysql();
//                database.upload(puzzle);
//                myProblem = loadProblemFromArray(database.getArray());
//                myProblem.setName(database.getName());
////                this.rootPane.getContentPane().removeAll();
//                initialize();
//
//                suTypeList.setSelectedItem(myProblem.getSuType());
//                sourceField.setText(database.getSource());
//                lowerField.setText(database.getLower());
//                upperField.setText(database.getUpper());
//                levelField.setText(database.getLevel());
//                nameField.setText(database.getName());
//                originalField.setText(database.getOrigName());
//                descriptionField.setText(database.getDesc());

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

        }
        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(puzzTypeBox.getSelectedItem().toString(),
                            maxDiffBox.getSelectedItem().toString(), diffBox.getSelectedItem().toString(),
                            numSolBox.getSelectedIndex(), consisBox.getSelectedItem().toString(), orderBy);

                    queryResults.setListData(results);

                } catch (Exception ex) {
                    Logger.getLogger(constructorInterface.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"))
        {

            //removeAll() causes combo box to be invisible

////            this.rootPane.getContentPane().remove(dbDefaultLabel);
////            this.rootPane.getContentPane().remove(dbDefaultLabel2);
////            this.rootPane.getContentPane().remove(dbDefaultLabel3);
////            this.rootPane.getContentPane().remove(dbDefaultLabel4);
            //this.rootPane.getContentPane().remove(dbDefaultLabel5);
            //this.rootPane.getContentPane().remove(dbDefaultLabel6);
            //this.rootPane.getContentPane().remove(dbDefaultLabel7);
            //this.rootPane.getContentPane().remove(dbDefaultLabel8);
////            this.rootPane.getContentPane().remove(dbDefaultLabel9);
            //this.rootPane.getContentPane().remove(dbDefaultLabel10);
            //this.rootPane.getContentPane().remove(dbDefaultLabel11);
            //this.rootPane.getContentPane().remove(dbDefaultLabel12);
////            this.rootPane.getContentPane().remove(dbDefaultLabel13);
////            this.rootPane.getContentPane().remove(matchesBox);
////            this.rootPane.getContentPane().remove(goButton);
////            this.rootPane.getContentPane().remove(cancelButton);
////            this.rootPane.getContentPane().remove(selectButton);
////            this.rootPane.getContentPane().remove(diffBox);
////            this.rootPane.getContentPane().remove(puzzTypeBox);
////            this.rootPane.getContentPane().remove(maxDiffBox);
////            this.rootPane.getContentPane().remove(queryResults);
////            this.rootPane.getContentPane().remove(scroller);
////            this.rootPane.getContentPane().remove(numSolBox);
////            this.rootPane.getContentPane().remove(consisBox);
////            this.rootPane.getContentPane().remove(dbDefaultBtn1);
////            this.rootPane.getContentPane().remove(dbDefaultBtn2);
////            this.rootPane.getContentPane().remove(dbDefaultBtn3);
////            this.rootPane.getContentPane().remove(dbDefaultBtn4);
////            this.rootPane.getContentPane().remove(dbDefaultBtn5);
////            this.rootPane.getContentPane().remove(dbDefaultBtn6);
////
////
////            this.rootPane.getJMenuBar().setVisible(true);
            initialize();

        }
		else if(e.getActionCommand().equals("load"))
		{
			Frame parent = new Frame();
			FileDialog openDialog = new FileDialog(parent, "load", FileDialog.LOAD);
			//openDialog.setDirectory("/net/napoli/export/creeson/sudoku/java/sudokuCSP/puzzles");
//			openDialog.setDirectory(this.getCodeBase() + "/puzzles");
			openDialog.setVisible(true);

			String inputFile = openDialog.getFile();
			if(inputFile == null)
			{
				//do nothing
			}
			else
			{
////				myProblem = this.loadProblem(openDialog.getDirectory() + File.separator + inputFile);

////				this.rootPane.getContentPane().remove(dbDefaultLabel);
////            this.rootPane.getContentPane().remove(dbDefaultLabel2);
////            this.rootPane.getContentPane().remove(dbDefaultLabel3);
////            this.rootPane.getContentPane().remove(dbDefaultLabel4);
////            this.rootPane.getContentPane().remove(matchesBox);
////            this.rootPane.getContentPane().remove(goButton);
////            this.rootPane.getContentPane().remove(cancelButton);
////            this.rootPane.getContentPane().remove(selectButton);
////            this.rootPane.getContentPane().remove(diffBox);
////            this.rootPane.getContentPane().remove(puzzTypeBox);
////            this.rootPane.getContentPane().remove(maxDiffBox);
////            this.rootPane.getContentPane().remove(queryResults);
////            this.rootPane.getContentPane().remove(scroller);
////            this.rootPane.getJMenuBar().setVisible(true);

				initialize();
			}
		}
//		else 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("findSolutions"))
		{
			numSolutions.setText("...");
			//make a thread to calculate the number of solutions

                        parentInterface.findSolutions();
			//mySolverThread.run();
		}
        else if(e.getActionCommand().equals("XML"))
		{
			String XMLfile = parentInterface.generateSudokuXML();
            try {
                //make a thread to calculate the number of solutions
                BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/jasongaare/puzzle.xml"));
                bw.write(XMLfile);

            } catch (IOException ex) {
                //do nothing
            }



		}
        else if(e.getActionCommand().equals("stop!"))
	{
            t.interrupt();
            numSolutions.setText("Unknown");
        }

		else if(e.getActionCommand().equals("displaySolutions"))
		{
//			solIndex = 1;
//			soluList = null;
//			solverThreadForSol mySolverThread = new solverThreadForSol(myProblem.copy(), this);
//			Thread t = new Thread(mySolverThread);
//			t.start();
                        JOptionPane.showMessageDialog(parentInterface, "Currently cannot display solutions.");
			System.out.println("displaySolutions starts...");

			//mySolverThread.run();
		}
		else if(e.getActionCommand().equals("next"))
		{
			parentInterface.displayNextSols(soluList);
			System.out.println("next doing...");

			//mySolverThread.run();
		}
		else if(e.getActionCommand().equals("prev"))
		{
			parentInterface.displayPrevSols(soluList);
			System.out.println("prev doing...");

			//mySolverThread.run();
		}
		else if (e.getActionCommand().equals("back")) {
			parentInterface.backToOrigProblem();
			System.out.println("back to constructor...");
		}

		else if(e.getActionCommand().equals("resetGrid"))
		{
                        parentInterface.resetGrid();
		}
		else if(e.getActionCommand().equals("resetAll"))
		{
			parentInterface.loadNewProblemWithResetAll(problemLocation);
		}
        else if(e.getActionCommand().equals("Choose"))
		{
			int num = Integer.parseInt(inputNumField.getText());

			parentInterface.loadNewProblemFromFile(num);
		}
        else if (e.getActionCommand().equals("Open"))
		{
			int num = 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);
		}
	}


    public void removeAllEvenOddCells() {
		evenOddCells.clear();
	}

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

			}
			else if (item.getActionCommand() == "extra regions") {
				if (item.isSelected()){
//					playingBoard.setMouseAction("extra regions");
				}else {
//					playingBoard.setMouseAction("assign");
				}
			} else if (item.getActionCommand() == "even-odd") {
				if (item.isSelected()){
//					playingBoard.setMouseAction("even-odd");
				}else {
//					playingBoard.setMouseAction("assign");
				}
			}
		}

//		if ((e.getItem() instanceof JComboBox) == true)
//		{
//			JComboBox item = (JComboBox)e.getItem();
//			if (item.getActionCommand() == "type") {
//				sudoku_type = (String)item.getSelectedItem();
//				System.out.println(sudoku_type);
//				if (sudoku_type == "extra regions") {
//					initialize_extra_region();
//					//set extraRegionCells
//					extraRegionCells = Arrays.asList(new Integer[]{4, 5, 6, 7, 8, 9, 10, 11, 12});
//
//				}
//				playingBoard.repaint();
//			}
//		}
	}

	public void runDomainColoring()
	{
//		playingBoard.runDomainColoring();
	}



	public void doAutoPropogation()
	{

		if(autoPropogationType.equals("propNone"))
		{
			//do nothing
			return;
		}
		else if(autoPropogationType.equals("propNonBinaryFC"))
		{
			//TODO:This
		}
		else if(autoPropogationType.equals("propBinaryFC"))
		{
			//This shouldn't happen.  It should call the overloaded method with
			// one variable passed to it.
		}
		else if(autoPropogationType.equals("propBinaryMAC"))
		{

		}
		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;
		}
		if(autoPropogationType.equals("propBinaryFC"))
		{

//			playingBoard.preformBinaryForwardCheckOnVariable(originalVariable);

		}
		if(autoPropogationType.equals("propBinaryMAC"))
		{
//			playingBoard.preformArcConsistency();
		}
	}

	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();
		}
	}

	public boolean showDomains()
	{
		if(showDomains)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	public void updateValuesRemoved(int numRemoved)
	{
		numberEliminatedLabel.setText(""+numRemoved);
	}
	public void updateValuesRemoved(String numRemoved)
	{
		numberEliminatedLabel.setText(numRemoved);
	}


	private void createLoadMenu(String indexLocation, JMenu mainMenu, ActionListener myListener)
	{
		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, mainMenu, myListener);
//			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)
	{

		//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), tempMenu, myListener);
				}
			}
			else if((currentNode.getNodeName()).equals("file"))
			{
				//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);
				parentMenu.add(tempItem);
			}
		}
	}



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

		return null;

	}



	private constraintProblem loadProblem(String absoluteAddress)
	{
		parserXML myparser = new parserXML();
		parserXML3 myparser3 = new parserXML3();
		testXMLFormat testF = new testXMLFormat();
		problemLocation = absoluteAddress;

		String format = testF.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;

	}
	public String getSudokuType(){
		return (String)suTypeList.getSelectedItem();
	}
	public Map getExtraRegionCells() {
		return (Map)extraRegionCells;
	}
	public boolean extraRegionCellsContains(String key){
		return extraRegionCells.containsKey(key);
	}
	public void setExtraRegionCell(Object obj1, Object obj2){
		extraRegionCells.put(obj1, obj2);
	}
	public void removeExtraRegionCell(Object obj1) {
		extraRegionCells.remove(obj1);
	}


	public Map getEvenOddCells() {
		return (Map)evenOddCells;
	}
	public boolean evenOddCellsContains(String key){
		return evenOddCells.containsKey(key);
	}
	public void setEvenOddCell(Object obj1, Object obj2){
		evenOddCells.put(obj1, obj2);
	}
	public void removeEvenOddCell(Object obj1) {
		evenOddCells.remove(obj1);
	}
	public void setSoluList(List newSoluList) {
		soluList = newSoluList;
	}

    public class showAboutMenu implements ActionListener {
        private Component component;

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

        public void actionPerformed(ActionEvent e) {
            aboutBox.setVisible(true);
        }

    };

	private 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();
	}


}
