/* Populate data information */
var Unit = {};

Unit.label = ""; // label used to describe units in comment

Unit.alias = {};
Unit.alias.mph = "miles/hour";
Unit.alias.mpg = "miles/gallon";
Unit.alias.fps = "feet/second";
Unit.alias.kph = "km/hour";
Unit.alias.kmph = "km/hour";
Unit.alias.hz = "times/second";

Unit.length = {};
Unit.length.SI = {};
Unit.length.SI.meter = 1; // meter

Unit.mass = {};
Unit.mass.SI = {};
Unit.mass.SI.kilogram = 1; // kilogram base

Unit.time = {};
Unit.time.SI = {};
Unit.time.SI.second = 1; // second base

Unit.area = ["\\^2", "sq", "squared", "square"]; // words that connote a square unit
Unit.area.SI = {};
Unit.area.SI.meter = 2; // area = m^2

Unit.volume = ["\\^3", "cu", "cubed", "cubic"]; // ditto for cubic units
Unit.volume.SI = {};
Unit.volume.SI.meter = 3; // volume = m^3

Unit.speed = {};

Unit.liquid = {};
Unit.liquid.SI = {};
Unit.liquid.SI.meter = 3; // volume = m^3

Unit.power = {};
Unit.force = {};
Unit.torque = {};
Unit.energy = {};
Unit.data = {};
Unit.currency = {};

// temperature - nonlinear conversions
Unit.temperature = {};
Unit.temperature.conversion = "function";
Unit.temperature.C = function(C){return C}; // identity
Unit.temperature.F = function(F){return (F - 32.0) * 5/9; }; // Fahrenheit to Celcius 
Unit.temperature.K = function(K){return K - 273.15}; // Kelvin to Celcius

Unit.data.base = 1; // 1 bit
Unit.data.bit = Unit.data.bits = 1;
Unit.data.kilobit = Unit.data.kbit = Unit.data.kbits = 1024 * Unit.data.bit;
Unit.data.megabit = Unit.data.mbit = Unit.data.mbits = 1024 * Unit.data.kbit;
Unit.data.gigabit = Unit.data.gbit = Unit.data.gbits = 1024 * Unit.data.mbit;
Unit.data.terabit = Unit.data.tbit = Unit.data.tbits = 1024 * Unit.data.gbit;
Unit.data.petabit = Unit.data.pbit = Unit.data.pbits = 1024 * Unit.data.tbit;

Unit.data["byte"] = Unit.data["bytes"] = 8 * Unit.data.bit;

Unit.data["kilobyte"] = Unit.data["kb"] = 1024 * Unit.data["byte"];
Unit.data["megabyte"] = Unit.data["mb"] = 1024 * Unit.data.kb;
Unit.data["gigabyte"] = Unit.data["gb"] = 1024 * Unit.data.mb;
Unit.data["terabyte"] = Unit.data["tb"] = 1024 * Unit.data.gb;
Unit.data["petabyte"] = Unit.data["pb"] = 1024 * Unit.data.tb;

Unit.currency.base = 1; // 1 dollar
Unit.currency.dollar = Unit.currency.dollars = 1;
Unit.currency.penny = Unit.currency.pennies = Unit.currency.cent = Unit.currency.cents = .01 * Unit.currency.dollars;

Unit.constant = {};
Unit.constant.base = 1; // unity
Unit.constant.unity = 1; // unity - use as default unit for no conversion
Unit.constant.times = Unit.constant.time = 1; // time(s) per second
Unit.constant.kilotimes = Unit.constant.kilotime = 1000 * Unit.constant.time; // time(s) per second


Unit.time.base = 1; // second
Unit.time.name = "time";

Unit.time.second = Unit.time.seconds = Unit.time.s = Unit.time.sec = Unit.time.secs = 1;

Unit.time.ps = 1e-12 * Unit.time.second;
Unit.time.ns = 1e-9 * Unit.time.second;
Unit.time.us = 1e-6 * Unit.time.second;
Unit.time.ms = 1e-3 * Unit.time.second;

Unit.time.minute = Unit.time.minutes = Unit.time.min = Unit.time.mins = 60 * Unit.time.second;

