//********************************************************************
//***                        unitsPda                              ***
//***                      April 14, 2007                          ***
//***              Copyright Glenn Hollowell 2007                  ***
//***                     glenn@blepsias.net                       ***
//***  **********************************************************  ***
//***  Software is provided "AS IS," without a warranty of any     ***
//***  kind. ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES,***
//***  INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS  ***
//***  FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY    ***
//***  EXCLUDED. THE ENTIRE RISK ARISING OUT OF USING THE SOFTWARE ***
//***  IS ASSUMED BY THE USER. See the GNU General Public License  ***
//***  at www.gnu.org for further details.                         ***
//***  *********************************************************** ***
//***  The application was written using the SuperWaba toolset     ***
//***  developed by Guilherme Hazan and his staff at               ***
//***  Superwaba, Ltd. Superwaba is a proprietary development      ***
//***  environment based in part on the Waba development           ***
//***  environment developed by WabaSoft, Inc.                     ***                        
//********************************************************************  

import waba.fx.*;
import waba.sys.*;
import waba.util.*;
import waba.ui.*;
import waba.io.*;

public class convertUnits extends Container{
	chooseUnits chooseUnits;	
	public keyPad keyPad;	
	Button btnConvert,btnBack,btnExit;
	MessageBox mb1;	
	ListBox lbSource,lbDestination;
	Label lblBaseValue, lblResultValue, lblInput, lblOutput;
	Edit edBaseValue, edResultValue;
	String szInput, szDestination, szTemporary, szOutputUnits, szInputUnits, szChoice = unitsPda.szConversionType;
	String szHeight, szWidth;
	int iWidth, iHeight;
	int intSource, intDestination, intDataType, nItems;  //index controls
	double dInput, dOutput;
	Color brickRed, glacialTill, moreBlue;	
	//Length <meter>
	String lengthName[] = { "centimeter", "fathom", "foot", "furlong", "inch", "kilometer", "meter", "mile", "millimeter", "naut. mile (int.)", "naut. mile (UK)", "yard" };
	String lengthShort[] = { "cm", "ftm", "ft", "flg", "in", "km", "m", "mi", "mm", "nmI", "nmU", "yd" };
	double lengthFactor[] = { 0.01, 1.828805516, 0.3048, 201.1686067, 0.0254, 1000, 1, 1609.344, 0.001, 1852, 1853.184, 0.914402757 };
	//Weight <gram>
	String weightName[] = { "apothec. oz", "drachm", "grain", "gram", "hundredWeight", "kilogram", "milligram", "ounce", "pennyWeight", "pound", "quarter", "scruple", "sh hundred weight", "slug", "stone", "ton (metric)", "long ton (UK)", "short ton (US)", "troy pound", "troy ounce" };
	String weightShort[] = { "ap oz", "dr", "gr", "g", "hW", "kg", "mg", "oz", "pW", "lb", "qtr", "sc", "shW", "slg", "st", "t", "lt (UK)", "st (US)", "tr lb", "tr oz" };
	double weightFactor[] = { 31.1035, 3.8879, 0.0648, 1, 50802.3454, 1000, 0.001, 28.3495, 1.5552, 453.5924, 12700.5864, 1.296, 45359.237, 14593.9, 6350.2932, 1000000, 1016046.9088, 907184.74, 31.1035, 373.2417 };	
	//Area <sq meter>
	String areaName[] = { "acre", "hectare", "square mile", "rood", "sq centimeter", "square foot", "square inch", "sq kilometer", "square meter", "sq millimeter", "square yard" };
	String areaShort[] = { "ac", "h", "mi2", "rd", "cm2", "ft2", "in2", "km2", "m2", "mm2", "yd2" };
	double areaFactor[] = { 4046.85468, 10000, 2589986.995, 1011.71367, 0.0001, 0.092903, 0.000645159, 1000000, 1, 0.000001, 0.836127 };
	//Volume <cu cm> ...add cubic foot, add acre foot
	String volumeName[] = { "barrel (dry)", "barrel (oil)", "bushel", "bushel (UK)", "cubic centimeter", "acre foot","cubic foot ","cubic inch", "cubic meter", "cubic millimeter", "cup", "gallon", "gallon (UK)", "liter", "milliliter", "ounce (fluid)", "peck", "peck (UK)", "pint (dry)", "pint (liq)", "pint (UK)", "quart (dry)", "quart (liq)", "quart (UK)", "tablespoon", "tablespn-metric", "teaspoon", "teaspn-metric" };
	String volumeShort[] = { "bd",  "bl", "bu", "buU", "cm3","AcFt","ft3","in3", "m3", "mm3", "c", "gal", "galU", "ltr", "mL", "fl oz", "pk", "pkU", "pt", "fl pt", "ptU", "qt", "fl qt", "qtU", "Tbsp", "TbsM", "tsp", "tspM" };
	double volumeFactor[] = { 115627.0252, 158987.1, 35239.04, 36368.704, 1,1233479808, 28316.8, 16.3871, 1000000, 0.001, 236.592, 3785.408, 4546.088, 1000, 1, 29.5735, 8809.76, 9092.176, 550.61, 473.176, 568.261, 1101.22, 946.352, 1136.522, 14.787, 15, 4.929, 5 };	
	//Temperature
	String temperatureName[] = { "Fahrenheit", "Celsius", "Kelvin" };
	String temperatureShort[] = { "°F", "°C", "K" };	
	//Speed
	String speedName[] = { "km/h", "knots", "m/s", "mph" }; 
	String speedShort[] = { "kmh", "knots", "m/s", "mph" };
	double speedFactor[] = { 0.277778, 0.5, 1, 0.447 };	
	//Energy
	String energyName[] = { "Brit. ther. unit", "calorie", "joule", "kilo calorie", "kilo joule", "kilowatt hour", "watt hour" };
	String energyShort[] = { "btu", "cal", "J", "kcal", "kJ", "kwh", "wh" };
	double energyFactor[] = { 1055.06, 4.1868, 1, 4186.8, 1000, 3600000, 3600 };	
	//Power
	String powerName[] = { "ft lb-force/sec", "horsepower", "kiloWatt", "watt"};
	String powerShort[] = { "ft lb/sec", "hp", "kW", "W" };
	double powerFactor[] = { 1.35582, 745.7, 1000, 1 };	
	//Pressure
	String pressureName[] = { "bar", "hectoPascal", "inch. mercury", "kiloPascal", "millibar", "mm mercury", "pascal", "pound/sq foot", "pound/sq inch", "std. atmosphere" };
	String pressureShort[] = { "bar", "hPa", "inHg", "kPa", "mBar", "mmHg", "Pa", "psf", "psi", "sAtm" };
	double pressureFactor[] = { 100000, 100, 3386.3882, 1000, 100, 133.3224, 1, 47.8803, 6894.757, 101325 };
	
