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

package rec.agent;

import javax.swing.*;
import java.awt.*;
import java.rmi.*;
import java.util.*;
import metaglue.*;
import rec.util.*;
import rec.ui.*;
import rec.sys.*;

public class SketchAgent extends AgentAgent implements Sketch
{

  RecSystem pad;
  GrammarHandler grammarHandler;

  Attribute full_screen = new Attribute( "full screen" );
  // constructor

  Attribute start_file = new Attribute( "start file" );

  /**
   * Constructs a new SketchAgent.
   **/
  public SketchAgent () throws RemoteException
  {
    try {
      System.err.println( "Making the actual system." );

      //log( "Full screen variable = \"" + full_screen.getValue() + "\"" );

      if ( full_screen.getValue().startsWith( "t" ) )
      {
	Toolkit tk = Toolkit.getDefaultToolkit();
	Dimension d = tk.getScreenSize();
	log( "Making a big sketch surface: " + d.width + "," + d.height );
	pad = new RecSystem( start_file.getValue(), d.width, d.height );
      }
      else
      {
	log( "Making a standard 800x600 pad for projection screen" );
	pad = new RecSystem( start_file.getValue(), 800, 600 );
      }

      SpeechToSketch sts = (SpeechToSketch)reliesOn( "rec.agent.SpeechToSketch" );

      // set the handler for grammars
      grammarHandler = sts;
      // set the engine in charge of dictation and speech out
      PhraseIO.setIO( new SpeechPhraseIO( sts ) );      

      RecGrammarManager.getTheManager( ).addGrammarHandler( grammarHandler );
      
      // start up the pad.
      pad.load();

      System.err.println( "Done with constructor of SketchAgent." );
    }
    catch ( Throwable th )
    {
      th.printStackTrace();
      System.exit( 1 );
    }
  }


  // methods
  public int takeGremlin( Gremlin g ) throws RemoteException
  {
    Console.writeln( "Beginning a tweak" );
    try
    {
      Console.indent();

      int resp = g.tweak( pad.getSurface() );
      ( pad.getSurface().getScreen() ).repaint();

      Console.writeln( "Tweak done." );
      Console.outdent();

      return resp;
    }
    catch ( Exception e )
    {
      e.printStackTrace();
      System.err.println( "....continue(takeGremlin())...." );
    }
    
    return 0;
  }

  public Id installModule( ModuleMaker mm ) throws RemoteException
  {
    Module m = mm.make( null );
    
    installModule( m );

    return m.getId();
  }

  public RemoteModule installModule( ModuleMaker mm,
				     AgentID parent )
  {
    try
    {
      ModuleListener ml = (ModuleListener)reliesOn( parent );

      return installModule( mm, ml );
    }
    catch (Exception e )
    {
      e.printStackTrace();
      System.err.println( "....continuing(installModule-id)...." );
    }

    return null;
  }

  public RemoteModule installModule( ModuleMaker mm,
				     ModuleListener parent )
    throws RemoteException
  {
    System.err.println( "Installing module with " + mm );
    RemoteModule rm = (RemoteModule) mm.make( parent );

    // install the module on the surface
    installModule( (Module)rm );

    // return the module (which will be stubified and the stub
    // will be the real thing handed off to the invoker.

    System.err.println( "Returning module handle: " + rm );
    return rm;
  }

  public void removeModule( Id module_id ) throws RemoteException
  {
    // remove module with id module_id from Surface.
    Module m = pad.getSurface().removeModule( module_id );
    if ( m == null )
      log( "ERROR--Could not remove module." );
    else
      log( "Module " + m + " removed" );
  }

  public Id installModule( Module m ) throws RemoteException
  {
    // add module to the surface.
    System.err.println( "Adding module." );
    pad.getSurface().addModule( m, EditModeManager.DEFAULT_MODE );

    return m.getId();
  }


  public void loadBase( String base_name )
  {
    Console.writeln( "loading a new ini module base." );
    pad.loadIniModule( base_name );
    Console.writeln( "Finished with this action." );
  }

  public void addUtterance( WUtterance utterance ) throws RemoteException
  {
    Console.writeln( "SketchAgent adding utterance to surface" );
    pad.getSurface( ).addUtterance( utterance );
  }

} // end of SketchAgent class