Unit.time.hour = Unit.time.hours = Unit.time.hr = Unit.time.hrs = Unit.time.h = 60 * Unit.time.minute;

Unit.time.day = 24 * Unit.time.hour;
Unit.time.days = 24 * Unit.time.hour;

Unit.time.week = 7 * Unit.time.day;
Unit.time.weeks = 7 * Unit.time.day;

Unit.time.fortnight = 2 * Unit.time.week;
Unit.time.fortnights = 2 * Unit.time.week;

Unit.time.month = 4.34812141 * Unit.time.week;
Unit.time.months = 4.34812141 * Unit.time.week;

Unit.time.year = 12 * Unit.time.month;
Unit.time.years = 12 * Unit.time.month;

Unit.time.decade = 10 * Unit.time.year;
Unit.time.decades = 10 * Unit.time.year;

Unit.time.century = 100 * Unit.time.year;
Unit.time.centuries = 100 * Unit.time.year;

Unit.time.millenium = 1000 * Unit.time.year;
Unit.time.milleniums = 1000 * Unit.time.year;
Unit.time.millenia = 1000 * Unit.time.year;

// area measure - grab the corresponding conversion in length and square it

// energy measure
Unit.energy.base = 1; // joule
Unit.energy.name = "energy";
Unit.energy.joule = Unit.energy.joules = Unit.energy.j = 1;

Unit.energy["electron volt"] = Unit.energy["ev"] = 1.60217646e19 * Unit.energy.joule;
Unit.energy["watt-hour"] = Unit.energy["watt hour"] = Unit.energy["w h"] = 3600 * Unit.energy.joule;
Unit.energy["kilowatt-hour"] = Unit.energy["kilowatt hour"] = Unit.energy["kwh"] = Unit.energy["kw h"] = 3600 * 1000 * Unit.energy.joule;
Unit.energy["btu"] = Unit.energy["btus"] = Unit.energy["british thermal unit"] = Unit.energy["british thermal units"] = 1055.05585 * Unit.energy.joule;
Unit.energy["calorie"] = Unit.energy["calories"] = Unit.energy["cal"] = 4.18400 * Unit.energy.joule;

Unit.energy["kilocalorie"] = Unit.energy["kilocalories"] = Unit.energy["kcal"] = Unit.energy["kcals"] = 1000 * Unit.energy.calorie;

// force measure
Unit.force.base = 1; // newton
Unit.force.name = "force";
Unit.force.newton = Unit.force.n = 1;

Unit.force["pound-force"] = Unit.force["pound force"] = Unit.force["lb force"] = Unit.force["lbf"] = Unit.force["lb"] = 4.44822162 * Unit.force.newton;

// torque measure
Unit.torque.base = 1; // newton - meter
Unit.torque.name = "torque";
Unit.torque["newton-meter"] = Unit.torque["newton meter"] = Unit.torque["newton meters"] = Unit.torque["n m"] = 1;

Unit.torque["foot lb"] = Unit.torque["ft lb"] = Unit.torque["foot-pound"] = Unit.torque["foot pound"] = 1.35581795 * Unit.torque["N m"];
Unit.torque["foot lbs"] = Unit.torque["ft lbs"] = Unit.torque["foot-pounds"] = Unit.torque["foot pounds"] = 1.35581795 * Unit.torque["N m"];


// power measure
Unit.power.base = 1; // watt
Unit.power.name = "power";

Unit.power.watt = Unit.power.watts = Unit.power.w = 1;
Unit.power.milliwatt = Unit.power.milliwatts = 1e-3 * Unit.power.watt;
Unit.power.kilowatt = Unit.power.kilowatts = Unit.power.kw = 1e3 * Unit.power.watt;
Unit.power.megawatt = Unit.power.megawatts = 1e6 * Unit.power.watt; // hrm... megawatt (caps) vs milliwatt (small)
Unit.power.gigawatt = Unit.power.gigawatts = Unit.power.gw = 1e9 * Unit.power.watt; // hrm... megawatt (caps) vs milliwatt (small). Don't have a difference. Case issues are too easy to happen.

