// convertunits.js version 1.1 2007-02-24
//
// A JavaScript class for converting units of measurement.
//
// base: http://www.webaware.com.au/free/conversions/
//
// Copyright © 2007 WebAware Pty Ltd
//---------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// Full license: http://www.webaware.com.au/free/license.htm
//---------------------------------------------------------------------
// This class is easily extensible, either by adding directly to this
// class or subclassing and adding new conversions. Just record the 
// new functions in the class member "catalogue". I've only put in the
// most frequently converted units used at my place :)
//
// ref: http://en.wikipedia.org/wiki/Conversion_of_units
//---------------------------------------------------------------------
// methods: (not uncluding conversion functions)
// ConversionsCatalogue		returns a catalogue of conversion functions
// AvailableConversions		returns an associative array of descriptions
// DescribeConversion		returns a description of specified function
// Convert					performs the specified conversion function 
//---------------------------------------------------------------------

// class for cataloging UnitsConverter functions
function UnitsConverterCatItem(fn_name, units_cat, units_from, units_to)
{
	this.fn_name = fn_name;
	this.units_cat = units_cat;
	this.units_from = units_from;
	this.units_to = units_to;
}

// constructor for class
function UnitsConverter()
{
}

// class "constants"
UnitsConverter.prototype.LB_GRAM = 453.59237;			// pounds into grams
UnitsConverter.prototype.OUNCE_GRAM = 28.349523125;		// ounces into grams
UnitsConverter.prototype.SHORTTON_KG = 907.18474;		// "short" tons into kilograms
UnitsConverter.prototype.LONGTON_KG = 1016.0469088;		// (long) tons into kilograms
UnitsConverter.prototype.INCH_MM = 25.4;				// inches into milimetres
UnitsConverter.prototype.MILE_M = 1609.344;				// miles into metres
UnitsConverter.prototype.GALLONUS_L = 3.785411784;		// US gallons into litres
UnitsConverter.prototype.GALLONUK_L = 4.54609;			// British gallons into litres

// temperature conversions
UnitsConverter.prototype.TempC2F = function(degC) { return degC * 1.8 + 32; }
UnitsConverter.prototype.TempF2C = function(degF) { return (degF - 32) * 5 / 9; }

// mass conversions
UnitsConverter.prototype.MassLb2Kg = function(lb) { return lb * this.LB_GRAM / 1000; }
UnitsConverter.prototype.MassKg2Lb = function(kg) { return kg * 1000 / this.LB_GRAM; }
UnitsConverter.prototype.MassLb2G = function(lb) { return lb * this.LB_GRAM; }
UnitsConverter.prototype.MassG2Lb = function(g) { return g / this.LB_GRAM; }
UnitsConverter.prototype.MassOz2G = function(oz) { return oz * this.OUNCE_GRAM; }
UnitsConverter.prototype.MassG2Oz = function(g) { return g / this.OUNCE_GRAM; }
UnitsConverter.prototype.MassTon2Kg = function(ton) { return ton * this.LONGTON_KG; }
UnitsConverter.prototype.MassKg2Ton = function(kg) { return kg / this.LONGTON_KG; }
UnitsConverter.prototype.MassShortTon2Kg = function(ton) { return ton * this.SHORTTON_KG; }
UnitsConverter.prototype.MassKg2ShortTon = function(kg) { return kg / this.SHORTTON_KG; }

// length conversions
UnitsConverter.prototype.LengthIn2MM = function(inch) { return inch * this.INCH_MM; }
UnitsConverter.prototype.LengthMM2In = function(mm) { return mm / this.INCH_MM; }
UnitsConverter.prototype.LengthFt2M = function(ft) { return ft * 12 * this.INCH_MM / 1000; }
UnitsConverter.prototype.LengthM2Ft = function(m) { return m * 1000 / (12 * this.INCH_MM); }
UnitsConverter.prototype.LengthMi2Km = function(mi) { return mi * this.MILE_M / 1000; }
UnitsConverter.prototype.LengthKm2Mi = function(km) { return km * 1000 / this.MILE_M; }

// volume conversions
UnitsConverter.prototype.VolumeGUS2L = function(gal) { return gal * this.GALLONUS_L; }
UnitsConverter.prototype.VolumeL2GUS = function(l) { return l / this.GALLONUS_L; }
UnitsConverter.prototype.VolumeGUK2L = function(gal) { return gal * this.GALLONUK_L; }
UnitsConverter.prototype.VolumeL2GUK = function(l) { return l / this.GALLONUK_L; }