	/****************************************************************************
	 * Remove letters allows the user to do repetitive conversions using the same
	 * value stripping off the added units that are added to the input, XXXmm, 
	 * XXXbtu, etc.
	 * 
	 * Pardon the big conditional, but isDigit is not in the Character class yet.
	 ***************************************************************************/	
	protected static String removeLetters(String string){
		int i, len = string.length();
		StringBuffer dest = new StringBuffer(len);
		char c;
		
		for (i = (len - 1); i >= 0; i--){
			c = string.charAt(i);
			//	if (Character.isDigit(c)){//not SW supported!!!
			if ((c == '1')||(c == '2')||(c == '3')||(c == '4')||
					(c == '5')||(c == '6')||(c == '7')||(c == '8') ||
					(c == '9')||(c == '0')||(c == '.')||(c == '-')){	
				dest.append(c);
			}			
		}
		dest.reverse();//this function makes a mirror string as it parses...
		return dest.toString();
	}	
	public void onStart(){
		szWidth = unitsPda.szWidth;
		szHeight = unitsPda.szHeight;
		
		iWidth = Convert.toInt(szWidth);
		iHeight = Convert.toInt(szHeight);
		
		glacialTill = unitsPda.glacialTill;
		brickRed = unitsPda.brickRed;
		moreBlue = unitsPda.moreBlue;
		
		keyPad = new keyPad();
		
		lblInput = new Label("Units In");
		add(lblInput);
		lblInput.setRect(iWidth/8*1,TOP+2,iWidth/16*5,PREFERRED);
		
		lblOutput = new Label("Units Out");
		add(lblOutput);
		lblOutput.setRect(iWidth/16*9,SAME,iWidth/16*5,PREFERRED);
		
		lbSource = new ListBox();
		add(lbSource);
		if (iHeight == iWidth){//is square screen
			lbSource.setRect(iWidth/32*1,AFTER,iWidth/16*7,iHeight/16*8);}
		else{ //is rectangle screen
			lbSource.setRect(iWidth/32*1,AFTER,iWidth/16*7,iHeight/16*10);}			
		lbDestination = new ListBox();
		add(lbDestination);
		
		if (iHeight == iWidth){//is square
			lbDestination.setRect(iWidth/8*4,SAME,iWidth/16*7,iHeight/16*8);}
		else{//is rectangle
			lbDestination.setRect(iWidth/8*4,SAME,iWidth/16*7,iHeight/16*10);}			
		
		lblBaseValue = new Label(" Base Value:");
		add(lblBaseValue);
		if (iHeight == iWidth){//is square
			lblBaseValue.setRect(LEFT+2,iHeight/32*19,PREFERRED,PREFERRED);}
		else{//is rectangle
			lblBaseValue.setRect(LEFT+2,iHeight/32*22,PREFERRED,PREFERRED);}			
		
		//lblBaseValue.setRect(LEFT+2,iHeight/32*19,PREFERRED,PREFERRED);
		
		edBaseValue = new Edit();
		add(edBaseValue);
		edBaseValue.setValidChars(Edit.numbersSet);
		edBaseValue.setRect(AFTER+2,SAME,iWidth/16*7,PREFERRED);
		
		lblResultValue = new Label("Result Value:");
		add(lblResultValue);
		lblResultValue.setRect(LEFT+2,AFTER+2,PREFERRED,PREFERRED);
		
		edResultValue = new Edit();
		add(edResultValue);
		edResultValue.setRect(AFTER+4, SAME,iWidth/16*7,PREFERRED);
		edResultValue.setEditable(false);
		
		btnConvert = new Button("Convert");
		btnConvert.setGap(10);
		btnConvert.setBorder(Button.BORDER_3D);
		add (btnConvert);
		
		if (iHeight == iWidth){//is square
			btnConvert.setRect(CENTER,iHeight/32*25,PREFERRED,iHeight/32*4);}
		else{//is rectangle
			btnConvert.setRect(CENTER,iHeight/32*26,PREFERRED,iHeight/32*4);}			
		
		//btnConvert.setRect(CENTER,iHeight/32*25,PREFERRED,iHeight/32*4);
		
		btnBack = new Button("Back");
		btnBack.setGap(10);
		btnBack.setBorder(Button.BORDER_3D);
		add (btnBack);
		btnBack.setRect(LEFT+2,SAME,PREFERRED,iHeight/32*3);
		
		btnExit = new Button("Exit");
		btnExit.setGap(10);
		btnExit.setBorder(Button.BORDER_3D);
		add (btnExit);
		btnExit.setRect(RIGHT-2,SAME,PREFERRED,iHeight/32*3);
		
		if (Settings.isColor)
		{
			lblInput.setBackColor(glacialTill);
			lblOutput.setBackColor(glacialTill);
			lbSource.setBackColor(glacialTill);
			lbDestination.setBackColor(glacialTill);
			lblBaseValue.setBackColor(glacialTill);
			edBaseValue.setBackColor(glacialTill);
			lblResultValue.setBackColor(glacialTill);
			edResultValue.setBackColor(glacialTill);
			btnConvert.setBackColor(brickRed);
			btnExit.setBackColor(brickRed);
			btnBack.setBackColor(brickRed);
			this.setBackColor(glacialTill);
		}
		
		if (szChoice.compareTo("Length")==0){
			intDataType = 0;
			lbSource.add(lengthName);
			lbDestination.add(lengthName);
		}	     
		else if (szChoice.compareTo("Weight")==0){
			intDataType = 1;
			lbSource.add(weightName);
			lbDestination.add(weightName);
		}
		else if (szChoice.compareTo("Area")==0){
			intDataType = 2;
			lbSource.add(areaName);
			lbDestination.add(areaName);
		}
		else if (szChoice.compareTo("Volume")==0){
			intDataType = 3;
			lbSource.add(volumeName);
			lbDestination.add(volumeName);
		}
		else if (szChoice.compareTo("Temperature")==0){
			intDataType = 4;
			lbSource.add(temperatureName);
			lbDestination.add(temperatureName);
		}
		else if (szChoice.compareTo("Speed")==0){
			intDataType = 5;
			lbSource.add(speedName);
			lbDestination.add(speedName);
		}
		else if (szChoice.compareTo("Energy")==0){
			intDataType = 6;
			lbSource.add(energyName);
			lbDestination.add(energyName);
		}
		else if (szChoice.compareTo("Power")==0){
			intDataType = 7;
			lbSource.add(powerName);
			lbDestination.add(powerName);
		}
		else if (szChoice.compareTo("Pressure")==0){
			intDataType = 8;
			lbSource.add(pressureName);
			lbDestination.add(pressureName);
		}
	}
	public void onEvent(Event event){		
		if(event.type == PenEvent.PEN_DOWN){
			if (event.target == edBaseValue)
				//MainWindow.getMainWindow().popupBlockingModal(keyPad);
				keyPad.popupBlockingModal();
			//locationEdit.popupBlockingModal();
		}	 
		if(event.type == ControlEvent.WINDOW_CLOSED)
			if(event.target == keyPad){  
				edBaseValue.setText(unitsPda.szInput);
				repaint();
			}	 
		if (event.type == ControlEvent.PRESSED){
			if (event.target == btnConvert){
				szInput = edBaseValue.getText();
				szInput = removeLetters(szInput);
				szInput.trim();
				dInput = Convert.toDouble(szInput);
				
				if ((szInput.compareTo("")==0)||(dInput == 0)){
					//mb1.popupBlockingModal();
					mb1 = new MessageBox("Conditional Violation","Please enter a | number to convert. |             Thank you.");
					mb1.popupBlockingModal();
					//MainWindow.getMainWindow().popupModal(mb1);
					
					
					return;       	
				}				
				//below snags listbox selections
				intSource = lbSource.getSelectedIndex();  
				intDestination = lbDestination.getSelectedIndex();
				//below confirms that both listboxes have had selections made
				if ((intSource >= 0)  && (intDestination >= 0)){
				}
				else{
					mb1 = new MessageBox("Conditional Violation","Please confirm that you | have selected a category | from both the Input and Output | listboxes above. |             Thank you.");
					mb1.popupBlockingModal();
					//MainWindow.getMainWindow().popupModal(mb1);
					return;
				}       	
				switch(intDataType){
				case 0:         //length conversions
					dOutput = lengthFactor[intSource]/lengthFactor[intDestination]* dInput;
					szOutputUnits = lengthShort[intDestination];
					szInputUnits = lengthShort[intSource];
					break;
				case 1:			//weight conversions
					dOutput = weightFactor[intSource]/weightFactor[intDestination]* dInput;
					szOutputUnits = weightShort[intDestination];
					szInputUnits = weightShort[intSource];
					break;
				case 2:         //area conversions
					dOutput = areaFactor[intSource]/areaFactor[intDestination]* dInput;
					szOutputUnits = areaShort[intDestination];
					szInputUnits = areaShort[intSource];
					break;
				case 3:			//volume conversions
					dOutput = volumeFactor[intSource]/volumeFactor[intDestination]* dInput;
					szOutputUnits = volumeShort[intDestination];
					szInputUnits = volumeShort[intSource];
					break;
				case 4:         //Temperature conversions       			
					if (intSource == 0 && intDestination == 1)
						dOutput=(dInput-32)*5/9; //F to C
					else if (intSource == 1 && intDestination == 0)
						dOutput=dInput*9/5+32; //C to F
					else if (intSource == 1 && intDestination == 2)
						dOutput=dInput+273.15; //C to K
					else if (intSource == 2 && intDestination == 1)
						dOutput=dInput-273.15; //K to C
					else if (intSource == 0 && intDestination == 2)
						dOutput=((dInput-32)*5/9)+273.15; //F to K
					else if (intSource == 2 && intDestination == 0)
						dOutput=(dInput-273.15)*9/5+32; //K to F
					else
						dOutput=dInput;
					szOutputUnits = temperatureShort[intDestination];
					szInputUnits = temperatureShort[intSource];
					break;
				case 5:			//speed conversions
					dOutput = speedFactor[intSource]/speedFactor[intDestination]* dInput;
					szOutputUnits = speedShort[intDestination];
					szInputUnits = speedShort[intSource];
					break;
				case 6:         //Energy conversions
					dOutput = energyFactor[intSource]/energyFactor[intDestination]* dInput;
					szOutputUnits = energyShort[intDestination];
					szInputUnits = energyShort[intSource];
					break;
				case 7:			//Power conversions
					dOutput = powerFactor[intSource]/powerFactor[intDestination]* dInput;
					szOutputUnits = powerShort[intDestination];
					szInputUnits = powerShort[intSource];
					break;
				case 8:			//Pressure conversions
					dOutput = pressureFactor[intSource]/pressureFactor[intDestination]* dInput;
					szOutputUnits = pressureShort[intDestination];
					szInputUnits = pressureShort[intSource];
					break;      		
				}
				//adds units suffix, (mm, ft, etc) to input
				szInput = szInput + " " + szInputUnits;
				edBaseValue.setText(szInput);
				
				szDestination = Convert.toString(dOutput,4);
				//adds units suffix, (mm, ft, etc) to output
				szDestination = szDestination + " " + szOutputUnits; //adds units suffix, (mm, ft, etc)     	
				edResultValue.setText(szDestination);   	
			}           
			else if (event.target == btnExit)
				MainWindow.getMainWindow().exit(0);
			else if (event.target == btnBack){
				if (chooseUnits == null) chooseUnits = new chooseUnits();
				MainWindow.getMainWindow().swap(chooseUnits);
			}
		}
	}
}

