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

// -*-Mode: Java-*- 
// $Id: WMSimPulley.java,v 1.8 2003/03/06 00:40:40 moltmans Exp $
// WMSimPulley.java -- 
// Author: Michael Oltmans <moltmans@ai.mit.edu> 
// Maintainer: Michael Oltmans <moltmans@ai.mit.edu> 
// Copyright: Copyright (C) 1999 by Michael Oltmans 
// Created: <Fri Oct 22 13:04:02 1999> 
// Time-stamp: <2001-09-10 18:28:59 moltmans> 
// Keywords: 
package rec.simulate.widgets.wm;

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

// class used when an interface to Working Model is desired.

public class WMSimPulley extends WSimPulley
{
  
    public WMSimPulley( List wheels, List ropes )
    {
	super( wheels, ropes );
    }
    
    // the key to this class is the load funciton, which "loads"
    // the object into the simulator.  that is, prints it to the 
    // file. it takes a WMSimulator so that it knows the conversion 
    // factors that it should use to convert dimensions.
    // it needs another parameter to resolve name conflicts.

    public String load( WMSimulatorRegistryBase reg ) 
    {
	String output;
	double length = 0;
	
	output = "Dim " + m_Name + " as WMConstraint\n";
	output += "redim p(" + Integer.toString( m_numWheels + 2 ) + ")\n";

	GPoint end1 = reg.convert( getFreeEnd1() );
	GPoint end2 = reg.convert( getFreeEnd2() );
	
	// thanks to our good friends at "Knowledge Revolution" the
	// coordinates for the endpoints must be specified relative to the
	// bodies they are attached to
	
	if ( m_EndBody1 != null ) {
	    GPoint body1 = reg.convert( m_EndBody1.getLocation().getCenter() );
	    end1.x -= body1.x;
	    end1.y -= body1.y;
	}

	if ( m_EndBody2 != null ) {
	    GPoint body2 = reg.convert( m_EndBody2.getLocation().getCenter() );
	    end2.x -= body2.x;
	    end2.y -= body2.y;
	}

	 output += "p(" + 1 + ").X = " + end1.x + "\n";
	 output += "p(" + 1 + ").Y = " + end1.y + "\n";
	 

	 GPoint tempPoint;
	 GPoint tempPointPrev = reg.convert(getFreeEnd1());
	 
	 for( int i=0; i<m_numWheels; i++ ) {
	     
	     tempPoint = reg.convert( getWheelN( i ).getCenter() );

	     length += Geometry.distance(tempPointPrev,
					 tempPoint);
	     
	     tempPointPrev = new GPoint(tempPoint);
   
	     if (m_PulleyBodies[i] != null){
		 GPoint b = reg.convert( m_PulleyBodies[i]
					 .getLocation()
					 .getCenter() );
		 tempPoint.x -= b.x;
		 tempPoint.y -= b.y;
	     }
	     
	     output += "p(" + (i+2) + ").X = " + tempPoint.x + "\n";
	     output += "p(" + (i+2) + ").Y = " + tempPoint.y + "\n";

    
	 }

	 length += Geometry.distance(reg.convert(getWheelN( m_numWheels - 1 )
				     .getCenter()),
				     reg.convert(getFreeEnd2()));

	 
	 int n = m_numWheels + 2;
	 output += "p(" + n + ").X = " + end2.x + "\n";
	 output += "p(" + n + ").Y = " + end2.y + "\n";
	  
	 
	 output += "Set " + m_Name + " = Draw_Pulley( " + n + ", p )\n";
	 output += m_Name + ".length.value = " 
	     + Math.max(length, reg.convert(m_ropesLength)) + "\n";

	 if ( m_EndBody1 != null ) {
	     output +=  "Set " + m_Name + ".Point(1).Body = " + 
		 m_EndBody1.getName() + "\n";
	 }
	 
	 for( int i=0; i<m_numWheels; i++ ) {
	 	     
	     if (m_PulleyBodies[i] != null){
		 output += ( "Set " + m_Name + ".Point(" + (i+2) + ").Body = " +
			     m_PulleyBodies[i].getName() + "\n" );
	     }	     
	 }
	 

	 if ( m_EndBody2 != null ) {
	     output += ( "Set " + m_Name + ".Point(" + n + ").Body = " +
			 m_EndBody2.getName() + "\n" );
	 }

	 return output;
    }
}