Unit.power.horsepower = Unit.power.hp = 745.69987158227022 * Unit.power.watt;

// liquid measure
Unit.liquid.base = 1; // have the base be a cubic METER, which is the base for AREA
Unit.liquid.name = "Liquid measure";
Unit.liquid.liter = Unit.liquid.liters = Unit.liquid.litre = Unit.liquid.litres = Unit.liquid.l = Unit.liquid.ls = .001;
Unit.liquid.ml = Unit.liquid.mls = 1e-3 * Unit.liquid.liter; 
Unit.liquid.milliliter = Unit.liquid.milliliters = Unit.liquid.millilitre = Unit.liquid.millilitres = 1e-3 * Unit.liquid.liter;
Unit.liquid.cc = Unit.liquid.ccs = Unit.liquid.ml;

Unit.liquid.tsp = Unit.liquid.tsps = 4.92892161 * Unit.liquid.ml;
Unit.liquid.teaspoon = Unit.liquid.teaspoons = 4.92892161 * Unit.liquid.ml;

Unit.liquid.tbsp = Unit.liquid.tbsps = 3 * Unit.liquid.tsp;
Unit.liquid.tablespoon = Unit.liquid.tablespoons = 3 * Unit.liquid.tsp;

Unit.liquid.cup = Unit.liquid.cups = Unit.liquid.cp = 16 * Unit.liquid.tablespoon;
Unit.liquid.pint = Unit.liquid.pints = Unit.liquid.pt = 2 * Unit.liquid.cup;
Unit.liquid.quart = Unit.liquid.quarts = Unit.liquid.qt = 4 * Unit.liquid.cup;

Unit.liquid.gallon = Unit.liquid.gallons = Unit.liquid.gal = Unit.liquid.gals = 16 * Unit.liquid.cup;
Unit.liquid.barrel = Unit.liquid.barrels = 31 * Unit.liquid.gallon;

// weights in terms of grams
Unit.mass.base = 1; // kilogram base
Unit.mass.name = "mass";

Unit.mass.kilogram = Unit.mass.kilograms = 1;
Unit.mass.kg = Unit.mass.kgs = 1;

Unit.mass.gram = Unit.mass.grams = 1e-3 * Unit.mass.kg;
Unit.mass.g = Unit.mass.gs = Unit.mass.gram;

Unit.mass.mg = Unit.mass.milligram = Unit.mass.milligrams = 1e-3 * Unit.mass.gram;
Unit.mass.mgs = 1e-3 * Unit.mass.gram;

Unit.mass.ug = 1e-6 * Unit.mass.gram;
Unit.mass.ugs = 1e-6 * Unit.mass.gram;

// english units
Unit.mass.lb = .45359237 * Unit.mass.kg;
Unit.mass.lbs = .45359237 * Unit.mass.kg;
Unit.mass.pound = .45359237 * Unit.mass.kg;
Unit.mass.pounds = .45359237 * Unit.mass.kg;

Unit.mass.oz = Unit.mass.lb * 0.0625;
Unit.mass.ozs = Unit.mass.lb * 0.0625;
Unit.mass.ounce = Unit.mass.lb * 0.0625;
Unit.mass.ounces = Unit.mass.lb * 0.0625;

Unit.mass.dram = Unit.mass.oz * 0.0625;
Unit.mass.drams = Unit.mass.oz * 0.0625;

Unit.mass.stone = Unit.mass.lb * 14;
Unit.mass.stones = Unit.mass.oz * 14;

Unit.mass.ton = Unit.mass.lb * 2000;
Unit.mass.tons = Unit.mass.lb * 2000;

// everything in terms of meters
Unit.length.base = 1; // reference unit is meter
Unit.length.name = "length"; // reference unit is meter

Unit.length.meter = 1;
Unit.length.meters = 1;
Unit.length.m = 1;

Unit.length.km = 1e3;
Unit.length.kms = 1e3;
Unit.length.kilometer = 1e3;
Unit.length.kilometers = 1e3;

Unit.length.au = 149597870.691 * Unit.length.km; // from: http://en.wikipedia.org/wiki/Astronomical_unit
Unit.length["light year"] = Unit.length["lightyear"] = Unit.length["light years"] = 9460730472580.8 * Unit.length.km;
Unit.length.ly = 9460730472580.8 * Unit.length.km;

