// Draw a Rig. (Java 1.1 or later version)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.lang.String.*;
import java.lang.Double.*;

public class Rig extends Applet implements ActionListener
{

   TextField lOAField;
   TextField lODField;
   TextField lWLField;
   TextField freeboardField;
   TextField beam_locationField;
   TextField beamField;
   TextField mast_heightField;
   TextField mast_locationField;
   TextField boom_heightField;
   TextField boom_lengthField;

   String message = ""; // String containing system messages
   double lOA;		// LOA
   double lOD;		// LOD
   double lWL;		// LWL
   double freeboard;	// Freeboard
   double beam_location;// Percent forward of transom to max beam
   double beam;		// Beam
   double mast_height;	// Mast height
   double mast_location;// Percent forward of transom to mast
   double boom_height;	// Height of boom from deck
   double boom_length;	// Length of boom
   double scale = 2.5;	// Scale factor
   double pi = 3.14159;	// pI
   int side_x = 380;	// Start location for Side view
   int side_y = 350;
   int plan_x = 380;	// Start location for Plan view
   int plan_y = 380;

   public void init()
   {
	Label lOALabel = new Label( "LOA(ft): ", Label.RIGHT );
	Label lODLabel = new Label( "LOD(ft): ", Label.RIGHT );
	Label lWLLabel = new Label( "LWL(ft): ", Label.RIGHT );
	Label freeboardLabel = new Label( "Freeboard(ft): ", Label.RIGHT );
	Label beam_locationLabel = new Label( "Beam location(%): ", Label.RIGHT );
	Label beamLabel = new Label( "Beam(ft): ", Label.RIGHT );
	Label mast_heightLabel = new Label( "Mast height(ft): ", Label.RIGHT );
	Label mast_locationLabel = new Label( "Mast location(%): ", Label.RIGHT );
	Label boom_heightLabel = new Label( "Boom Height(ft): ", Label.RIGHT );
	Label boom_lengthLabel = new Label( "Boom Length(ft): ", Label.RIGHT );



	lOAField = new TextField( 4 );
	lODField = new TextField( 4 );
	lWLField = new TextField( 4 );
	freeboardField = new TextField( 4 );
	beam_locationField = new TextField( 4 );
	beamField = new TextField( 4 );
	mast_heightField = new TextField( 4 );
	mast_locationField = new TextField( 4 );
	boom_heightField = new TextField( 4 );
	boom_lengthField = new TextField( 4 );


	// Add controls
	add( lOALabel );
	add( lOAField );
	add( lODLabel );
	add( lODField );
	add( lWLLabel );
	add( lWLField );
	add( freeboardLabel );
	add( freeboardField );
	add( beam_locationLabel );
	add( beam_locationField );
	add( beamLabel );
	add( beamField );
	add( mast_heightLabel );
	add( mast_heightField );
	add( mast_locationLabel );
	add( mast_locationField );
	add( boom_heightLabel );
	add( boom_heightField );
	add( boom_lengthLabel );
	add( boom_lengthField );



	// Register ActionListeners to receive action events.
	lOAField.addActionListener( this );
	lODField.addActionListener( this );
	lWLField.addActionListener( this );
	freeboardField.addActionListener( this );
	beam_locationField.addActionListener( this );
	beamField.addActionListener( this );
	mast_heightField.addActionListener( this );
	mast_locationField.addActionListener( this );
	boom_heightField.addActionListener( this );
	boom_lengthField.addActionListener( this );



   }

   // ActionListeners.
   public void actionPerformed( ActionEvent ae )
   {
	repaint();
   }

