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

// -*-Mode: Java-*- 
// $Id: Annotation.java,v 1.6 2003/03/06 00:40:49 moltmans Exp $
// Anotation.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Created: <Tue Aug 24 13:38:02 1999> 
// Time-stamp: <2000-07-20 23:25:55 moltmans> 
package rec.annotate.facts;

import java.util.*;
import rec.tms.Fact;
import rec.annotate.*;
import rec.annotate.rules.*;

/**
 * The root interface that all Annotations must implement
 **/
public abstract class Annotation implements Fact, Interval
{
  /* Methods from Fact:
   *   public String getFactType();
   *   public boolean sameFact( Fact fact );
   */

  private long m_startTime;
  private long m_endTime;

  public Annotation( long start, long end ) 
  {
    m_startTime = start;
    m_endTime = end;
  }
  
  public long getStartTime() 
  {
    return m_startTime;
  }
  
  public long getEndTime() 
  {
    return m_endTime;
  }

  /** implements sameFact instead of equals **/
  public final boolean equals( Object o ) 
  {
    return ( (o instanceof Annotation) &&
	     sameFact( (Annotation)o ) );
  }
  

  /** @return true if a <= test <= b **/
  private boolean isBetween( long test, long min, long max )
  {
    return (test >= min) && (test <= max );
  }
  
  public boolean doesTimeOverlap( Annotation a ) 
  {
    return ( isBetween( a.getEndTime(),
			getStartTime(), getEndTime() ) ||
	     isBetween( a.getStartTime(),
			getStartTime(), getEndTime() ) );
  }

  ////////////////////////////////////////////////////////////////////
  // methods that compute the appropriate start and end times from a
  // collection of annotations
  
  public static long getMinTime( Collection annotations ) 
  {
    long minTime = Long.MAX_VALUE;
    Iterator it = annotations.iterator();
    while( it.hasNext() ) {
      Annotation a = (Annotation)it.next();
      minTime = Math.min( minTime, a.getStartTime() );
    }
    return minTime;
  }

  public static long getMaxTime( Collection annotations ) 
  {
    long maxTime = Long.MIN_VALUE;
    Iterator it = annotations.iterator();
    while( it.hasNext() ) {
      Annotation a = (Annotation)it.next();
      maxTime = Math.max( maxTime, a.getEndTime() );
    }
    return maxTime;
  }

  /**
   * Check if the two collections of annotations are equivalent
   * according to sameFact.
   **/
  public static boolean sameFacts( Collection c1,
				   Collection c2 )
  {
    if( c1.size() != c2.size() )
      return false;
    
    Iterator it = c1.iterator();
    LinkedList annotations = new LinkedList( c2 );
    while( it.hasNext() ) {
      Annotation a = (Annotation)it.next();
      Iterator inner = annotations.iterator();
      boolean found = false;
      while( inner.hasNext() && !found ) {
	Annotation a2 = (Annotation)inner.next();
	if( a2.sameFact( a ) ) {
	  found = true;
	  inner.remove();
	}
      }
      if( !found )
	return false;
    }
    return true;
  }
}

    
