//(C)2000 Heitor Chang
//"Conversion Calculator" converts between several SI and British units of measurement

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class ConvCalc extends Applet implements ActionListener, ItemListener {

    //radio Panel includes all radio buttons
    //field Panel includes text fields and the Convert button
    private Panel radio, field;
    private TextField input, output;
    private Button convert;
    private Label toLabel, status, copyright; 
    //declaration of the seven types of units implemented
    private Checkbox area, energy, pressure, length, velocity, volume, weight;
    private CheckboxGroup units;
    //array of ratio/factors between units
    private double factor[];
    //drop-down of all units available for each category of measurement
    private Choice inputChoice, outputChoice;

    public void init() {
	super.init();
	this.setLayout(null);
	this.setBackground(new Color(238, 238, 204));

	radio = new Panel(new FlowLayout());
	//field Panel Grid of 2 rows by 3 columns
	field = new Panel(new GridLayout(2, 3, 5, 10));

	input = new TextField("1", 10);
	output = new TextField(10);
	convert = new Button("Convert >>");
	toLabel = new Label("to", Label.CENTER);
	status = new Label();
	copyright = new Label("(C)2000 Heitor Chang");

	output.setEditable(false);

	units = new CheckboxGroup();

	area = new Checkbox("Area", units, false);
	energy = new Checkbox("Energy", units, false);
	length = new Checkbox("Length", units, true);
	pressure = new Checkbox("Pressure", units, false);
	velocity = new Checkbox("Velocity", units, false);
	volume = new Checkbox("Volume", units, false);
	weight = new Checkbox("Weight", units, false);

	//add parts to event listeners
	convert.addActionListener(this);
	area.addItemListener(this);
	energy.addItemListener(this);
	length.addItemListener(this);
	pressure.addItemListener(this);
	velocity.addItemListener(this);
	volume.addItemListener(this);
	weight.addItemListener(this);

	inputChoice = new Choice();
	outputChoice = new Choice();

	inputChoice.setFont(new Font("Courier", Font.PLAIN, 12));
	outputChoice.setFont(new Font("Courier", Font.PLAIN, 12));
	
	//set the default Choice lists to 'length'
	factor = lengthFactor();
	inputChoice.add("US: inches");
	inputChoice.add("US: feet");
	inputChoice.add("US: yards");
	inputChoice.add("US: miles");
	inputChoice.add("SI: millimeters");
	inputChoice.add("SI: centimeters");
	inputChoice.add("SI: meters");
	inputChoice.add("SI: kilometers");
	
	outputChoice.add("US: inches");
	outputChoice.add("US: feet");
	outputChoice.add("US: yards");
	outputChoice.add("US: miles");
	outputChoice.add("SI: millimeters");
	outputChoice.add("SI: centimeters");
	outputChoice.add("SI: meters");
	outputChoice.add("SI: kilometers");

	//add Checkboxes to their panels
	radio.add(area);
	radio.add(energy);
	radio.add(length);
	radio.add(pressure);
	radio.add(velocity);
	radio.add(volume);
	radio.add(weight);

	field.add(input);
	field.add(convert);
	field.add(output);
	field.add(inputChoice);
	field.add(toLabel);
	field.add(outputChoice);

	//set coordinates manually
	radio.setBounds(10, 50, 580, 70);
	field.setBounds(50, 125, 500, 66);
	status.setBounds(50, 200, 250, 30);
	copyright.setBounds(393, 200, 250, 30);

	//add Panels and Labels to the applet
	this.add(radio);
	this.add(field);
	this.add(status);
	this.add(copyright);
    }

    public void actionPerformed(ActionEvent e) {
	try { 
	    //obtain the base input value
	    String baseStr = input.getText();
	    //since Double.parseDouble is not supported on the Netscape Java VM...
	    Double baseRaw = new Double(baseStr);
	    double base = baseRaw.doubleValue();
	    
	    //get index of selected units and assign them the respective ratio factor on the factor[] array.
	    int inputIndex = inputChoice.getSelectedIndex();
	    int outputIndex = outputChoice.getSelectedIndex();
	    double inputFactor = factor[inputIndex];
	    double outputFactor = factor[outputIndex];
	    
	    //convert the input
	    double factor = inputFactor / outputFactor;
	    double converted = base * factor;
	    output.setText("" + converted);
	    status.setText("");
	}
	//check for valid input (numbers)
	catch (NumberFormatException nfe) {
	    status.setText("Input must be a number.");
	    input.setText("");
	}
    }

    public void itemStateChanged(ItemEvent e) {
	//check for selected radio button
	Checkbox cb = (Checkbox)(e.getItemSelectable());
	output.setText("");
	inputChoice.removeAll();
	outputChoice.removeAll();
	//assign Choice values depending on selected Checkbox
	if (cb == area) {
	    //assign appropriate factors
	    factor = areaFactor();
	    
	    inputChoice.add("US: sq. inches");
	    inputChoice.add("US: sq. feet");
	    inputChoice.add("US: sq. yards");
	    inputChoice.add("US: sq. miles");
	    inputChoice.add("SI: sq. centimeters");
	    inputChoice.add("SI: sq. meters");
	    inputChoice.add("SI: acre");
	    inputChoice.add("SI: sq. kilometers");
	    
	    outputChoice.add("US: sq. inches");
	    outputChoice.add("US: sq. feet");
	    outputChoice.add("US: sq. yards");
	    outputChoice.add("US: sq. miles");
	    outputChoice.add("SI: sq. centimeters");
	    outputChoice.add("SI: sq. meters");
	    outputChoice.add("SI: acre");
	    outputChoice.add("SI: sq. kilometers");

	} else if (cb == energy) {
	    factor = energyFactor();
	    
	    inputChoice.add("US: in * lbf");            // 0.1130
	    inputChoice.add("US: ft * lbf");            // 1.35582
	    inputChoice.add("US: Btu's");               // 1055.06
	    inputChoice.add("US: kilocalories");        // 4186.8
	    inputChoice.add("SI: Joules");              // 1.0
	    inputChoice.add("SI: kilowatt-hours");      // 3600000
	    inputChoice.add("SI: horsepowers");         // 2647800
	    
	    outputChoice.add("US: in * lbf");            // 0.1130
	    outputChoice.add("US: ft * lbf");            // 1.35582
	    outputChoice.add("US: Btu's");               // 1055.06
	    outputChoice.add("US: kilocalories");        // 4186.8
	    outputChoice.add("SI: Joules");              // 1.0
	    outputChoice.add("SI: kilowatt-hours");      // 3600000
	    outputChoice.add("SI: horsepowers");         // 2647800

	} else if (cb == length) {
	    factor = lengthFactor();
	    
	    inputChoice.add("US: inches");
	    inputChoice.add("US: feet");
	    inputChoice.add("US: yards");
	    inputChoice.add("US: miles");
	    inputChoice.add("SI: millimeters");
	    inputChoice.add("SI: centimeters");
	    inputChoice.add("SI: meters");
	    inputChoice.add("SI: kilometers");
		    
	    outputChoice.add("US: inches");
	    outputChoice.add("US: feet");
	    outputChoice.add("US: yards");
	    outputChoice.add("US: miles");
	    outputChoice.add("SI: millimeters");
	    outputChoice.add("SI: centimeters");
	    outputChoice.add("SI: meters");
	    outputChoice.add("SI: kilometers");

	} else if (cb == pressure) {
	    factor = pressureFactor();
	    
	    inputChoice.add("US: psi");            // 6894.76
	    inputChoice.add("US: psf");            // 47.8803
	    inputChoice.add("US: mmHg, Torr");     // 133.322
	    inputChoice.add("US: atmospheres");    // 101325
	    inputChoice.add("SI: Pascals");        // 1.0
	    inputChoice.add("SI: microbar");       // 0.1
	    inputChoice.add("SI: millibar");       // 100
	    inputChoice.add("SI: bar");            // 100000
	    inputChoice.add("SI: N/sq. mm.");      // 1000000

	    outputChoice.add("US: psi");            // 6894.76
	    outputChoice.add("US: psf");            // 47.8803
	    outputChoice.add("US: mmHg, Torr");     // 133.322
	    outputChoice.add("US: atmospheres");    // 101325
	    outputChoice.add("SI: Pascals");        // 1.0
	    outputChoice.add("SI: microbar");       // 0.1
	    outputChoice.add("SI: millibar");       // 100
	    outputChoice.add("SI: bar");            // 100000
	    outputChoice.add("SI: N/sq. mm.");      // 1000000	

	} else if (cb == velocity) {
	    factor = velocityFactor();
	    
	    inputChoice.add("US: mph");   // 1.60934
	    inputChoice.add("US: knots"); // 1.852
	    inputChoice.add("SI: km/h");  // 1.0
	    inputChoice.add("SI: m/s");   // 3.6
  
	    outputChoice.add("US: mph");   // 1.60934
	    outputChoice.add("US: knots"); // 1.852
	    outputChoice.add("SI: km/h");  // 1.0
	    outputChoice.add("SI: m/s");   // 3.6
		
	} else if (cb == volume) {       
	    factor = volumeFactor();
	    
	    inputChoice.add("US: cu. inches");      // 0.01639
	    inputChoice.add("US: cu. feet");        // 28.3168
	    inputChoice.add("US: cu. yards");       // 764.555
	    inputChoice.add("US: fl. ounces");      // 0.029574
	    inputChoice.add("US: liq. pints");      // 0.47318
	    inputChoice.add("US: liq. quarts");     // 0.94625
	    inputChoice.add("US: gallon");          // 3.785
	    inputChoice.add("SI: milliliter");      // 0.001
	    inputChoice.add("SI: liter");           // 1.0
	    inputChoice.add("SI: cu. meter");       // 1000		    
	    
	    outputChoice.add("US: cu. inches");      // 0.01639
	    outputChoice.add("US: cu. feet");        // 28.3168
	    outputChoice.add("US: cu. yards");       // 764.555
	    outputChoice.add("US: fl. ounces");      // 0.029574
	    outputChoice.add("US: liq. pints");      // 0.47318
	    outputChoice.add("US: liq. quarts");     // 0.94625
	    outputChoice.add("US: gallon");          // 3.785
	    outputChoice.add("SI: milliliter");      // 0.001
	    outputChoice.add("SI: liter");           // 1.0
	    outputChoice.add("SI: cu. meter");       // 1000

	} else if (cb == weight) {
	    factor = weightFactor();
	    
	    inputChoice.add("US: drams");
	    inputChoice.add("US: ounces");
	    inputChoice.add("US: pounds");
	    inputChoice.add("US: hundredweight");
	    inputChoice.add("US: long ton");
	    inputChoice.add("SI: grams");
	    inputChoice.add("SI: kilograms");
	    inputChoice.add("SI: metric ton");
	    
	    outputChoice.add("US: drams");
	    outputChoice.add("US: ounces");
	    outputChoice.add("US: pounds");
	    outputChoice.add("US: hundredweight");
	    outputChoice.add("US: long ton");
	    outputChoice.add("SI: grams");
	    outputChoice.add("SI: kilograms");
	    outputChoice.add("SI: metric ton");
	}
    }

    public void paint(Graphics g) {
	//draw the simple title
	g.setFont(new Font("Monospaced", Font.BOLD, 26));
	g.setColor(new Color(200, 200, 200));
        g.drawString("Conversion Calculator", 122, 33);
	g.setColor(new Color(0, 0, 150));
        g.drawString("Conversion Calculator", 120, 30);
    }

    public double[] areaFactor() {
	//assign the appropriate ratio factors to each category of measurement
	double cFactor[] = {0.0006452, 0.0929, 0.8361, 2590000, 0.0001, 1.0, 100, 1000000};
	return cFactor;
    }

    public double[] energyFactor() {
	double cFactor[] = {0.112985, 1.35582, 1055.06, 4186.8, 1.0, 3600000, 2647800};
	return cFactor;
    }

    public double[] lengthFactor() {
	//n this case, the first value, inches (0.0254), has a ratio of 0.0254 in relation to one meter, the base factor. 0.0254 meters = 1 inch.
	double cFactor[] = {0.0254, 0.3048, 0.9144, 1609.344, 0.001, 0.01, 1.0, 1000.0};
	return cFactor;
    }

    public double[] pressureFactor() {
	double cFactor[] = {6894.76, 47.8803, 133.322, 101325, 1.0, 0.1, 100, 100000, 1000000};
	return cFactor;
    }

    public double[] velocityFactor() {
	double cFactor[] = {1.60934, 1.852, 1.0, 3.6};
	return cFactor;
    }

    public double[] volumeFactor() {
	double cFactor[] = {0.01639, 28.3168, 764.555, 0.029574, 0.47318, 0.94625, 3.785, 0.001, 1.0, 1000};
	return cFactor;
    }

    public double[] weightFactor() {
	double cFactor[] = {0.00177184, 0.02834, 0.45359, 45.3592, 907.19404, 0.001, 1.0, 1000.0};
	return cFactor;
    }

}
