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


public class nonBinaryIntensiveConstraint extends nonBinaryConstraint implements
		intensiveConstraint {

	private String key;
	private boolean isViolated;
	private graph matching;
	private graph constraintGraph;
	private List allNodes;
	//private constraintProblem myProblem;
	
	public nonBinaryIntensiveConstraint(String constraintScopeString,
			constraintProblem currentProblem, String constraintKey) {
		super(constraintScopeString, currentProblem);

		//parentProblem = currentProblem;
		matching = null;
		List constraintScope = new LinkedList();
		constraintScope = parseScope(constraintScopeString);
	
		currentProblem.addNonBinaryIntensiveConstraint(this, constraintKey);
	
		//tell the variables in the scope about this constraint
		for(int i=0; i<constraintScope.size(); i++)
		{
			((problemVariable)constraintScope.get(i)).addNonBinaryIntensiveConstraint(this);
		}
		
		allNodes = new LinkedList();
		int adjacencyMatrixIterator = 0;
		//create all the value nodes
		List domainValues = new LinkedList(currentProblem.getDomain().getDomainList());
		for(int i =0; i < domainValues.size(); i++)
		{
			allNodes.add(new graphNode((String)domainValues.get(i), adjacencyMatrixIterator));
			adjacencyMatrixIterator++;
		}
		
		//create all the variable nodes
		for(int i =0; i < constraintScope.size(); i++)
		{
			allNodes.add(new graphNode((problemVariable)constraintScope.get(i), adjacencyMatrixIterator));
			adjacencyMatrixIterator++;
		}
		
		//create the constraint graph which for now is zeroed out.
		constraintGraph = new graph(allNodes);
		
		isViolated = false;

	}
	
	//creates a current bidirectional bipartite graph of the values
	//and variables in the current problem that are contained in this constraint.
	//it builds it from scratch so that it does not take advantage of the fact that
	//few variable value combinations may of changed.
	//Returns a list of removed edges if any are removed, 
	//if none are removed it returns a list with 0 elements.
	//or null if there is an error.
	public List updateGraph()
	{
		constraintGraph.clear();
		List variableNodes = new LinkedList(constraintGraph.getVariableNodes());
		
		for(int variableIndex =0; variableIndex < variableNodes.size(); variableIndex++)
		{
			List variableValues = new LinkedList((((graphNode)variableNodes.get(variableIndex)).getVariable()).getEntireDomain());
			for(int valuableIndex=0; valuableIndex < variableValues.size(); valuableIndex++)
			{
				graphNode valueNode = constraintGraph.getValueNode((String)variableValues.get(valuableIndex));
				constraintGraph.addBidirectionalEdge(valueNode,(graphNode)variableNodes.get(variableIndex));
			}
		}
		
		matching = constraintGraph.computeMaximumMatching(null);
		if(matching.getAllFreeNodes().size() == 0)
		{
			return constraintGraph.reduceGraph(matching);
		}
		else
		{
			return null;
		}
	}

	public boolean isViolated()
	{
		if(constraintGraph.getAllFreeNodes().size() !=0)
		{
			return true;
		}
		
		return false;
	}
	
	public List getAllNodes()
	{
		return allNodes;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getKey() {
		return key;
	}
	
//	public void updateGraph()
//	{
//		this.getScope();
//	}
	
//	public boolean check(String value1, String value2)
//	{
//		if (value1.compareTo(value2) == 0)
//			return ( false );
//		return (true);
//	}

}
