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

// -*-Mode: Java-*- 
// $Id: LatchAnnotation.java,v 1.2 2003/03/06 00:40:43 moltmans Exp $
// LatchAnnotation.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Mon Feb 28 13:24:25 2000> 
// Time-stamp: <2000-04-18 13:33:21 moltmans> 
package rec.annotate;

import java.util.*;
import rec.util.*;
import rec.sys.*;
import rec.core.widgets.*;
import rec.simulate.widgets.*;
import rec.annotate.widgets.*;
import rec.speech.*;

/**
 * This class is for storing information about latches and latching
 * behavior:
 *
 * A latch involves a body acting as the latch and a latchee which is
 * latched in place by the latch.
 **/
public class LatchAnnotation implements Annotation
{
  private LinkedList m_entities;
  private LinkedList m_sentences;
  private Entity m_latch;
  private Entity m_latchee;

  private AnnotationNotebook m_notebook;
  //  private LinkedList m_causalChain;

  public LatchAnnotation( Surface s )
  {
    m_notebook = s.getAnnotationNotebook();
    m_sentences = new LinkedList();
    m_latch = new Entity( m_notebook );
    m_latchee = new Entity( m_notebook );
  }

  public LatchAnnotation( AnnotationNotebook book, LinkedList sentences, 
			  Entity latch, Entity latchee )
  {
    m_notebook = book;
    m_sentences = new LinkedList( sentences );
    m_latch = (Entity)latch.clone();
    m_latchee = (Entity)latchee.clone();
  }
  
  public LatchAnnotation( Surface s, WSentence phrase )
  {
    this( s );
    m_sentences.add( phrase );
    m_latch.addName( phrase.getSubject() );

    String obj = phrase.getDirectObject();
    if ( obj != null ) {
      m_latchee.addName( obj );
    }
  }

  public WSimBody getLatch()
  {
    return (WSimBody)m_latch.getWidget();
  }

  public void setLatch( WSimBody latch )
  {
    m_latch.setWidget( latch );
  }

  /**
   * Get the latchee.
   **/
  public WSimBody getLatchee()
  {
    return (WSimBody)m_latchee.getWidget();
  }

  public void setLatchee( WSimBody latchee )
  {
    m_latchee.setWidget( latchee );
  }

  public String getLatchName()
  {
    return m_latch.getAName();
  }

  public void setLatchName( String name ) 
  {
    m_latch.addName( name );
  }

  public String getLatcheeName()
  {
    return m_latchee.getAName();
  }

  public void setLatcheeName( String name ) 
  {
    m_latchee.addName( name );
  }

  public LinkedList getEntities() 
  {
    if( m_entities == null ) {
      m_entities = new LinkedList();
      m_entities.add( m_latch );
      m_entities.add( m_latchee );
    }
    return new LinkedList( m_entities );
  }

  public LinkedList getSentences() 
  {
    return new LinkedList( m_sentences );
  }
    
  /**
   * This is called to assert knowledge into the notebook.
   **/
  public void updateNotebook()
  {
  }

  public void retractUpdate()
  {
  }

  public String describe() 
  {
    String result = "Latch:";

    result += "[" + m_latch + "]";
    
    if ( !m_latchee.isEmpty() ) {
      result += " latches the [" + m_latchee + "] in place";
    }

    return result;
  }

  public Annotation merge( Annotation a ) 
  {
    if ( a instanceof LatchAnnotation )
      return merge( (LatchAnnotation)a );
    else
      return null;
  }
  
  /**
   * Try to merge the two annotations.  If they cannot be merged
   * return null.
   **/
  public LatchAnnotation merge( LatchAnnotation m )
  {
    // check if temporaliy proximate...(how?)
    Entity latch = Entity.merge( m_latch, m.m_latch );
    Entity latchee = Entity.merge( m_latchee, m.m_latchee );

    if ( latch == null || latchee == null )
      return null;

    LinkedList sentences = getSentences();
    sentences.addAll( m.getSentences() );
    
    return new LatchAnnotation( m_notebook, sentences, latch, latchee );
  }

  public void setCause( Annotation a )
  {
    Assert.error( "Not yet implemented" );
  }
  public void setEffect( Annotation a )
  {
    Assert.error( "Not yet implemented" );
  }

  public Annotation getCause() 
  {
    return null;
  }
  public Annotation getEffect() 
  {
    return null;
  }

}
