/***************************************************************************
 *   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['SquareMile'] = [3.86102158593e-07,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['CubicInch'] = [61023.74409473228,0];
  unit['CubicFoot'] = [35.31466672148859,0];
  unit['CubicYard'] = [1.307950619314392, 0];
  unit['CubicMillimeter'] = [1000000000, 0];
  unit['CubicCentimeter'] = [1000000,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();
  set_category('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 set_category(unit)
{
  var s = "";
  current_unit = "";
  for (var i in unit_hash[unit]) {
    current_unit = i;
    break;
  }
  button = document.getElementById(unit + "_button");
  current_category = button;
  current_category.style.fontWeight = "bold";
  process_entry(document.getElementById('value').value);
}

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,n)
{
  while(s.length < n) {
    s += " ";
  }
  return s;//.replace(/ /g,"&nbsp;");
}

function set_selection_style(s,state)
{
  e = document.getElementById(s + "_selector");
  e.style.background = (state)?"black":"white";
  e.style.color = (state)?"white":"black";
}

function process_buttons(e)
{
  button = get_target(e);
  cn = button.className.replace(/(.*) .*/,"$1");
  switch(cn) {
    case "categorybutton":
    if(current_category) {
      current_category.style.fontWeight = "normal";
    }
    txt = get_text(button);
    set_category(txt);
    break;
    case "selector":
    if(current_unit) {
      set_selection_style(current_unit,false);
      document.getElementById('value').focus();
    }
    current_unit = button.id.replace(/(.*)_.*/,"$1");
    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 keyPressed(e)
{
  key = (e.which)?e.which:event.keyCode;
  if(key == 13) {
    txt = document.getElementById('value').value;
    process_entry(txt);
  }
}

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

function format_num(key,n,p)
{
  var fp = n.toFixed(p);
  if(fp == 0 || (/e/.test(fp)) || fp.indexOf(".") < 0 || fp.length > p+8 || (/^0.0/.test(fp))) {
    fp = n.toExponential(p);
    fp = fp.replace(/(e[+|-])(\d)$/,"$10$2");
    fp = fp.replace(/0+e[+|-]0+$/, "");
    if(fp.indexOf("e") < 0) {
      fp += make_tab(4);
    }
  }
  else {
    fp = fp.replace(/\.[0|e|+|-]+$/, ".0" + make_tab(p-1));
    fp += make_tab(4);
  }
  while(fp.length < 32) {
    fp = " " + fp;
  }
  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);
  document.getElementById('unit_field').innerHTML = "Unit: " + current_unit;
  input_key = current_unit; // get_text(current_unit);
  input_vals = unit_hash[cat_key][input_key];
  out += "<table width=\"100%\">\n";
  n = 0;
  for ( unit_key in unit_hash[cat_key]) {
    oks = format_text(unit_key,32);
    output_vals = unit_hash[cat_key][unit_key];
    v = ((s - input_vals[1]) * output_vals[0] / input_vals[0]) + output_vals[1];
    fp = format_num(unit_key,v,8);
    var ss = oks+fp;
    ss = ss.replace(/ /g,"&nbsp;");
    rowname = "row" + n % 2;
    out += "<tr><td class=\"selector " + rowname + "\" ID=\"" + unit_key + "_selector\">" + ss + "</td></tr>\n";
    n++;
  }
  out += "</table>";
  ow = document.getElementById('unitWindow');
  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();
}