Unit.length.parsec = Unit.length.parsecs = 3.08567758e16 * Unit.length.meter;

Unit.length.cm = 1e-2;
Unit.length.cms = 1e-2;
Unit.length.centimeter = 1e-2;
Unit.length.centimeters = 1e-2;

Unit.length.mm = 1e-3;
Unit.length.mms = 1e-3;
Unit.length.millimeter = 1e-3;
Unit.length.millimeters = 1e-3;

Unit.length.um = 1e-6; // micrometer
Unit.length.micrometer = 1e-6; // micrometer

Unit.length.nm = 1e-9;
Unit.length.nanometer = 1e-9;
Unit.length.nanometers = 1e-9;


Unit.length.pm = 1e-12; // picometer
Unit.length.picometer = 1e-12; // picometer
Unit.length.picometers = 1e-12; // picometer

// English units: see http://www.infoplease.com/ipa/A0001660.html

Unit.length.inch = 0.0254;
Unit.length.inches = 0.0254;
Unit.length['in'] = 0.0254;
Unit.length['ins'] = 0.0254;

Unit.length.foot = Unit.length.inch * 12;
Unit.length.feet = Unit.length.inch * 12;
Unit.length.ft = Unit.length.inch * 12;

Unit.length.yard = Unit.length.foot * 3;
Unit.length.yards = Unit.length.foot * 3;
Unit.length.yd = Unit.length.foot * 3;
Unit.length.yds = Unit.length.foot * 3;

Unit.length.fathom = Unit.length.foot * 6;
Unit.length.fathoms = Unit.length.foot * 6;

Unit.length.rod = Unit.length.foot * 16.5;
Unit.length.rods = Unit.length.foot * 16.5;
Unit.length.rd = Unit.length.foot * 16.5;
Unit.length.rds = Unit.length.foot * 16.5;

Unit.length.furlong = Unit.length.foot * 660;
Unit.length.furlongs = Unit.length.foot * 660;

Unit.length.mile = Unit.length.foot * 5280;
Unit.length.miles = Unit.length.foot * 5280;

Unit.length.league = Unit.length.mile * 3;
Unit.length.leagues = Unit.length.mile * 3;

Unit.length.knot = Unit.length.foot * 6076.11549;
Unit.length.knots = Unit.length.foot * 6076.11549;

// area
Unit.area.base = 1;
Unit.area.name = "area";
Unit.area.acre = Unit.area.acres = Unit.length.rod * Unit.length.rod * 160;

/*  DYNAMICALLY LOAD DATA */
//Now, process the data..

//Unit.currencies = null;
function loadCurrencyData(){
	// The web service call
	var req  = 'http://instacalc.com/data/currencies.json'; 
	// Create a new request object
	bObj = new JSONscriptRequest(req); // will callback to processData
	// Build the dynamic script tag
	bObj.buildScriptTag();
	// Add the script tag to the page
	bObj.addScriptTag();
}

currencies = null;
InstaCalc.loadCurrencies = function(data){
    if (currencies != null){
	  return;
	}
	
	currencies = {};
    var dataset = data["frbny:DataSet"]; // this is an array of currency values

	// populate currency data
	for (i = 0; i < dataset.length; i++){
	  var curr = dataset[i];
	  var unit; // string for unit
	  var rate; // conversion rate to USD
	  
	  rate = curr["frbny:Obs"]["frbny:OBS_VALUE"];
	  
	  if (curr.UNIT == "USD"){ // currency in terms of USD
	     unit = curr["frbny:Key"]["frbny:CURR"].toLowerCase(); // lowercase for all units  
		 currencies[unit] = rate;
	  }
	  else{
	     unit = curr.UNIT.toLowerCase();
		 currencies[unit] = 1/rate;
	  }
	}
	
	currencies.usd = 1; // base unit 
	
	Unit.currencies = currencies;
}

// callback from getting the currency data
function processData(jsonData) {     
     //alert("called");
	 getCurrencyData(jsonData);
}

loadCurrencyData();