// fuel efficiency conversions
UnitsConverter.prototype.FuelLp100km2MPG = function(lp100km) { return (100 / (this.MILE_M / 1000)) / (lp100km / this.GALLONUS_L) }
UnitsConverter.prototype.FuelMPG2Lp100km = function(mpg) { return (this.GALLONUS_L * 100) / (mpg * (this.MILE_M / 1000)) }

// class variable: array of objects describing the conversion functions
//	members are: fn_name, units_cat, units_from, units_to
UnitsConverter.catalogue = {
	"TempC2F"			: new UnitsConverterCatItem("TempC2F", "Temperature", "centigrade", "Fahrenheit"),
	"TempF2C"			: new UnitsConverterCatItem("TempF2C", "Temperature", "Fahrenheit", "centigrade"),
	"MassLb2Kg"			: new UnitsConverterCatItem("MassLb2Kg", "Mass", "pounds", "kilograms"),
	"MassKg2Lb"			: new UnitsConverterCatItem("MassKg2Lb", "Mass", "kilograms", "pounds"),
	"MassLb2G"			: new UnitsConverterCatItem("MassLb2G", "Mass", "pounds", "grams"),
	"MassG2Lb"			: new UnitsConverterCatItem("MassG2Lb", "Mass", "grams", "pounds"),
	"MassOz2G"			: new UnitsConverterCatItem("MassOz2G", "Mass", "ounces", "grams"),
	"MassG2Oz"			: new UnitsConverterCatItem("MassG2Oz", "Mass", "grams", "ounces"),
	"MassTon2Kg"		: new UnitsConverterCatItem("MassTon2Kg", "Mass", "(long) tons", "kilograms"),
	"MassKg2Ton"		: new UnitsConverterCatItem("MassKg2Ton", "Mass", "kilograms", "(long) tons"),
	"MassShortTon2Kg"	: new UnitsConverterCatItem("MassShortTon2Kg", "Mass", "short tons", "kilograms"),
	"MassKg2ShortTon"	: new UnitsConverterCatItem("MassKg2ShortTon", "Mass", "kilograms", "short tons"),
	"LengthIn2MM"		: new UnitsConverterCatItem("LengthIn2MM", "Length", "inches", "milimetres"),
	"LengthMM2In"		: new UnitsConverterCatItem("LengthMM2In", "Length", "milimetres", "inches"),
	"LengthFt2M"		: new UnitsConverterCatItem("LengthFt2M", "Length", "feet", "metres"),
	"LengthM2Ft"		: new UnitsConverterCatItem("LengthM2Ft", "Length", "metres", "feet"),
	"LengthMi2Km"		: new UnitsConverterCatItem("LengthMi2Km", "Length", "miles", "kilometres"),
	"LengthKm2Mi"		: new UnitsConverterCatItem("LengthKm2Mi", "Length", "kilometres", "miles"),
	"VolumeGUS2L"		: new UnitsConverterCatItem("VolumeGUS2L", "Volume", "US gallons", "litres"),
	"VolumeL2GUS"		: new UnitsConverterCatItem("VolumeL2GUS", "Volume", "litres", "US gallons"),
	"VolumeGUK2L"		: new UnitsConverterCatItem("VolumeGUK2L", "Volume", "imperial gallons", "litres"),
	"VolumeL2GUK"		: new UnitsConverterCatItem("VolumeL2GUK", "Volume", "litres", "imperial gallons"),
	"FuelLp100km2MPG"	: new UnitsConverterCatItem("FuelLp100km2MPG", "Fuel", "miles per US gallon", "litres per 100km"),
	"FuelMPG2Lp100km"	: new UnitsConverterCatItem("FuelMPG2Lp100km", "Fuel", "litres per 100km", "miles per US gallon")
};

// return an associative array of conversion functions as UnitsConverterCatItem catalogue entries
UnitsConverter.prototype.ConversionsCatalogue = function()
{
	return UnitsConverter.catalogue;
}

// return an associative array of conversion function names as textual labels
UnitsConverter.prototype.AvailableConversions = function()
{
	var a = new Array();

	for (var f in UnitsConverter.catalogue)
	{
		with (UnitsConverter.catalogue[f])
		{
			a[fn_name] = units_cat + ": " + units_from + " to " + units_to;
		}
	}

	return a;
}

// return a UnitsConverterCatItem object describing the specified conversion function
UnitsConverter.prototype.DescribeConversion = function(fn_name)
{
	return UnitsConverter.catalogue[fn_name];
}

// return result of conversion function specified
UnitsConverter.prototype.Convert = function(fn_name, from_value)
{
	return eval("this." + fn_name + "(" + from_value + ")");
}
