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

// -*-Mode: Java-*- 
// WMSimulatorReg.java -- 
// Author: Christine Alvarado <calvarad@ai.mit.edu> 
// Maintainer: Christine Alvarado <calvarad@ai.mit.edu> 
// Version: 
// Created: <Thu Mar 18 12:10:44 1999> 
// Time-stamp: <2002-04-10 17:53:49 moltmans> 
// Keywords: 
package rec.simulate;

import java.util.*;
import rec.util.*;
import java.io.*;
import rec.sys.*;
import rec.geo.*;
import rec.core.widgets.*;
import java.lang.*;
import rec.simulate.widgets.*;

// based on SimulateRegistry.  Has all the funcitonality of the Simulate Reg
// but it can also print out to a WM file.
public class WMSimulatorRegistry extends WMSimulatorRegistryBase
{
  // the conversion factor between pixels and WM units
  int converter = 80;
  
  public WMSimulatorRegistry( String filename )
  {
    super( );
    m_filename = filename;
        
  }


  // load all the header, then all the simulatable objects then the footer
  // into the WM file.
  public void load( Surface s )
  {
    // open and close the file here so we get the pointer to the beginning
    // in the future just open to append the file.
    try {
      m_output = new PrintWriter( new FileWriter( m_filename ), true );
    }      
    catch( IOException e ) {
      System.out.println( e );
      Assert.error("Error loading surface in WMSimulatorRegistry");
    }
       
    
    Console.writeln( "loading..." );
    // print the header stuff to the file
    printHeader();
    
    // step through the widgets on the surface.  For each visible widget 
    // which is on the surface and also in this registry, print it to 
    // the file.
    // for now the base simulatable class is WSimBody.  This only
    // handles polygons.  Obviously i will need to abstract one more time
    // in the future.
    Iterator it = s.getWidgetsIterator();
    while ( it.hasNext() ) {
      Console.writeln("Looking for visible widgets");
      Widget w = (Widget)it.next();
      // check to see if we have this one
      String object_message;
      if ( w instanceof WSimObject ) {
	object_message = ((WSimObject)w).load( this );
	m_output.println( object_message );
	Console.writeln( "loading simulatable widget... " );
      }
      
      
    }
    
    // print the footer stuff to the file
    printFooter();
    
    m_output.close();
  }

 

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

  // there are some variable name issues to consider here, like the name 
  // of the doccument, and the names of any objects created.  They should
  // all be controlled by this function, and passed in to the loading
  // function.  Also, when we start loading libraries to handle more 
  // complex shapes (that is, WMBasic libraries which already exist), into
  // the file that we are creating we will need to somehow keep track of 
  // them to be used at the beginning of printHeader()
  private void loadTypes()
  {
    // point type
    m_output.println( "Type point" );
    m_output.println( "X as double" );
    m_output.println( "Y as double" );
    m_output.println( "end Type" );
  }

  private void loadVariables()
  {
    m_output.println( "Dim center as point" );
    m_output.println( "Dim p() as point" );
    m_output.println( "Dim t1 as point" );
    m_output.println( "Dim t2 as point" );
  }
  
  private void loadLibs()
  {
    m_output.println( "WM.LoadWMBLibrary \".\\wmbasic\\draw_bodies.wbs\"" );
    m_output.println( "WM.LoadWMBLibrary \".\\wmbasic\\draw_constraints.wbs\"" );
  }
  
  private void unloadLibs()
  {
    m_output.println( "WM.UnloadWMBLibrary \".\\wmbasic\\draw_bodies.wbs\"" );
    m_output.println( "WM.UnloadWMBLibrary \".\\wmbasic\\draw_constraints.wbs\"" );
  }

  private void loadDeclare()
  {
    m_output.println( "Declare function Draw_Rect(h, w, c as point)" );
    m_output.println( "Declare function Draw_Poly(n, p() as point, c as point)" );
    m_output.println( "Declare function Draw_Spring(l as point, r as point)" );
    m_output.println( "Declare function Draw_Damper(l as point, r as point)" );
    m_output.println( "Declare function Draw_SpringDamper(l as point, r as point)");
    m_output.println( "Declare function Draw_Circle(r, c as point)" );
    m_output.println( "Declare function Draw_Force(c as point, fx, fy)" );
  }

  private void printHeader()
  {
    
    loadTypes();
    loadDeclare();
    
    Console.writeln( "writing to file" );
    m_output.println("Sub Main()");
    if ( m_output.checkError() )
      Console.writeln( "error occured writing to file" );
    
    loadLibs();

    m_output.println("dim doc as WMDocument");
    m_output.println("set doc = WM.ActiveDocument");

    // clear everything
    m_output.println("doc.SelectAll");
    m_output.println("doc.Delete");

    // declare variables
    loadVariables();
    
    // set gravity appropriately 
    if ( !m_gravity ) {
      m_output.println("doc.gravity = \"none\"");
    } 
  }

  private void printFooter()
  {
    m_output.println("doc.SelectAll False");
    unloadLibs();
    m_output.println("end Sub");

  }
  
  public void shutdown() 
  {
  }
  

  private String m_filename;
  private PrintWriter m_output;

}
