package edu.unl.consystlab.sudokuSolver;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;

//import sun.jdbc.odbc.OdbcDef;


public class problemVariable
{

	private constraintProblem parentProblem;
	private String variableIndex;
	private String variableAssigned;
	private List variableInitialDomain;
	private List variableCurrentDomain;
	private List variableBinaryIntensiveConstraints;
	private List variableNonBinaryIntensiveConstraints;
	private List variableNonBinaryConstraints;
	private boolean boolAssigned;
	
	//private List variableNeighbors;

	//default constructor
	//not used.
	//public problemVariable()
	//{
	//
	//}

	public problemVariable(String name, constraintProblem parent)
	{
		parentProblem = parent;
		variableIndex = name;
		parent.addVariable(this);
		variableNonBinaryIntensiveConstraints = new LinkedList();
		variableBinaryIntensiveConstraints = new LinkedList();
		boolAssigned = false;
	}

	public boolean isPreassigned()
	{
		if(boolAssigned && variableInitialDomain.size() == 1)
		{
			return true;
		}
		return false;
	}
	
	public void setDomain(List newDomain)
	{
		variableInitialDomain = new LinkedList(newDomain) ;
		variableCurrentDomain = new LinkedList(newDomain) ;
		return;
	}
	
	public void setCurrentDomain(List newDomain)
	{
		variableCurrentDomain = new LinkedList(newDomain) ;
		return;
	}
	
	public List getInitialDomain()
	{
		return variableInitialDomain;
	}
	
	public List getEntireDomain()
	{
		return variableCurrentDomain;
	}
	
	public void addToCurrentDomain(String newDomainValue)
	{
		if(!variableCurrentDomain.contains(newDomainValue))
		{
			variableCurrentDomain.add(newDomainValue);	
		}
	}
	//overload it to take lists
	public void addToCurrentDomain(List newDomainList)
	{
		for(int i =0; i< newDomainList.size(); i++)
		{
			variableCurrentDomain.add((String)(newDomainList.get(i)));
		}
	}
	
	public void removeFromCurrentDomain(String oldDomainValue)
	{
		parentProblem.addDomainReduction(new variableIndexAndValueGrouping(this.getIndex(), oldDomainValue));
		variableCurrentDomain.remove(oldDomainValue);
	}
	public boolean isInCurrentDomain(String domainValue)
	{	
		if(variableCurrentDomain.contains(domainValue))
		{
			return true;
		}
		return false;
	}
	public int getCurrentDomainSize()
	{
		return( variableCurrentDomain.size());
	}
	public String getCurrentDomainFirstValue()
	{
		return((String)variableCurrentDomain.get(0));
	}
//	public String getCurrentDomainNextValue()
//	{
//		int currentIndex = variableCurrentDomain.indexOf(variableAssigned);
//		return((String)variableCurrentDomain.get(currentIndex+1));
//	}
	public boolean isLastValueInCurrentDomain()
	{
		int currentIndex = variableCurrentDomain.indexOf(variableAssigned);
		if( currentIndex == variableCurrentDomain.size()-1 )
		{
			return true;
		}
		else
			return false;
	}
	public void setAssigned(String newAssignment)
	{
		boolAssigned = true;
		variableAssigned = newAssignment;
		
		//fix the current domain to reflect this.
		//remove everything but the value that is assigned.
		List currentDomain = new LinkedList(this.getEntireDomain());
		while(currentDomain.size() > 0)
		{
			if( !((String)currentDomain.get(0)).equals((String)newAssignment) )
			{
				this.removeFromCurrentDomain((String)currentDomain.get(0));
			}
			currentDomain.remove(0);
		}
		
//		//this removes all the values from the domain.
//		variableCurrentDomain.clear();
//		
//		//this adds back the current assigned value.
//		variableCurrentDomain.add(newAssignment);
		
	}

	public void unSetAssigned()
	{
		boolAssigned = false;
		variableAssigned = null;		
	}
	
	public boolean isAssigned()
	{
		return(boolAssigned);
	}
	public String getAssigned()
	{
		return (variableAssigned);		
	}
	
	public void setDomain(String domainName)
	{
		variableInitialDomain = new LinkedList(parentProblem.getDomain(domainName).getDomainList());
		variableCurrentDomain = new LinkedList(parentProblem.getDomain(domainName).getDomainList());
		return;
	}

	public String getIndex()
	{
		return variableIndex;
	}

	public int getColumnIndex()
	{
		String[] variableIndexes;
		variableIndexes = variableIndex.split(",");
		return(Integer.parseInt(variableIndexes[0]));
	}
	public int getLineIndex()
	{
		String[] variableIndexes;
		variableIndexes = variableIndex.split(",");
		return(Integer.parseInt(variableIndexes[1]));
	}
	
	public String toString ()
	{
		//for(int i =0; i < variableInitialDomain.size(); i++)
		//{
		//	System.out.print(variableInitialDomain.get(i) + " ");
		//}
		//System.out.println("");
		//return "hi";
		return (variableAssigned);
	}
	
	public void addBinaryIntensiveConstraint(problemConstraint newConstraint)
	{
		variableBinaryIntensiveConstraints.add(newConstraint);
		return;
	}
	
	public void addNonBinaryIntensiveConstraint(problemConstraint newConstraint)
	{
		variableNonBinaryIntensiveConstraints.add(newConstraint);
		return;
	}

	public List getNonBinaryIntensiveConstraints()
	{
		return(variableNonBinaryIntensiveConstraints);
	}
	
	public List getBinaryConstraints()
	{
		return(variableBinaryIntensiveConstraints);
	}
}