
package edu.unl.consystlab.sudokuSolver;

import edu.unl.consystlab.sudokuSolver.consistencyAlgorithms.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

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;

/**
 *
 * @author jasongaare
 */
public class SGACloop {


	private static constraintProblem myProblem;
    private static int unassignedVars;


    public static void main(String[] args) throws IOException, Exception {

    if(args.length >= 0)
        {

        
		
        String addon = null;
        
        String line = null;

		BufferedReader in = null;
		String [] numbers = null;
        String [] numArray = new String[82];
        int arrayIndex = 1;
		try {
			//URL source = new URL(getCodeBase(), batchFile);


        for(int puzzNum = 51; puzzNum <= 100; puzzNum++)
        {
           arrayIndex = 1;
           String batchFile = "http://consystlab.unl.edu/SudokuLibrary/FromFiles/Basic/VegardHanssen/3x3_4.";
           if(puzzNum < 10)
               addon = "00" + puzzNum;
           else if(puzzNum == 100)
               addon = "" + puzzNum;
           else
               addon = "0" + puzzNum;

           batchFile = batchFile + addon;

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

           

        

		if (numbers != null) {

            if (numArray != null) {
			String [] tmpStr = batchFile.split("_");
			String [] tmpStr2 = tmpStr[1].split("\\.");

			int diff = Integer.parseInt(tmpStr2[0]);
			myProblem = loadProblemFromArray(numArray, diff);


            consistencyAlgorithm myAlgorithm = new shavingGAC(myProblem,null);

            unassignedVars = 0;

                    Iterator i = ((Collection)myProblem.getAllVariables()).iterator();
                    while(i.hasNext())
                    {
                        problemVariable currentVariable = (problemVariable)i.next();
                        if(!currentVariable.isAssigned())
                        {
                            unassignedVars++;
                        }
                    }

                    //System.out.println(unassignedVars);

                    myAlgorithm.runAlgorithm();
                    if(myAlgorithm.getVariableReductions().size() == (8*unassignedVars))
                    {
                        System.out.println(puzzNum + "  Solved");
                        
                    }
                    else
                    {
                        System.out.println(puzzNum +"  UNSOLVED");
                    }
            }
        }
        }
        

        } catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			if (in != null) {
			  try {
				in.close();
			  } catch (IOException ioe) {
		     	ioe.printStackTrace();
			  }
		    }
	    }

    }
    
    else
    {
        System.out.println("Invalid argument");
    }
    }

    private static constraintProblem loadProblemFromArray(String [] numArray)
	{
		parserArray myparser = new parserArray();
		myparser.parseArray(numArray);
		//System.out.println("Load constraint from array");
		return myparser.getProblem();
	}

    private static 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 static 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;
	}

    /*
    private static void createLoadMenu(String indexLocation, JMenu mainMenu) throws IOException
    {
	DocumentBuilderFactory factoryBuilder;
	DocumentBuilder builder;
	Document doc;
	Element docElement;
	//NodeList currentNodeList;

	try
	    {
		factoryBuilder  = DocumentBuilderFactory.newInstance( );
		builder = factoryBuilder.newDocumentBuilder();
		doc = builder.parse( indexLocation );
		docElement = doc.getDocumentElement();
            try {
                //build the menu depth first recursively
                createLoadMenu(docElement, mainMenu);
            } catch (InterruptedException ex) {
                Logger.getLogger(SGACloop.class.getName()).log(Level.SEVERE, null, ex);
            }
		

	    }
	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 static void createLoadMenu(Node currentNode, JMenu parentMenu) throws InterruptedException
    {


	//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);
			    }
		    }
		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);
            if(address.substring(0,5).equalsIgnoreCase("Users") &&
                    !address.equalsIgnoreCase("UsersInput/Difficulty0..5/Level1/Base-00-00-0000-000001.sudoku.xml"))
                {
 
                    unassignedVars = 0;

                    myProblem = SGACloop.loadProblem(LIBRARY_LOCATION + address);
                    consistencyAlgorithm myAlgorithm = new shavingGAC(myProblem, null);
                    

                    Iterator i = ((Collection)myProblem.getAllVariables()).iterator();
                    while(i.hasNext())
                    {
                        problemVariable currentVariable = (problemVariable)i.next();
                        if(!currentVariable.isAssigned())
                        {
                            unassignedVars++;
                        }
                    }

                    //System.out.println(unassignedVars);

                    myAlgorithm.runAlgorithm();
                    if(myAlgorithm.getVariableReductions().size() != (8*unassignedVars))
                    {
                        System.out.println(LIBRARY_LOCATION + address);
                    }
                    else
                    {
                        System.out.println(".");
                    }

                    System.gc();
                }
			//parentMenu.add(tempItem);
		    }
	    }
    }


    private static 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 static 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;
    }	
*/
}
