/**
 * @author aherron
 */

$(document).ready(function() {
  FuelCalc.init();
});

window.FuelCalc = function() {
  
  var ENGLISH_TEXT = [
    ['#fuel-cost-title', 'Fuel cost per gallon'],
    ['#fuel-efficiency-title', 'Miles per gallon'],
    ['#distance-per-year-title', 'Average miles driven per year']
  ];
  var METRIC_TEXT = [
    ['#fuel-cost-title', 'Fuel cost per liter'],
    ['#fuel-efficiency-title', 'Liters per 100 kilometers'],
    ['#distance-per-year-title', 'Average kilometers driven per year']
  ];
  
  var currentMeasurement = "english";
  
  var toggleMeasureUnit = function() {
    switch (currentMeasurement) {
      case "english":
        currentMeasurement = "metric";
        break;
      case "metric":
        currentMeasurement = "english";
        break;
      default:
        currentMeasurement = "english";
    }
  };
  
  var updateLangNav = {
    english: function() {
      $("#lang-nav-metric").removeClass('this');
      $("#lang-nav-english").addClass('this');
    },
    metric: function() {
      $("#lang-nav-english").removeClass('this');
      $("#lang-nav-metric").addClass('this');
    }
  };
  
  var L100kmToMpg = function(num) {
    var newVal = (0.621371192 / (0.264172052 * num)) * 100;
    return newVal;
  };
  
  var MpgToL100km = function(num) {
    var newVal = 100 / ((1.609344 * num) / 3.78541178);
    return newVal;
  };
  
  var milesToKilometers = function(num) {
    return num * 1.609344;
  };
  
  var kilometersToMiles = function(num) {
    return num * 0.621371192;
  };
  
  var CPGtoCPL = function(num) {
    //num = Math.floor(num * 100);
    //var newCost = (Math.floor((num * 26.4172052)) / 10000)
    //return newCost;
    return num * 0.264172052;
  };
  
  var CPLtoCPG = function(num) {
    //num = Math.floor(num * 100);
    //var newCost = (num * 378.541178) / 10000;
    //return newCost;
    return num * 3.78541178;
  };
  
  var validateNumber = function(num) {
    if (typeof num == "string") {
      num = cleanCommas(num);
    }
    num = parseFloat(num);
    if (num > 0 && typeof num == 'number') {
      return true;
    } else {
      return false;
    }
  };
  
  var cleanCommas = function(value) {
    if (typeof value != "string") { return value; }
    value = value.replace(/,/g,'');
    return value;
  };
  
  var prettyNumber = function(num) {
  
    var numSplit = num.toString().split(".");
    var lessThan1K = numSplit[0].length % 3;
    var stringArr = [];
    if (lessThan1K) {
      stringArr.push(numSplit[0].substr(0,lessThan1K));
    }
    for (var i=lessThan1K;i<numSplit[0].length;i+=3){
      stringArr.push(numSplit[0].substr(i,3));
    }
    return stringArr.join(',') + (numSplit[1] ? "." + numSplit[1] : "");
  };
  
  var convertExistingValues = {
    english: function() {
      var curGasPrice = $('#fuel-cost-gas-raw').val();
      var curDieselPrice = $('#fuel-cost-diesel-raw').val();
      var curGasEff = $('#fuel-efficiency-gas').val();
      var curDieselEff = $('#fuel-efficiency-diesel').val();
      var curDistance = cleanCommas($('#distance-per-year').val());
            
      //convert cpl to cpg
      if (validateNumber(curGasPrice)) {
        var gas_cpg = CPLtoCPG(curGasPrice);
        $('#fuel-cost-gas-raw').val(gas_cpg);
        $('#fuel-cost-gas').val(Math.roundToPlace(gas_cpg, 2).toMoney());
        FuelCalc.updateGasPrice(true);
      }
      
      if (validateNumber(curDieselPrice)) {
        var d_cpg = CPLtoCPG(curDieselPrice);
        $('#fuel-cost-diesel-raw').val(d_cpg);
        $('#fuel-cost-diesel').val(Math.roundToPlace(d_cpg, 2).toMoney());
        FuelCalc.updateDieselPrice(true);
      }
      
      //convert L/100km to mpg      
      if (validateNumber(curGasEff)) {
        $('#fuel-efficiency-gas').val(Math.roundToPlace(MpgToL100km(curGasEff), 2));
      }
      
      if (validateNumber(curDieselEff)) {
        $('#fuel-efficiency-diesel').val(Math.roundToPlace(MpgToL100km(curDieselEff), 2));
      }
      
      //convert kilometers to miles
      if (validateNumber(curDistance)) {
        var miles = Math.round(kilometersToMiles(curDistance));
        $('#distance-per-year').val(prettyNumber(miles));
      }
    },
    metric: function() {
      var curGasPrice = $('#fuel-cost-gas-raw').val();
      var curDieselPrice = $('#fuel-cost-diesel-raw').val();
      var curGasEff = $('#fuel-efficiency-gas').val();
      var curDieselEff = $('#fuel-efficiency-diesel').val();
      var curDistance = cleanCommas($('#distance-per-year').val());
            
      //convert cpg to cpl
      if (validateNumber(curGasPrice)) {
        var gas_cpl = CPGtoCPL(curGasPrice);
        $('#fuel-cost-gas-raw').val(gas_cpl);
        $('#fuel-cost-gas').val(Math.roundToPlace(gas_cpl, 2).toMoney());
        FuelCalc.updateGasPrice(true);
      }
      
      if (validateNumber(curDieselPrice)) {
        var d_cpl = CPGtoCPL(curDieselPrice);
        $('#fuel-cost-diesel-raw').val(d_cpl);
        $('#fuel-cost-diesel').val(Math.roundToPlace(d_cpl, 2).toMoney());
        FuelCalc.updateDieselPrice(true);
      }
      
      //convert mpg to L/100km     
      if (validateNumber(curGasEff)) {
        $('#fuel-efficiency-gas').val(Math.roundToPlace(L100kmToMpg(curGasEff), 2));
      }
      
      if (validateNumber(curDieselEff)) {
        $('#fuel-efficiency-diesel').val(Math.roundToPlace(L100kmToMpg(curDieselEff), 2));
      }
      
      //convert kilometers to miles
      var kilometers = Math.round(milesToKilometers(curDistance));
      if (validateNumber(curDistance)) {
        $('#distance-per-year').val(prettyNumber(kilometers));
      }   
    }
  };
  
  var updateTitles = {
    english: function() {
      $("#distance-per-year").removeClass('metric');
      for (var i in ENGLISH_TEXT) {
        $(ENGLISH_TEXT[i][0]).html(ENGLISH_TEXT[i][1]);
      }
    },
    metric: function() {
      $("#distance-per-year").addClass('metric');
      for (var i in METRIC_TEXT) {
        $(METRIC_TEXT[i][0]).html(METRIC_TEXT[i][1]);
      }
    }
  };
  
  var updateFuelPrice = function(source, target, calc) {
    var sp = $(source).val();
    
    //make sure we're dealing with a price we can handle
    if (parseFloat(sp) > 9.99) {
      alert('Please make sure your fuel price is between 0.01 and 9.99');
      $(source).val('');
      sp = '';
    }
    var tens = sp.substr(0,1) || "0";
    var tenths = sp.substr(2,1) || "0";
    var hundreths = sp.substr(3,1) || "0";
    
    if (calc != true) $(source+'-raw').val(sp);
    
    var p = $(target).find('li').not('.dot').find('p');
    $(p[0]).html(tens);
    $(p[1]).html(tenths);
    $(p[2]).html(hundreths);
  };
  
  var calculateGasCost = {
    english: function(){
      var fuelCostGas = $('#fuel-cost-gas-raw').val();
      var fuelEffGas = $('#fuel-efficiency-gas').val();
      var distancePerYear = cleanCommas($('#distance-per-year').val());
      
      var costPerYearGas = (distancePerYear / fuelEffGas) * fuelCostGas;
      return Math.roundToPlace(costPerYearGas, 2);
    },
    metric: function(){
      var fuelCostGas = $('#fuel-cost-gas-raw').val();
      var fuelEffGas = $('#fuel-efficiency-gas').val();
      var distancePerYear = cleanCommas($('#distance-per-year').val());
      
      var costPerYearGas = ((fuelEffGas / 100) * distancePerYear) * fuelCostGas;
      return Math.roundToPlace(costPerYearGas, 2);
    }
  };
    
  var calculateDieselCost = {
    english: function() {
      var fuelCostDiesel = $('#fuel-cost-diesel-raw').val();
      var fuelEffDiesel = $('#fuel-efficiency-diesel').val();
      var distancePerYear = cleanCommas($('#distance-per-year').val());
      
      var costPerYearDiesel = (distancePerYear / fuelEffDiesel) * fuelCostDiesel;
      return Math.roundToPlace(costPerYearDiesel, 2);
    },
    metric: function() {
      var fuelCostDiesel = $('#fuel-cost-diesel-raw').val();
      var fuelEffDiesel = $('#fuel-efficiency-diesel').val();
      var distancePerYear = cleanCommas($('#distance-per-year').val());
      
      var costPerYearDiesel = ((fuelEffDiesel / 100) * distancePerYear) * fuelCostDiesel;
      return Math.roundToPlace(costPerYearDiesel, 2);            
    }
  };
  
  var validateFieldsForEmpty = function() {
    var validated = true;
    var checkFields = [
        $('#fuel-cost-gas-raw').val(),
        $('#fuel-cost-diesel-raw').val(),
        $('#fuel-efficiency-gas').val(),
        $('#fuel-efficiency-diesel').val(),
        cleanCommas($('#distance-per-year').val())
      ];
    for (var f in checkFields) {
      if (!validateNumber(checkFields[f])) {
        validated = false;
      }
    }
    
    return validated;
  }
  
  return {
    
    init: function() {
        
        //set measurement handlers
        $('#lang-nav ul').click(this.changeMeasurements);
        
        //update gas price
        $('#fuel-cost-gas').keyup(this.updateGasPrice);
        
        //update diesel price
        $('#fuel-cost-diesel').keyup(this.updateDieselPrice);
        
        //set calculate button handler
        $('#calculate-cost-per-year').click(this.calculateCostPerYear);
        
        //set embed code handler
        $('#widget-embed').click(this.embedWidget);
        
        //set link for diesel tech forum homepage
        $('#link-diesel-forum').click(function() {
          window.open('http://www.dieselforum.org/');
          return false;
        });
        
        //set link for diesel vehicles for sale
        $('#link-diesel-vehicles').click(function() {
          window.open('http://www.dieselforum.org/where-is-diesel/cars-trucks-suvs/diesels-for-sale-in-the-us/');
          return false;
        });
    },
    
    changeMeasurements: function() {
      toggleMeasureUnit();
      updateLangNav[currentMeasurement]();
      updateTitles[currentMeasurement]();
      convertExistingValues[currentMeasurement]();
    },
    
    updateGasPrice: function(calc) {
      updateFuelPrice('#fuel-cost-gas', '#fuel-cost-digits-gas', calc);
    },
    
    updateDieselPrice: function(calc) {
      updateFuelPrice('#fuel-cost-diesel', '#fuel-cost-digits-diesel', calc);
    },
    
    calculateCostPerYear: function() {
      if (!validateFieldsForEmpty()) {
        alert('Please make sure all fields are filled in.');
        return;
      }
      
      var gasCostPerYear = calculateGasCost[currentMeasurement]();
      var dieselCostPerYear = calculateDieselCost[currentMeasurement]();
      var savingsPerYear = gasCostPerYear - dieselCostPerYear;
      
      $('#fuel-cost-per-year-gas').html(prettyNumber(gasCostPerYear.toMoney()));
      $('#fuel-cost-per-year-diesel').html(prettyNumber(dieselCostPerYear.toMoney()));
      $('#fuel-cost-per-year-savings').html(prettyNumber(savingsPerYear.toMoney()));
      
      return false;
    },
    
    embedWidget: function() {
      window.open('http://widgets.mslideas.com/dieselcalculator/');
      return false;
    }
  };
  
}();

Number.prototype.toMoney = function () {
    var mnt = this;
    mnt -= 0;
    mnt = (Math.roundToPlace(mnt, 2));
    return (mnt == Math.floor(mnt)) ? mnt + '.00' 
              : ( (mnt*10 == Math.floor(mnt*10)) ? 
                       mnt + '0' : mnt);
};

Math.roundToPlace = function(num, places) {
  var pl = 1;
  for (var i=0;i<places;i++) {
    pl *= 10;
  }
  return (Math.round(num * pl) / pl);
};
