/***************************************************************************
 *   Copyright (C) 2006, Paul Lutus                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

if (typeof document.attachEvent!='undefined') {
   window.attachEvent('onload',init);
   document.attachEvent('onclick',mouseClick);
   document.attachEvent('onkeydown',keyPressed);
}
else {
   window.addEventListener('load',init,false);
   document.addEventListener('click',mouseClick,false);
   document.addEventListener('keydown',keyPressed,false);
}

function define_units() {
   unit_hash = {};
   unit = {};
   unit['Acre'] = [0.0002471053814671653,0];
   unit['Are'] = [0.009884215258686614,0];
   unit['Barn'] = [1e28,0];
   unit['Hectare'] = [0.0001,0];
   unit['Rood'] = [0.0009884215258686613,0];
   unit['Section'] = [3.8610215854244587e-7,0];
   unit['SquareCentimeter'] = [10000,0];
   unit['SquareFoot'] = [10.763910416709722,0];
   unit['SquareInch'] = [1550.0031000062,0];
   unit['SquareMeter'] = [1,0];
   unit['Township'] = [1.0725059959512385e-8,0];
   unit_hash['Area'] = unit;
   unit = {};
   unit['BTU'] = [0.000947813394498891,0];
   unit['Calorie'] = [0.23884589662749595,0];
   unit['ElectronVolt'] = [6.241506363094028e18,0];
   unit['Erg'] = [10000000,0];
   unit['Joule'] = [1,0];
   unit['Kilocalorie'] = [0.00023884589662749595,0];
   unit['Rydberg'] = [4.5873663929538054e17,0];
   unit['Therm'] = [9.47813394498891e-9,0];
   unit_hash['Energy'] = unit;
   unit = {};
   unit['Dyne'] = [100000,0];
   unit['GramWeight'] = [101.97162129779284,0];
   unit['KilogramForce'] = [0.10197162129779283,0];
   unit['KilogramWeight'] = [0.10197162129779283,0];
   unit['Newton'] = [1,0];
   unit['PoundForce'] = [0.2248090247334889,0];
   unit['PoundWeight'] = [0.2248090247334889,0];
   unit['Poundal'] = [7.233011464323171,0];
   unit['TonForce'] = [0.0001003610992350477,0];
   unit_hash['Force'] = unit;
   unit = {};
   unit['AU'] = [6.684587124055793e-12,0];
   unit['Bolt'] = [0.027340332458442695,0];
   unit['Cable'] = [0.004556722076407116,0];
   unit['Caliber'] = [3937.0078740157483,0];
   unit['Centimeter'] = [100,0];
   unit['Chain'] = [0.049709695378986715,0];
   unit['Cicero'] = [221.66666666666666,0];
   unit['Cubit'] = [2.1872265966754156,0];
   unit['Didot'] = [2660,0];
   unit['DidotPoint'] = [2660,0];
   unit['Ell'] = [0.8748906386701663,0];
   unit['Fathom'] = [0.5468066491688539,0];
   unit['Fermi'] = [1e15,0];
   unit['Foot'] = [3.2808398950131235,0];
   unit['Furlong'] = [0.004970969537898671,0];
   unit['Hand'] = [9.84251968503937,0];
   unit['Inch'] = [39.37007874015748,0];
   unit['Kilometer'] = [0.001,0];
   unit['League'] = [0.000207123730745778,0];
   unit['LightYear'] = [1.0570265842185932e-16,0];
   unit['Link'] = [4.9709695378986725,0];
   unit['Meter'] = [1,0];
   unit['Micron'] = [1000000,0];
   unit['Mil'] = [39370.07874015748,0];
   unit['Mile'] = [0.0006213711922373339,0];
   unit['Millimeter'] = [1000,0];
   unit['NauticalMile'] = [0.0005399568034557236,0];
   unit['Parsec'] = [3.2407557442395566e-17,0];
   unit['Perch'] = [0.1988387815159469,0];
   unit['Pica'] = [236.2204724409449,0];
   unit['Point'] = [2834.6456692913384,0];
   unit['Pole'] = [0.1988387815159469,0];
   unit['Rod'] = [0.1988387815159469,0];
   unit['Rope'] = [0.16404199475065617,0];
   unit['Skein'] = [0.009113444152814232,0];
   unit['Span'] = [4.374453193350831,0];
   unit['Stadion'] = [0.005274662210632031,0];
   unit['Stadium'] = [0.005413927219493603,0];
   unit['StatuteMile'] = [0.0006213711922373339,0];
   unit['SurveyMile'] = [0.0006213711922373339,0];
   unit['XUnit'] = [9.980039920159682e12,0];
   unit['Yard'] = [1.0936132983377078,0];
   unit_hash['Length'] = unit;
   unit = {};
   unit['AMU'] = [6.0221366516751604e26,0];
   unit['AtomicMassUnit'] = [6.0221366516751604e26,0];
   unit['Dalton'] = [6.0221366516751604e26,0];
   unit['Geepound'] = [0.06852177964766101,0];
   unit['Gram'] = [1000,0];
   unit['Kilogram'] = [1,0];
   unit['MetricTon'] = [0.001,0];
   unit['Quintal'] = [0.01,0];
   unit['Slug'] = [0.06852177964766101,0];
   unit['SolarMass'] = [5.0273993263284895e-31,0];
   unit['Tonne'] = [0.001,0];
   unit_hash['Mass'] = unit;
   unit = {};
   unit['Atmosphere'] = [9.869232667160129e-6,0];
   unit['Bar'] = [0.00001,0];
   unit['Barye'] = [10,0];
   unit['InchMercury'] = [0.00029529971444517615,0];
   unit['MillimeterMercury'] = [0.007500637554192106,0];
   unit['PSI'] = [0.0001450377438972831,0];
   unit['Pascal'] = [1,0];
   unit['Torr'] = [0.007500637554192106,0];
   unit_hash['Pressure'] = unit;
   unit = {};
   unit['Centigrade'] = [1,-273.15];
   unit['Fahrenheit'] = [1.8,-459.67];
   unit['Kelvin'] = [1,0];
   unit['Rankine'] = [1.8,0];
   unit_hash['Temperature'] = unit;
   unit = {};
   unit['Century'] = [3.1709791983764586e-10,0];
   unit['Day'] = [0.000011574074074074073,0];
   unit['Decade'] = [3.1709791983764586e-9,0];
   unit['Fortnight'] = [8.267195767195768e-7,0];
   unit['Hour'] = [0.0002777777777777778,0];
   unit['Millennium'] = [3.1709791983764586e-11,0];
   unit['Minute'] = [0.016666666666666666,0];
   unit['Month'] = [3.8051750380517503e-7,0];
   unit['Second'] = [1,0];
   unit['SiderealSecond'] = [1.0027378754952523,0];
   unit['SiderealYear'] = [3.168753604748751e-8,0];
   unit['TropicalYear'] = [3.168876540268821e-8,0];
   unit['Week'] = [1.6534391534391535e-6,0];
   unit['Year'] = [3.1709791983764586e-8,0];
   unit_hash['Time'] = unit;
   unit = {};
   unit['Foot/Hour'] = [11811.023622047243,0];
   unit['Foot/Minute'] = [196.8503937007874,0];
   unit['Foot/Second'] = [3.2808398950131235,0];
   unit['Furlong/Fortnight'] = [6012.884753042234,0];
   unit['Kilometer/Hour'] = [3.6,0];
   unit['Kilometer/Minute'] = [0.06,0];
   unit['Kilometer/Second'] = [0.001,0];
   unit['Meter/Hour'] = [3600,0];
   unit['Meter/Minute'] = [60,0];
   unit['Meter/Second'] = [1,0];
   unit['Mile/Hour'] = [2.2369362920544025,0];
   unit['Mile/Minute'] = [0.03728227153424004,0];
   unit['Mile/Second'] = [0.0006213711922373339,0];
   unit_hash['Velocity'] = unit;
   unit = {};
   unit['Bag'] = [9.458948164964056,0];
   unit['Barrel'] = [6.289308176100628,0];
   unit['BoardFoot'] = [423.7760006578631,0];
   unit['Bucket'] = [66.04307910798519,0];
   unit['Bushel'] = [28.37684449489217,0];
   unit['Butt'] = [2.096605685967784,0];
   unit['Cord'] = [0.2758958337616296,0];
   unit['CubicCentimeter'] = [1000000,0];
   unit['CubicFoot'] = [35.31466672148859,0];
   unit['CubicInch'] = [61023.74409473228,0];
   unit['CubicMeter'] = [1,0];
   unit['Cup'] = [4226.757062911052,0];
   unit['Drop'] = [3.3333333333333336e7,0];
   unit['Ephah'] = [25.223861773237484,0];
   unit['Fifth'] = [1320.8615821597039,0];
   unit['Firkin'] = [24.44102758878753,0];
   unit['FluidDram'] = [270512.45202630735,0];
   unit['FluidOunce'] = [33814.05650328842,0];
   unit['Gallon'] = [264.17231643194077,0];
   unit['Gill'] = [8453.514125822105,0];
   unit['Hogshead'] = [4.193211371935568,0];
   unit['Jeroboam'] = [330.21539553992596,0];
   unit['Jigger'] = [22542.704335525614,0];
   unit['Last'] = [0.34371182650526877,0];
   unit['Liter'] = [1000,0];
   unit['Magnum'] = [528.3446328638815,0];
   unit['Minim'] = [1.623074712157844e7,0];
   unit['Noggin'] = [8453.514125822105,0];
   unit['Omer'] = [252.23861773237482,0];
   unit['Pint'] = [2113.378531455526,0];
   unit['Pony'] = [45085.40867105123,0];
   unit['Puncheon'] = [3.144908528951676,0];
   unit['Quart'] = [1056.689265727763,0];
   unit['RegisterTon'] = [0.3531466672148859,0];
   unit['Seam'] = [3.547105561861521,0];
   unit['Shot'] = [33814.05650328842,0];
   unit['Stere'] = [1,0];
   unit['Tablespoon'] = [67628.11300657684,0];
   unit['Teaspoon'] = [202884.33901973054,0];
   unit['Tun'] = [1.048302842983892,0];
   unit['UKGallon'] = [219.96924829908775,0];
   unit['UKPint'] = [1759.754760576566,0];
   unit['WineBottle'] = [1319.8222252255512,0];
   unit_hash['Volume'] = unit;
   unit = {};
   unit['AssayTon'] = [34.285322453457674,0];
   unit['AvoirdupoisOunce'] = [35.27399072294044,0];
   unit['AvoirdupoisPound'] = [2.2046244201837775,0];
   unit['Bale'] = [0.004409248840367555,0];
   unit['Carat'] = [5000.,0];
   unit['Cental'] = [0.022046244201837775,0];
   unit['Drachma'] = [232.97532791277402,0];
   unit['Grain'] = [15432.336918779609,0];
   unit['GrossHundredweight'] = [0.019684146608783728,0];
   unit['Hundredweight'] = [0.019684146608783728,0];
   unit['Kilogram'] = [1,0];
   unit['Libra'] = [3.067757561255449,0];
   unit['Mina'] = [2.329730973458499,0];
   unit['NetHundredweight'] = [0.022046244201837775,0];
   unit['Obolos'] = [1397.858480807403,0];
   unit['Ounce'] = [35.27399072294044,0];
   unit['Pennyweight'] = [643.0868167202573,0];
   unit['Pondus'] = [3.0677730437823914,0];
   unit['Pound'] = [2.2046244201837775,0];
   unit['Shekel'] = [70.92198581560284,0];
   unit['ShortHundredweight'] = [0.022046244201837775,0];
   unit['ShortTon'] = [0.0011023122100918888,0];
   unit['Stone'] = [0.15747317287026982,0];
   unit['Talent'] = [0.038828849557641654,0];
   unit['Ton'] = [0.0009842073304391866,0];
   unit['TroyOunce'] = [32.151239430280036,0];
   unit['Wey'] = [0.008748509603903878,0];
   unit_hash['Weight'] = unit;
}

current_category = false;
current_unit = false;

function init() {
   define_units();
   fill_button_bar();
   fill_unit_window('Length');
}

function debug_object(e)
{
   var out = "";
   for (var i in e) {
      out += "." + i + "<br/>";
      for (var j in e[i]) {
         out += "." + i + "." + j + "<br/>";
      }
   }
   // document.getElementById('debugWindow').innerHTML = out;
}

function fill_unit_window(unit)
{
   var s = "";
   first = false;
   for (var i in unit_hash[unit]) {
      if(!first) {
         first = i;
      }
      s += "<div class=\"selector\" ID=\"" + i + "_selector\">" + i + "</div>\n";
   }
   w = document.getElementById('unitWindow');
   w.innerHTML = s;
   button = document.getElementById(unit + "_button");
   current_category = button;
   current_category.style.fontWeight = "bold";
   current_unit = document.getElementById(first + "_selector");
   set_selection_style(current_unit,true);
   process_entry(document.getElementById('value').value);
   // this hack forces MSIE to update itself
temp = w.style.fontSize;
   w.style.fontSize = 36;
   w.style.fontSize = temp;
}

function fill_button_bar()
{
   out = "<table width=100%><tr>";
   for (var i in unit_hash) {
      out += "<td><div class=\"categorybutton\" ID=\"" + i + "_button\">" + i + "</div></td>";
   }
   out += "</tr></table>";
   document.getElementById('buttonbar').innerHTML = out;
}

// some MSIE compatibility hacks

function get_text(button)
{
   return button.textContent?button.textContent:button.innerText;
}

function get_target(e)
{
   return e.originalTarget?e.originalTarget:e.srcElement;
}

function format_text(s)
{
   return s.replace(/ /,"&nbsp;");
}

function set_selection_style(e,state)
{
   e.style.background = (state)?"black":"white";
   e.style.color = (state)?"white":"black";
   e.style.fontWeight = (state)?"bold":"normal";
}

function process_buttons(e)
{
   button = get_target(e);
   switch(button.className) {
      case "categorybutton":
      if(current_category) {
         current_category.style.fontWeight = "normal";
      }
      txt = get_text(button);
      fill_unit_window(txt);
      break;
      case "selector":
      if(current_unit) {
         set_selection_style(current_unit,false);
         document.getElementById('value').focus();
      }
      current_unit = button;
      text = document.getElementById('value').value;
      process_entry(text);
      break;
      case "compbutton":
         text = document.getElementById('value').value;
      process_entry(text);
      break;
   }
}

function mouseClick(e) {
   process_buttons(e);
}

function make_tab(n)
{
   var out = "";
   for(var k = 0;k < n;k++) {
      out += "&nbsp;";
   }
   return out;
}

function format_num(key,n,p)
{
   var fp = n.toFixed(p);
   if(fp == 0 || (/e/.test(fp)) || fp.indexOf(".") < 0 || fp.length > 10 || (/^0.0/.test(fp))) {
      fp = n.toExponential(p);
      fp = fp.replace(/(e[+|-])(\d)$/,"$10$2");
      fp = fp.replace(/0+e[+|-]0+$/, make_tab(p));
      if(fp.indexOf("e") < 0) {
         fp += make_tab(4);
      }
   }
   else {
      fp = fp.replace(/\.[0|e|+|-]+$/, "." + make_tab(p));
      fp += make_tab(4);
   }
   return fp;
}

function process_entry(s)
{
   var out = "";
   if(s.length == 0) {
      s = "1.0";
      document.getElementById('value').value = s;
   }
   cat_key = get_text(current_category);
   input_key = get_text(current_unit);
   input_vals = unit_hash[cat_key][input_key];
   out += "<table width=85%>\n";
   for ( output_key in unit_hash[cat_key]) {
      oks = format_text(output_key);
      output_vals = unit_hash[cat_key][output_key];
      v = ((s - input_vals[1]) * output_vals[0] / input_vals[0]) + output_vals[1];
      fp = format_num(output_key,v,6);
      out += "<tr><td class=\"mono\" width=\"50%\" style=\"text-align: right\">" + fp + "</td><td  class=\"mono\">&nbsp;&nbsp;</td><td  class=\"mono\" width=50%>" + oks + "</td></tr>\n";
   }
   out += "</table>";
   ow = document.getElementById('outputWindow');
   ow.innerHTML = out;
   // MSIE hack to force update
   temp = ow.style.fontSize;
   ow.style.fontSize = 36;
   ow.style.fontSize = temp;
   set_selection_style(current_unit,true);
   document.getElementById('value').focus();
}

function keyPressed(e)
{
   key = (e.which)?e.which:event.keyCode;
   if(key == 13) {
      txt = document.getElementById('value').value;
      process_entry(txt);
   }
}

