// (c) MIT 2003.  All rights reserved.

package rec.house.speech;

import rec.agent.*;
import java.rmi.*;
import java.util.*;
import metaglue.*;
import rec.util.*;
import rec.sys.*;
import java.io.*;
import rec.house.*;

public class NameTrackerModule extends RemoteModuleImpl
    implements Registerable
{
  Hashtable nodes;

  //  Hashtable name_to_id;

  // last id tinkered with--can be asked for it.
  Id last_Id;

  Surface surf;

  public NameTrackerModule( ModuleListener parent ) throws RemoteException
  {
    super( parent );
    
    nodes = new Hashtable();
    //    name_to_id = new Hashtable();

    last_Id = null;

    System.err.println( "Constructed NameTracker connected to " + parent );
  }


  public boolean recognizeWidget( Surface s, Widget w )
  {
    // HACK TO GET HANDLE ON SURFACE--GRRRR....
    if ( surf == null )
      surf = s;

    //    if ( w instanceof Namable )
    if ( w instanceof Region )
      {
	last_Id = w.getId();

	if ( ! nodes.containsKey( w ) )
	  {
	    if ( ((Namable)w).getName() != null )
	      {
		nodes.put( w, ((Namable)w).getName() );
		tellPop( (Namable)w, true );
	      }
	    s.register( this, w );
	  }
      }

    return false;
  }


  private void tellPop( Namable w, boolean added )
  {
    String n = w.getName();

    tellPop( n, added );
  }

  private void tellPop( String name, boolean added )
  {
    try 
      {
	NameTracker n = new NameTracker( name, -1, added );

	System.err.println( "Telling pop new name " + n );
	parent.ring( n );
      }
    catch ( RemoteException e )
      {
	e.printStackTrace();
      }
  }

  public void removed( Widget w )
  {
    Console.writeln( "Seeing thing disappear." );
    nodes.remove( w );
    if ( ((Namable)w).getName() != null )
      tellPop( (Namable)w, false );
  }

  public void replaced( Widget ow, Widget nw )
  {
    //    last_Id = nw.getId();

    nodes.remove( ow );
    if ( ((Namable)ow).getName() != null )
      tellPop( (Namable)ow, false );

    if ( nw instanceof Namable )
      {
	Namable n = (Namable)nw;
	if ( n.getName() != null )
	  {
	    nodes.put( nw, n.getName() );
	    tellPop( (Namable)nw, true );
	  }
      }
    else
      surf.unregister( this, nw );
  }

  public void replaced( Widget ow, Collection nws )
  {
    Iterator it = nws.iterator();
    while( it.hasNext() )
      replaced( ow, (Widget)it.next() );
  }

  public void altered( Widget w, Transition t )
  {
    //    last_Id = w.getId();

    Namable n = (Namable)w;
    String name = (String)nodes.get( n );
    if ( ( name == null ) || !name.equals( n.getName() ) )
      {
	if ( name != null )
	  {
	    nodes.remove( w );
	    tellPop( n, false );
	  }
	if ( n.getName() != null )
	  {
	    nodes.put( n, n.getName() );
	    tellPop( n, true );
	  }
      }
  }


  /**
   * Return the Id of the last object hit by anything.
   */
  public Object query( Object q ) throws RemoteException
  {
    try 
      {
	if ( q != null )
	  {
	    String name = (String)q;
	    // find thing by name
	    Iterator it = surf.getWidgetsIterator();
	    while( it.hasNext() )
	      {
		Widget w = (Widget)it.next();
		if ( w instanceof Namable )
		  {
		    Namable nm = (Namable)w;
		    if ( name.equalsIgnoreCase( nm.getName() ) )
		      return w.getId();
		  }
	      }
	    return null;
	  }

	//	int v = ( (Integer)q ).intValue();

	return last_Id;
      }
    catch ( Exception e )
      {
	e.printStackTrace();
      }

    return null;
  }


}


