/**
 * Programmer Name: Ross Winters
 * Date: 6/20/01 copyright, all rights reserved.
 * Course: Renegade web site
 * Program Name: bcApplet
 * Program Description: Applet program to calculate ballistic coefficient 
 *  for rifle and pistol (type G1) projectiles.
 *
 * From: American Rifleman, March 1989 by William C. Davis Jr.
 * Units: Barometric Pressure(BP): inches Hg, Temperature(TF): Fahrenheit, Relative Humidity(RH): percent
 *  Velocity(v1,v2,SU,SV): feet per second, Range(r1,r2): yard
 */
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.NumberFormat;

public class bcapplet extends Applet implements ActionListener, MouseListener
{
private double v1,r1,v2,r2,bp,tf,rh;
private double SU,SV,AS,BS,U,V,VB,CS,A,RO;

private Button enterButton = new Button("Calculate");
private Button closeButton = new Button("Close");
private TextField v1Entry = new TextField(12);
private TextField r1Entry = new TextField(12);
private TextField v2Entry = new TextField(12);
private TextField r2Entry = new TextField(12);
private TextField tfEntry = new TextField(12);
private TextField bpEntry = new TextField(12);
private TextField rhEntry = new TextField(12);
private TextField resultField = new TextField(12);

private Label v1Label = new Label("Velocity1 [feet/sec.]");
private Label r1Label = new Label("Range1 [yards]");
private Label v2Label = new Label("Velocity2 [feet/sec.]");
private Label r2Label = new Label("Range2 [yards]");
private Label tfLabel = new Label("Temperature [Fahrenheit]");
private Label bpLabel = new Label("Barometric Pressure [in.Hg]");
private Label rhLabel = new Label("Relative Humidity [%]");
private Label promptLabel1 = new Label("    Calculate Bullet Ballistic Coefficient");
private Label promptLabel2 = new Label("        Enter 2 velocities at 2 ranges.");
private Label resultLabel = new Label("Ballistic Coefficient");

    public static void main (String args[]) {
	Frame appletFrame = new Frame("Ballistic Coefficient");
	Applet myApplet = new bcapplet();
	myApplet.init();
	myApplet.start();
	//	appletFrame.setLayout(null);
	appletFrame.add(myApplet);
	//	appletFrame.resize(350,400);
	appletFrame.show();
    } // main

  public void init()
  {
  setLayout(null); // Use absloute x,y,w,h layout.

  promptLabel1.setBounds(10,10,390,25); // Place and size the components.
  promptLabel2.setBounds(10,35,390,25);
  v1Entry.setBounds(200,70,100,25);
  r1Entry.setBounds(200,100,100,25);
  v2Entry.setBounds(200,130,100,25);
  r2Entry.setBounds(200,160,100,25);
  tfEntry.setBounds(200,190,100,25);
  bpEntry.setBounds(200,220,100,25);
  rhEntry.setBounds(200,250,100,25);

  v1Label.setBounds(10,70,190,25);
  r1Label.setBounds(10,100,190,25);
  v2Label.setBounds(10,130,190,25);
  r2Label.setBounds(10,160,190,25);
  tfLabel.setBounds(10,190,190,25);
  bpLabel.setBounds(10,220,190,25);
  rhLabel.setBounds(10,250,190,25);
  resultLabel.setBounds(10,300,150,25);
  resultField.setBounds(200,300,100,25);
  enterButton.setBounds(140,350,70,30);

  enterButton.setBackground(Color.lightGray); // Set the Button background color.

  add(promptLabel1); // add the Components.
  add(promptLabel2);
  add(enterButton);
  add(v1Entry); v1=0;  v1Entry.setText(String.valueOf(v1));
  add(r1Entry); r1=0;  r1Entry.setText(String.valueOf(r1));
  add(v2Entry); v2=0;  v2Entry.setText(String.valueOf(v2));
  add(r2Entry); r2=0;  r2Entry.setText(String.valueOf(r2));
  add(tfEntry); tf=50; tfEntry.setText(String.valueOf(tf));
  add(bpEntry); bp=32; bpEntry.setText(String.valueOf(bp));
  add(rhEntry); rh=50; rhEntry.setText(String.valueOf(rh));
  add(v1Label);
  add(r1Label);
  add(v2Label);
  add(r2Label);
  add(tfLabel);
  add(bpLabel);
  add(rhLabel);
  add(resultLabel);
  add(resultField);

  enterButton.addMouseListener(this); // add the mouse listeners.
  enterButton.addActionListener(this); // add the action listeners.

  setBackground(new Color(255,208,64));
  setSize(350,400);
  } // init()

public void actionPerformed(ActionEvent e)
  {
      NumberFormat bc = NumberFormat.getInstance();
      bc.setMaximumFractionDigits(6);

      if (e.getSource() == enterButton) {    // || e.getSource() == valueEntry) {
	  v1=Double.valueOf(v1Entry.getText()).doubleValue();
	  r1=Double.valueOf(r1Entry.getText()).doubleValue();
	  v2=Double.valueOf(v2Entry.getText()).doubleValue();
	  r2=Double.valueOf(r2Entry.getText()).doubleValue();
	  tf=Double.valueOf(tfEntry.getText()).doubleValue();
	  bp=Double.valueOf(bpEntry.getText()).doubleValue();
	  rh=Double.valueOf(rhEntry.getText()).doubleValue();
	  // Check the input value ranges and make sure the bullet doesn't speed up.
	  if (v1 < 300.0 || v1 > 4500.0 || v2 < 300.0 || v2 > 4500.0 || r1 < 0.0 || r2 < 0.0 || (v1 < v2 && r1 < r2) || (v1 > v2 && r1 > r2) || bp < 5.0 || bp > 50.0 || tf < -20.0 || tf > 120.0 || rh < 5.0 || rh > 100.0)
	      resultField.setText("Range Error!");
	  else resultField.setText(bc.format(doBC(v1,r1,v2,r2,tf,bp,rh)));

      }

  doLayout();
  } // actionPerformed


public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}

