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

// $Id: TransitionSuitcase.java,v 1.9 2003/03/06 00:40:39 moltmans Exp $
// Time-stamp: <2000-03-11 18:59:36 moltmans>
package rec.sys;



import java.util.*;
import rec.util.*;

/* Suitcases are an all or nothing list of transitions.  They can be built
 * onto as long as they are not active (i.e. have not been executed)  
 * All transitions must be done and undone in a single shot.
 */
public class TransitionSuitcase
{
  /* A list of transitions to be taken at some future point.
   * Unlike a recorder, transitions are put in here for future execution
   */
  private Vector m_DoList;       // list of transitions to be taken
  private int m_Index; 
  private boolean m_Open;

  public TransitionSuitcase()
  {
    m_DoList = new Vector();
    m_Index = 0;
    m_Open = false;
  }

  /////////////////////////////////////////////////////////////////////////////

  /* Gets the actions in the suitcase, but does not actually perform them
   */
  public Vector getActions()
  {
    Vector acts = new Vector();

    // we don't want to give the caller the ability to actually perform
    // any actions
    if ( m_DoList.size() <= 0 ) {
      return acts;
    }

    for ( int i = 0; i < m_DoList.size(); i++ ) {
      acts.add( ((DoTransition)m_DoList.elementAt( i )).getAction() );
    }

    return acts;
  }

  /** Execute all the actions in the suitcase, if it has not already been 
   * executed 
   */
  public void unpack()
  {
    if ( m_Open ) {
      Assert.note( "Attempt to unpack open suitcase" );
      return;
    }
    
    m_Open = true;

    if ( m_Index >= m_DoList.size() + 1 ) {
      Console.writeln( "nothing to execute in Suitcase" );
      return;
    }
    else {
      while ( m_Index < m_DoList.size() )  {
	DoTransition t = (DoTransition)m_DoList.elementAt( m_Index );
	Console.writeln( "****unpacking: " + t );
	t.doDo();
	m_Index += 1;
      }
    }
  }

  /* run undo on all the actions in the suitcase */
  public void repack()
  {
    if ( !m_Open ) {
      Assert.note( "Attempt to repack unopened suitcase" );
      return;
    }

    m_Open = false;

    if ( m_Index <= 0 ) {
      Console.writeln( "Nothing to put back into Suitcase" );
      return;
    }

    else {
      while ( m_Index > 0 ) {
	m_Index -= 1;
	DoTransition t = (DoTransition)m_DoList.elementAt( m_Index );
	Console.writeln( "****packing: " + t );	
	t.doUndo();
      }
    }
  }

  public void addTransitionToBeginning( DoTransition t )
  {
    // only add transitions when the suitcase is closed
    Assert.check( !m_Open, "Cannot add actions to open suitcase" );

    m_DoList.insertElementAt( t, 0 );
  }
  
    
  
  /* add a transition to the suitcase */
  public void addTransition( DoTransition t )
  {
    // only add transitions when the suitcase is closed
    Assert.check( !m_Open, "Cannot add actions to open suitcase" );

    m_DoList.add( t );
  }

  public boolean isOpen() 
  {
    return m_Open;
  }

}

