// Resistor Calculators 
// Copyright (c) 2008, CEPD Inc.
// http://www.cepd.com

function log10(val) {
  return Math.log(val)/Math.log(10);
}

// attempt to get around toy language bugs
function round(value, digits) {
  var ivalue;
  var power;
  
  power = Math.pow(10,digits);
  value = value * power;
  ivalue = Math.floor(value);
  if ((value-ivalue) > 0.499999999) {
    ivalue++;
 }
  ivalue=ivalue/power;

  return ivalue;
}

// go thru the resistor list and find the best fit, this simple approach avoids some headaches with Javascript math
// standard familes are of the form R = d * 10^(i/N)
// where d is a decade (10,100,1000,etc.)
// i = 0,1,2,3....N
// and N is a family numer 192 (<1%), 96 (1%), 48 (2%), 24 (5%), 12 (10%)
function BestR(desired, familyN) {

  var E6ray = [1,1.5,2.2,3.3,4.7,6.8,10,15];
  var E12ray = [1,1.2,1.5,1.8,2.2,2.7,3.3,3.9,4.7,5.6,6.8,8.2,10,12];
  var E24ray = [1,1.1,1.2,1.3,1.5,1.6,1.8,2.0,2.2,2.4,2.7,3.0,3.3,3.6,3.9,4.3,4.7,5.1,5.6,6.2,6.8,7.5,8.2,9.1,10,11];
  var j,RFrac, RInt, logR, start;
  
  logR = log10(desired);  
  RInt = Math.floor(logR);
  RFrac = logR-RInt;

  start = Math.floor(RFrac*familyN) - 2;  // good starting point, will be less than desired
  this.bestLow = 10 * Math.pow(10,RInt);    

  for (j=start; j<(familyN+2); j++) {
    if (familyN >= 48) {    // E48 and higher are computable  
      this.bestHi = Math.pow(10,j/familyN);
      this.bestHi = round(this.bestHi,2);
    }
    else if (familyN == 24) {   
      this.bestHi = E24ray[j];
    }
    else if (familyN == 12) {   
      this.bestHi = E12ray[j];
    }
    else if (familyN == 6) {  
      this.bestHi = E6ray[j];
    }
    
    this.bestHi = this.bestHi * Math.pow(10,RInt);
    
    this.bestHi = round(this.bestHi,2);

    if (this.bestHi > desired) {break;}
    this.bestLow = this.bestHi;
  }
  
  this.LowErr = (this.bestLow - desired)/desired * 100;
  this.LowErr = this.LowErr.toFixed(1);
  this.HighErr = (this.bestHi - desired)/desired * 100;
  this.HighErr = this.HighErr.toFixed(1);
}


function CalcBestR(form) {
	var ans;
  ans = new BestR(form.Desired.value,form.Familyselect.value);

  form.Low.value = ans.bestLow;
  form.High.value = ans.bestHi;
  form.LowE.value = ans.LowErr.toString() + "%";
  form.HighE.value = ans.HighErr.toString()+ "%";
}

//Resistor Divider//

var RdivBtnSel = 2;
function CalcRdivider(form) {
var Vin,Vout;
var R1,R2;
  switch (RdivBtnSel) {
    case 1:
      Vout = parseFloat(form.Vout.value);
      R1 = parseFloat(form.R1.value);
      R2 = parseFloat(form.R2.value);
      form.Vin.value = ((Vout/R2*(R1+R2))).toFixed(3);
      break;
    case 2:
      Vin = parseFloat(form.Vin.value);
      R1 = parseFloat(form.R1.value);
      R2 = parseFloat(form.R2.value);
      form.Vout.value = (Vin*R2/(R1 + R2)).toFixed(3);
      break;
    case 3:
      Vin = parseFloat(form.Vin.value);
      Vout = parseFloat(form.Vout.value);
      R2 = parseFloat(form.R2.value);
      form.R1.value = ((Vin-Vout)/Vout*R2).toFixed(2);
      break;
    case 4:
      Vin = parseFloat(form.Vin.value);
      Vout = parseFloat(form.Vout.value);
      R1 = parseFloat(form.R1.value);
      form.R2.value = (Vout/(Vin-Vout)*R1).toFixed(2);
      break;
    default:
      break;
  }
}

//Resistors in Parallel//

var RparaB = 1;
function CalcRparallel(form) {
var R1,R2, R1pR2;
  switch (RparaB) {   // find R1 || R2
    case 1:
      R1 = parseFloat(form.R1.value);
      R2 = parseFloat(form.R2.value);
      if ((R1===0) && (R2===0)) {
        form.R1pR2.value = "0.000";
        return;
      }
      form.R1pR2.value = (R1*R2/(R1 + R2)).toFixed(3);
      break;
    case 2:
      R2 = parseFloat(form.R2.value);
      R1pR2 = parseFloat(form.R1pR2.value);
      if (R2<R1pR2) {
        form.R1.value = "????";
        return;
      }
      form.R1.value = (1/(1/R1pR2-1/R2)).toFixed(3);
      break;
    default:
      break;
  }
}

//RC calculator//

function CalcRC(form){
  var R;
  var C;
  var F;

  C =form.Cin.value * Math.pow(10,form.Csunits.value);
  R =form.Rin.value * Math.pow(10,form.Rsunits.value);
  F = 1/(2*Math.PI*R*C);
  form.Tout.value = (R*C).toExponential(4) + " s";
  form.Fout.value = F.toExponential(4) + " Hz";
}