   public void paint( Graphics g )
   {

	message = "";

	try
	{
		lOA = scale * 1 * (double)Long.parseLong( lOAField.getText() );
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"lOA\" field must contain a number: " + exceptionText;
		lOA = 0;
	}
	try
	{
		 lOD = scale * 1 * (double)Long.parseLong( lODField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"LOD\" field must contain a number: " + exceptionText;
		 lOD = 1.0;
	}
	try
	{
		 lWL = scale * 1 * (double)Long.parseLong( lWLField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"lWL\" field must contain a number: " + exceptionText;
		 lWL = 1.0;
	}
	try
	{
		 freeboard = scale * 1 * (double)Long.parseLong( freeboardField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"freeboard\" field must contain a number: " + exceptionText;
		 freeboard = 1.0;
	}
	try
	{
		 beam_location = .01 * (double)Long.parseLong( beam_locationField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"Beam Location\" field must contain a number: " + exceptionText;
		 beam_location = 1.0;
	}
	try
	{
		beam = scale * 1 * (double)Long.parseLong( beamField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"beam\" field must contain a number: " + exceptionText;
		beam = 1.0;
	}
	try
	{
		 mast_height = scale * 1 * (double)Long.parseLong( mast_heightField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"Mast Height\" field must contain a number: " + exceptionText;
		 mast_height = 1.0;
	}
	try
	{
		 mast_location= .01 * (double)Long.parseLong( mast_locationField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"Mast location\" field must contain a number: " + exceptionText;
		 mast_location= 1.0;
	}
	try
	{
		boom_height = scale * 1 * (double)Long.parseLong( boom_heightField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"Boom Height\" field must contain a number: " + exceptionText;
		 boom_height = 1.0;
	}
	try
	{
		boom_length = scale * 1 * (double)Long.parseLong( boom_lengthField.getText() );	
	}
	catch( NumberFormatException exceptionText )
	{
		message = "\"Boom Length\" field must contain a number: " + exceptionText;
		 boom_length = 1.0;
	}

	
	
	// Draw Rig
	// Draw Mast
	g.drawLine( (int)(side_x - lOD * mast_location), side_y, (int)(side_x - lOD * mast_location), (int)(side_y - mast_height) );
	// Draw Deck
	g.drawLine( (int)(side_x - lOD), side_y, side_x, side_y );
	// Draw Forestay
	g.drawLine( (int)(side_x - lOA), side_y, (int)(side_x - lOD * mast_location), (int)(side_y - mast_height) );
	// Draw Stays'l stay
	g.drawLine( (int)(side_x - lOD), side_y, (int)(side_x - lOD * mast_location), (int)(side_y - mast_height * .875) );
	// Draw Backstay
	g.drawLine( (int)(side_x - lOD * mast_location), (int)(side_y - mast_height), side_x, side_y );
	// Draw Boom
	g.drawLine( (int)(side_x - lOD * mast_location), (int)(side_y - boom_height), (int)(side_x - lOD * mast_location + boom_length), (int)(side_y - boom_height) );
	// Draw Toping Lift
	g.drawLine( (int)(side_x - lOD * mast_location), (int)(side_y - mast_height), (int)(side_x - lOD * mast_location + boom_length), (int)(side_y - boom_height) );


	// Draw Waterline
	g.drawLine( (int)(side_x - lOD * mast_location - lWL * (1 - mast_location)), (int)(side_y + freeboard), (int)(side_x - lOD * mast_location + lWL * mast_location), (int)(side_y + freeboard) );
	// Draw bow
	g.drawLine( (int)(side_x - lOD), side_y, (int)(side_x - lOD * mast_location - lWL * (1 - mast_location)), (int)(side_y + freeboard) );
	// Draw transom
	g.drawLine( side_x, side_y, (int)(side_x - lOD * mast_location + lWL * mast_location), (int)(side_y + freeboard) );
	// Draw bowsprit
	g.drawLine( (int)(side_x - lOA ), (int)(side_y), (int)(side_x - lOD), (int)(side_y) );


	// Draw Plan
	// Draw LOA
	g.drawLine( (int)(plan_x - lOA), plan_y, plan_x, plan_y );
	// Draw LOD
	g.drawLine( (int)(plan_x - lOD), plan_y, plan_x, plan_y );
	// Draw Beam
	g.drawLine( (int)(plan_x - lOA * beam_location), (int)(plan_y - beam * .5), (int)(plan_x - lOA * beam_location), (int)(plan_y + beam * .5) );


	g.drawString( "LOA(ft): " + lOA, 6 ,200 );
	g.drawString( "Beam(ft): " + beam, 6, 225 );

	g.drawString( "Message: " + message, 6, 325 );
   }

   // main() is the entry point when called as an application.
   // main() is not used when run as an applet.
   public static void main ( String args[] )
   {
	Frame mainWindow = new Frame ( "Rig" );
	Rig application = new Rig ();

	mainWindow.setSize ( 400, 400 );
	mainWindow.add ( "Center", application );
	mainWindow.show ();
	application.init();
   }

}