public void mouseEntered(MouseEvent e)
  {
   if (e.getComponent() == enterButton)
     enterButton.requestFocus();
  } // mouseEntered

private double doBC(double V1, double R1, double V2, double R2, double TF, double BP, double RH)
{
double vTemp, rTemp;

// Exchange values if they're entered backwards.
 if ((V1 < V2) && (R1 > R2)) {
     vTemp = V1; rTemp = R1;
     V1 = V2; R1 = R2;
     V2 = vTemp; R2 = vTemp;
 }

 RO = (1.1357*BP/(29.5275+0.065092*TF))-(0.06577*RH*Math.exp(0.03288*TF-2.6538)/(4598.67+TF));
 A = Math.sqrt((459.67+TF)/518.67);
 doTable(V1/A);
 SV=AS+BS*(V1-VB)+CS*Math.pow(V1-VB,2);
 doTable(V2/A);
 SU=AS+BS*(V2-VB)+CS*Math.pow(V2-VB,2);
 return ((RO*3*(R2-R1))/(SU-SV));
}


private void doTable(double F)
     {
	 if (F >= 300  && F <  400) {VB= 350; AS=  396631; BS=  -63.768; CS=  0.0758391;}
	 if (F >= 400  && F <  500) {VB= 450; AS=  339581; BS=  -51.756; CS=  0.0473157;}
	 if (F >= 500  && F <  600) {VB= 550; AS= 29218.7; BS=   -43.64; CS=   0.035161;}
	 if (F >= 600  && F <  700) {VB= 650; AS=   25192; BS=  -37.095; CS=  0.0311391;}
	 if (F >= 700  && F <  800) {VB= 750; AS=   21792; BS=  -30.896; CS=  0.0313196;}
	 if (F >= 800  && F <  900) {VB= 850; AS= 19020.1; BS= -24.4588; CS=   0.033030;}
	 if (F >= 900  && F < 1000) {VB= 950; AS= 16906.5; BS= -17.8388; CS=  0.0325134;}
	 if (F >= 1000 && F < 1050) {VB=1025; AS= 15747.2; BS= -13.2423; CS=  0.0276581;}
	 if (F >= 1050 && F < 1075) {VB=1062; AS= 15288.1; BS= -11.3183; CS=   0.023346;}
	 if (F >= 1075 && F < 1100) {VB=1087; AS= 15019.2; BS= -10.2383; CS=  0.0199585;}
	 if (F >= 1100 && F < 1110) {VB=1105; AS=   14846; BS= -9.58136; CS=  0.0164795;}
	 if (F >= 1110 && F < 1120) {VB=1115; AS= 14751.9; BS=-9.231361; CS=  0.0165939;}
	 if (F >= 1120 && F < 1130) {VB=1125; AS= 14661.2; BS= -8.90021; CS=  0.0147629;}
	 if (F >= 1130 && F < 1150) {VB=1140; AS= 14530.6; BS=-8.482001; CS=  0.0116909;}
	 if (F >= 1150 && F < 1250) {VB=1200; AS= 14062.5; BS=  -7.2568; CS=     0.0085;}
	 if (F >= 1250 && F < 1500) {VB=1375; AS= 12977.5; BS=  -5.5464; CS= 0.00306207;}
	 if (F >= 1500 && F < 2000) {VB=1750; AS= 11189.1; BS= -4.31589; CS=0.000960342;}
	 if (F >= 2000 && F < 2500) {VB=2250; AS=9222.059; BS= -3.66916; CS= 0.00045401;}
	 if (F >= 2500 && F < 3000) {VB=2750; AS= 7492.73; BS= -3.26733; CS=  0.0003714;}
	 if (F >= 3000 && F < 3500) {VB=3250; AS= 5950.45; BS= -2.90704; CS=0.000348885;}
	 if (F >= 3500 && F < 4000) {VB=3750; AS= 4582.38; BS= -2.57414; CS=0.000310524;}
	 if (F >= 4000 && F < 4500) {VB=4250; AS= 3369.09; BS= -2.29123; CS=0.000257709;}
     }

} // class

