package prolog.implementation;

import java.io.*;
import java.util.*;

import prolog.model.*;

/**
 * <p>A query list stores statementtrees having a Query as root</p>
 * <p>prolog:</p>
 * <p>?-myQuery1(X,Y):-superman1(Y,X),superwomen1(X,Y).</p>
 * <p>?-myQuery2(X,Y):-superman2(Y,X),superwomen2(X,Y).</p>
 * <p>In this example, the two queries "myQuery1" and "myQuery2" are
 * stored in a querylist</p>
 *
 */
public class QueryList
	implements
		IQueryList
{
	/**
	 * list of IQueryListListeners
	 */
	protected List listeners = new ArrayList( 0 );

	/**
	 * the list storing the queries
	 */
	protected List queries = new ArrayList(0);

	/**
	 * constructor
	 */
	public QueryList()
	{
	}

	/**
	 * clears this query list
	 */
	public void clear()
	{
		queries.clear();
		fireChange();
	}

	/**
	 * returns a iterator over all stored queries
	 */
	public Iterator getQueries()
	{
		return queries.iterator();
	}

	/**
	 * adds the given query to the fact list
	 */
	public void addQuery( IFact f )
	{
		queries.add( f );
		fireChange();
	}

	/**
	 * returns a string representation of this class
	 */
	public String toString( ISymbolTable table )
	{
		StringBuffer back = new StringBuffer();
		Iterator i = getQueries();
		back.append( "querylist:\n" );
		while( i.hasNext() )
		{
			back.append( "\t" );
			back.append( ((IFact)i.next()).toString( table ) );
			if( i.hasNext() )
				back.append( "\n" );
		}
		return back.toString();
	}

	/**
	 * generates xml describing this object
	 * @param out the writer to append the xml
	 * @param table the symboltable to decode the symbols
	 * @throws IOException
	 */
	public void genXml( Writer out, ISymbolTable table )
	   throws IOException
	{
		out.write( "<querylist>" );
		Iterator i=getQueries();
		while( i.hasNext() )
		{
			IFact f = (IFact)i.next();
			f.genXml( out, table );
		}
		out.write( "</querylist>" );
	}

	/**
	 * registers a listener
	 */
	public void addListener( IQueryListListener l )
	{
		listeners.add( l );
	}

	/**
	 * unregisters a listener
	 */
	public void removeListener( IQueryListListener l )
	{
		listeners.remove( l );
	}

	/**
	 * fires a content changed notify
	 */
	protected void fireChange()
	{
		Iterator i = listeners.iterator();
		while( i.hasNext() )
			((IQueryListListener)i.next()).onQueriesChanged();
	}
}
