package prolog.implementation;

import java.io.*;
import java.util.*;
import prolog.model.*;
import prolog.util.*;

/**
 * <p>A ConstraintStatement is a expression to query. It has only one child,
 * the most top statement in the expression tree</p>

 */
public class ConstraintStatement
	extends
		AbstractStatement
	implements
		IStatement
{
	/**
	 * the one and only child
	 */
	protected IStatement expression = null;

	/**
	 * constructor
	 */
	public ConstraintStatement( int name )
	{
		super( name );
	}

	/**
	 * constructor 2
	 */
	public ConstraintStatement( int name, IRelation r )
	{
		super( name, r );
	}

	/**
	 * sets the child expression node
	 */
	public void setExpression( IStatement s )
	{
		expression = s;
	}

	/**
	 * querries the most top expression statement
	 * @param f - the fact to search for
	 * @param l - the fact database
	 * @param constraints - the statements to resolve unfound facts
	 * @return all relations matching the given fact
	 * @throws ParameterMatchingError
	 */
	public IFactList query( IFact f, IFactDb l, IStatementMap constraints )
		throws ParameterMatchingError
	{
		Map thisRelationFormat = getRelation().buildMap();
		return
			expression.query(
				generateFact(
					f,
					thisRelationFormat,
					expression ),
				l,
				constraints );
	}

	/**
	 * @return a string representation of this class
	 */
	public String toString()
	{
		return toString( null );
	}

	/**
	 * @param table is the ISymbolTable to decode the symbols
	 * @return a string representation of this object with decoded symbols
	 */
	public String toString( ISymbolTable table )
	{
		String back = super.toString( table );
		back += ":-";
		if( table != null )
			back += expression.toString( table );
		else
			back += expression.toString();
		return back;
	}

	/**
	 * generates a xml representation
	 * @param out is the writer to append the xml
	 * @param table is the symboltable too decode symbols
	 * @throws IOException
	 */
	public void genXml( Writer out, ISymbolTable table )
		throws IOException
	{
		out.write( "<fact class=\"" );
		out.write( getClass().getName() );
		out.write( "\">" );
		out.write( "<name>" );
		if( table != null )
			out.write( table.decode( getName() ) );
		else
			out.write( getName() );
		out.write( "</name>" );

		out.write( "<parameters>" );
		Iterator i = getRelation().getValues();
		while( i.hasNext() )
		{
			out.write( "<parameter>" );
			if( table != null )
				out.write( table.decode( (IAtom)i.next() ) );
			else
				out.write( i.next().toString() );
			out.write( "</parameter>" );
		}
		out.write( "</parameters>" );

		expression.genXml( out, table );

		out.write( "</fact>" );
	}
}
