/* JavaScript-Teil des Programmes Transmission Line Calculator tlc.htm/tlc.js. 
   Zur Berechnung von Wellenwiderstand, Induktivitäts- und Kapazitätsbelag 
   ungewöhnlicher Strukturen. (c) Hartwig Harm, DH2MIC, http://dh2mic.darc.de/ 
   Englich version included. Stand: 22. April 2018  */

// Globale Variablen fuer Strukturen 0 mit 8
  var Kwerte = new Array (1.0,1.08,1.10,1.17,1.4,1.2732,1.28,2.0,-2.0,1.078,1.08,1.08);
  // var Mcalc = new Array [3][3];
  var Interpolation = new Array ("Z-Interpolation", "k-Interpolation", "N\u00E4herung",
      "Z-Interpolation", "k-Interpolation", "Approximation");
  var kStruktur = new Array ("Rundes Rohr", "Quadratisches Rohr", "Rechteckiges Rohr", 
      "U-f\u00F6rmige Schiene", "L-f\u00F6rmige Schiene", "Zwei W\u00E4nde gleich weit weg", 
      "Zwei W\u00E4nde ungleich weit weg", "Eine leitende Wand", "Zweidrahtleitung",
      "Quadr. Rohr 1946 k=1.078", "Quadr. Rohr 1946 k=1.080","Quadratisches Rohr 1956",
      "Round Conductor", "Square Conductor", "Rectangular Conductor",
      "U-shaped Conductor", "L-shaped Conductor", "Two Planes equally apart", 
      "Two Planes unequally apart", "Single wire above Plane", "two-wire line", 
      "Square Conductor 1946 k=1.078", "Square Conductor 1946 k=1.080", "Square Conductor 1956");
  var Meldung = new Array (" Bitte geben Sie beim 'Durchmesser' und beiden 'Abstand' Feldern einen Wert ein. ",
      " Bitte geben Sie beim 'Durchmesser' und 'Abstand a' einen Wert ein. ", 
      " Bitte geben Sie auch bei 'Abstand b' einen Wert ein. ", 
      " Bitte geben Sie f\u00FCr Epsilon einen g\u00FCltigen Wert ein. ", 
      " ist keine g\u00FCltige Zahlenangabe. Bitte korrigieren! ", 
      " ist kein g\u00FCltiger Wert f\u00FCr Epsilon", 
      " Durchmesser d muss gr\u00F6\u00DFer als 0 sein", 
      " Abstand a muss gr\u00F6\u00DFer als der halbe Durchmesser sein", 
      " Abstand b muss gr\u00F6\u00DFer als der halbe Durchmesser sein", 
      " b muss >= a sein. Zur Berechnung vertausche ich die Werte von a und b.",
      "Zur Berechnung wurden die Werte von a und b vertauscht.",
      " Numbers required for 'Diameter' and both 'Distance' fields. ",
      " Numbers required for 'Diameter' and 'Distance a' fields. ", 
      " Please enter a number for 'Distance b' too. ", 
      " Please enter a valid number for Epsilon. ", 
      " is not a valid number. Please check and replace! ", 
      " is no valid value for Epsilon", 
      " Diameter d must be higher than 0 ", 
      " Distance a must be higher than half the Diameter", 
      " Distance b must be higher than half the Diameter", 
      " b must be >= a. For calculation purposes I will exchange the values of a and b.",
      "For calculation purposes values of a and b have been exchanged." ) 
  var RefSystem = 0;
  var k = 0.0;
  var Ztxt="", Cstxt="", Lstxt="", Ktxt="";
  var Hinweis=""; 
  var Korrtxt="";
  var Wertin = new Array ("", "", "", "", ""); 	 // Eingabewerte als String

  var Formel = 0;      // Berechnungsverfahren Z- oder k-Interpolation oder Näherungsformel
  var Sprache = 0;
  var Formelindex = 5.0;

// Funktion dieses Aufrufes: Generelle Festlegungen, falls nötig. Hier: Sprache 0=de, 1=en

function InitmainFrame (Lang)
 {
  Sprache = Number(Lang);
  /*
  var text = "";
  if (navigator.cookieEnabled == true)  {
    text = "Cookies are enabled.";
  } else {
    text = "Cookies are not enabled.";
  }
  alert(text);
  */
 }

// Funktion zur mathematischen Berechnung fuer beide Seiten

function CalcZ (dtxt, atxt, btxt, etxt, ksptxt)
 {
  //var Wertin = new Array ("", "", "", "", ""); 	 // Eingabewerte als String
  var Wertdec = new Array (0.0, 0.0, 0.0, 0.0, 0.0); 
  var d=0.0, a=0.0, b=0.0, eps=0.0, ksp=0.0, p=0.0;
  var Z=0.0, Ls=0.0, Cs=0.0;
  var i1=0, temp=0, Eingabefehler=0, Bruch=0.0, kabs=0.0, Verh=0.0, pi=0.0;
  var Znaeherg=0.0, Zkinterp=0.0;
  var Rho=0.0, Rho4=0.0, Rho8=0.0, Rho12=0.0;            // für alte Formeln
  
  Hinweis = "";
  pi = Math.PI;

  Wertin[0] = dtxt;  //Durchmesser
  Wertin[1] = atxt;  //AbstandA
  Wertin[2] = btxt;  //AbstandB
  Wertin[3] = etxt;  //Epsilon
  Wertin[4] = ksptxt;  //k Speziell

  Wertin[0] = delspaces (Wertin[0]);
  Wertin[1] = delspaces (Wertin[1]);
  Wertin[2] = delspaces (Wertin[2]); 
  Wertin[3] = delspaces (Wertin[3]); 
  Wertin[4] = delspaces (Wertin[4]); 

  if ((Wertin[0] == "") || (Wertin[1] == ""))
   { 
    if (((RefSystem == 2) || (RefSystem == 3) || (RefSystem == 4) || (RefSystem == 6)) && (Wertin[2] == ""))
     {
      alert(Meldung[Sprache * 11 + 0]);
      // alert(" Bitte geben Sie beim 'Durchmesser' und beiden 'Abstand' Feldern einen Wert ein. ");
      Eingabefehler = 1;
     }
    else
     {
      alert(Meldung[Sprache * 11 + 1]);
      // alert(" Bitte geben Sie beim 'Durchmesser' und 'Abstand a' einen Wert ein. ");
      Eingabefehler = 1;
     }
   }
  else
   {
    if (((RefSystem == 2) || (RefSystem == 3) || (RefSystem == 4) || (RefSystem == 6)) && (Wertin[2] == ""))
     {
      alert(Meldung[Sprache * 11 + 2]);
      // alert(" Bitte geben Sie auch bei 'Abstand b' einen Wert ein. ");
      Eingabefehler = 1;
     }
   }

  if (Wertin[3] == "") 
   {
    alert(Meldung[Sprache * 11 + 3]);
    // alert(" Bitte geben Sie f\u00FCr Epsilon einen g\u00FCltigen Wert ein. ");
    Eingabefehler = 1;
    Wertin[3]="1";
   }

  for (i1=0; i1<5; i1++)
   {
    Wertin[i1] = delspaces (Wertin[i1]);
    if (Wertin[i1]=="")
     {
      Wertdec[i1]=0;
     }
    else
     {
      temp = checkvalidnumber(Wertin[i1]);
      Wertin[i1] = korrtxt;     // Zeichenkette mit Dezimalpunkt statt Komma
      //Wertbak[i1] = korrtxt; 

      if (temp < 0)		// -1 (falsches Zeichen), -2 (mehr als ein Punkt), [ -3 (leeres Feld)]
       {
        alert(" " + Wertin[i1] + Meldung[Sprache * 11 + 4]);
        // alert(" " + Wertin[i1] + " ist keine g\u00FCltige Zahlenangabe. Bitte korrigieren! ");
        Wertin[i1] = "0";	// Dummywert. Er erlaubt parseFloat() fehlerfrei zu arbeiten
        Eingabefehler = 1;
       }   
      Wertdec[i1]=parseFloat(Wertin[i1]);
     }
   } 

  d = Wertdec[0];
  a = Wertdec[1];
  b = Wertdec[2];
  eps = Wertdec[3];
  ksp = Wertdec[4];

  if ((eps < 1.0) && (Eingabefehler == 0))
  {
   alert(eps.toString() + Meldung[Sprache * 11 + 5]);
   // alert(eps.toString() + " ist kein g\u00FCltiger Wert f\u00FCr Epsilon");
   Eingabefehler = 1;
  }

  if ((d == 0.0) && (Eingabefehler == 0))
  {
   alert(Meldung[Sprache * 11 + 6]);
   // alert("Durchmesser d muss gr\u00F6\u00DFer als 0 sein");
   Eingabefehler = 1;
  }

  if (((a + a) <= d) && (Eingabefehler == 0))
  {
   alert(Meldung[Sprache * 11 + 7]);
   // alert("Abstand a muss gr\u00F6\u00DFer als der halbe Durchmesser sein");
   Eingabefehler = 1;
  }

  if (((RefSystem == 2) || (RefSystem == 3) || (RefSystem == 4) || (RefSystem == 6)) && ((b + b) <= d) && (Eingabefehler == 0))
  {
   alert(Meldung[Sprache * 11 + 8]);
   // alert("Abstand b muss gr\u00F6\u00DFer als der halbe Durchmesser sein");
   Eingabefehler = 1;
  }


  if (((RefSystem == 2) || (RefSystem == 3) || (RefSystem == 4) || (RefSystem == 6)) && (b/a < 1.0) && (Eingabefehler == 0))
  {
   alert(Meldung[Sprache * 11 + 9]);
   // alert("b muss >= a sein. Zur Berechnung vertausche ich die Werte von a und b.");
   Bruch = a;  // Variable Bruch hier nur temporär verwendet
   a = b;
   b = Bruch;
   Hinweis = Hinweis + Meldung[Sprache * 11 + 10]; 
   //"Zur Berechnung wurden die Werte von a und b vertauscht."; 
  }

  if (Eingabefehler == 0)
  {
    p = (4.0/pi-1.08)/(4.0/pi+1.08-2.0);   // 4.0/pi = 1.2732.  statt gerundet 1.27, rectangular outer conductor
    if (RefSystem == 2) k = 1.0 + (4.0/pi-1.0) * (1 - p * Math.pow(a/b, 4.5))/(1 + p * Math.pow(a/b, 4.5));  
       // frueher linear: k = 1.27 - 0.19 * a / b;

    p = (4.0/pi-1.167754622)/(4.0/pi+1.167754622-2.0);  // U shaped outer conductor
    if (RefSystem == 3) k = 1.0 + (4.0/pi-1.0) * (1 - p * Math.pow(a/b, 4.0))/(1 + p * Math.pow(a/b, 4.0)); 
       // frueher nur b=a von hp-Seite;

    p = (2.00-1.400)/(2.0+1.400-2.0);  // L shaped conductor
    if (RefSystem == 4) k = 1.0 + (2.00-1.0) * (1 - p * Math.pow(a/b, 1.78))/(1 + p * Math.pow(a/b, 1.78)); 
       // frueher keine Abhaengigkeit von b

    p = (2.00-4.0/pi)/(2.0+4.0/pi-2.0);   // round conductor between two planes at unequal distances
    if (RefSystem == 6) k = 1.0 + (2.00-1.0) * (1 - p * Math.pow(a/b, 1.57))/(1 + p * Math.pow(a/b, 1.57)); 
       // frueher linear: k = 2.0 - 0.73 * a / b; 

/*
   //Formel aus Ref. Data f. Radio Eng, 1956. tanhyp durch sinh/cosh bzw. exp ersetzt;
    p = Math.exp(pi/2.0);
    p = (p - 1/p) / (p + 1/p) * (4.0)/pi;
    p = (4.0/pi+p)/(4.0/pi-p);
    p = Math.log(p);
    p = p * b / 2.0 / a;
    p = Math.exp(p);
    p = (p - 1/p) / (1 + 1/p);

    if (RefSystem == 3) k = 4.0/pi * p;  
       // Math.tanhyp(b/2.0/a * Math.log(p)); 
       // Formel aus Ref. Data f. Radio Eng. 1956;
*/

    if ((ksp >= 1) && (ksp <= 2)  && (RefSystem != 11)) k = ksp;
  
    kabs = Math.abs(k);
    Verh = 2 * a / d;
    Bruch = kabs * a / d;

    if (Formel == 1) 
     { 
       /* eigene Formel (k-Interpolation) */
       Z = 60.0 / Math.sqrt(eps) * Math.log(Bruch + Math.sqrt(Bruch * Bruch - (kabs - 1.0)));
     }

    if (Formel == 0)
     {   
       /* Interpolationsformel (Z-Interpolation) */
  
       /* Z(k) = 60 * LN(2a/d) + (60*ARCCOSHYP(2a/d)-60*LN(2a/d)) * LN(k)/LN(2) */
       /* Z(k) = 60 * (ARCCOSHYP(2a/d)-LN(2a/d)) * LN(k)/LN(2)) + 60 * LN(2a/d) */
       /* Z(k) = 60 *{ ln(2a/d) + ln(k)/ln(2)*ln[1+Wurzel(1-(2a/d)^-2)] } */

       Z = Math.log(1.0 + Math.sqrt(1.0 - 1.0/Verh/Verh));

       Z = Z * Math.log(kabs)/Math.log(2) + Math.log(Verh);
      
       Z = Z * 60.0 / Math.sqrt(eps);
     }

    if (Formel == 2)
     {
       Z = 60.0 / Math.sqrt(eps) * Math.log(2*Bruch);
     }

    if (Formel == 3)
     {   
       /* Interpolationsformel (Z+k-Interpolation) */
  
       /* Z(Z-int) + (Z(Z-int)-Z(k-int))*0.6 */
       /* Die Verbesserung von k- auf Z-interp. wird im Verhältnis zu Z(Näherung) erhöht */

       Z = Math.log(1.0 + Math.sqrt(1.0 - 1.0/Verh/Verh));
       Z = Z * Math.log(kabs)/Math.log(2) + Math.log(Verh);
       Z = Z * 60.0 / Math.sqrt(eps);
       Zkinterp = 60.0 / Math.sqrt(eps) * Math.log(Bruch + Math.sqrt(Bruch * Bruch - (kabs - 1.0)));
       Znaeherg = 60.0 / Math.sqrt(eps) * Math.log(2*Bruch);
       // Z = Z * 1.6 - 0.6 * Zkinterp;
       Z = Z + 1.33*(Znaeherg-Z)*(Z-Zkinterp)/(Znaeherg-Zkinterp);
     }


    /* Tabelle von ... (nur bei square Coax) (L = large) */

      /* Nicht implementiert */

    /* Formeln von 1946 und 1956 zum Testen */

       Rho = 2*a/d;

    if ((RefSystem == 9) || (RefSystem == 10))        // Formel von 1946
       /* Ref Data 1946 */
       Z = 60.0 / Math.sqrt(eps) * Math.log(Rho*(kabs-(kabs-1)/Rho/Rho));
    
       /* Ref Data 1956 */
       Rho4 = Rho*Rho*Rho*Rho; 
       Rho8 = 0.163/Rho4/Rho4;
       Rho12 = 0.067/Rho4/Rho4/Rho4;
       Rho4 = 0.405/Rho4;
       A = (1+Rho4)/(1-Rho4);
       B = (1+Rho8)/(1-Rho8);
       C = (1+Rho12)/(1-Rho12);

     if (RefSystem == 11)                            // Formel von 1956
       Z = (60*Math.log(Rho)+6.48-2.34*A-0.48*B-0.12*C)/Math.sqrt(eps);       

    /* Ende Berechnung mit alten Formeln */

    if (k < 0) Z = Z * 2.0;   // Zweidrahtleitung, k = -2.0
    if (Z > 0.0)
    {
     Cs=Math.sqrt(eps)/Z*1000000.0/299.792458; // pF/m
     Ls=Math.sqrt(eps)*Z*1000.0/299.792458; // nH/m
    }
    else
    {
     Cs=0.0;
     Ls=0.0;
    }

    Z=Runden2(Z);        // gerundet auf 2 Nachkommastellen
    Cs=Runden2(Cs);
    Ls=Runden2(Ls);
 
    Ztxt = Z.toString();
    Cstxt = Cs.toString(); 
    Lstxt = Ls.toString(); 

    if (Math.abs((kabs * 100.0 - Math.floor(kabs * 100.0))) < 0.01) 
     {
      kabs=Runden2(kabs);
     }
    else
     {
      kabs=Runden4(kabs);
     }
    Ktxt = kabs.toString();
    if (RefSystem == 11) Ktxt = "(" + Ktxt + ")";

    if ((ksp >= 1) && (ksp <= 2) && (RefSystem != 11))  
     {
      if (Sprache == 0)
       {
        Hinweis = "k(speziell) = " + Ktxt;
       }
      else
       {
        Hinweis = "k(special) = " + Ktxt;
       }
     }
    else
     {
       Hinweis = "";
     }
    Hinweis = " \u03B5=" + eps.toString() + " " + Hinweis;
    if ((RefSystem == 2) || (RefSystem == 3) || (RefSystem == 4) || (RefSystem == 6)) Hinweis = " b=" + b.toString() + Hinweis;
    Hinweis = "d=" + d.toString() + " a=" + a.toString() + Hinweis;
    if ((ksp >= 1) && (ksp <= 2) && (RefSystem <= 8))  
     {
      if (Sprache == 0)
       {
        Hinweis = "Spezielle Struktur mit: \n" + Hinweis;
       }
      else
       {
       Hinweis = "Specal Structure with: \n" + Hinweis;
       }
     }
    else
     {
      Hinweis = kStruktur[Number(RefSystem) + Sprache * 12] + "\n" + Hinweis;
     }
    if (RefSystem <= 8)
     {
      Hinweis = Interpolation[Number(Formel) + Sprache * 3] + "\n" + Hinweis; 
     }
    else
     {
     if (Sprache == 0) 
      {
       Hinweis = "Spezielle Formel f\u00FCr" + "\n" + Hinweis; 
      }
     else 
      {
       Hinweis = "Special Formula for" + "\n" + Hinweis; 
      } 
    }
  }
  else
  {
    Ztxt = "";
    Cstxt = ""; 
    Lstxt = "";
    Ktxt = "";
  }

 }

// Ende function CalcZ


function CalcA ()
 {
  var dtxt="", atxt="", btxt="", etxt="", ksptxt="";

  RefSystem = document.WahlA.RefSysA.value;
  k = Kwerte[RefSystem];
  Formel = document.WahlA.Formeln.value;

  dtxt = document.RechneA.Durchmesser.value;
  atxt = document.RechneA.AbstandA.value;
  btxt = document.RechneA.AbstandB.value;
  etxt = document.RechneA.Epsilon.value;
  ksptxt = document.RechneA.kSpeziell.value;

  CalcZ (dtxt, atxt, btxt, etxt, ksptxt);

  document.RechneA.Zett.value = Ztxt;
  document.RechneA.Lstrich.value = Lstxt; 
  document.RechneA.Cstrich.value = Cstxt; 
  document.RechneA.Kstrich.value = Ktxt;
  document.RechneA.Warnung.value = Hinweis;
  document.RechneA.kSpeziell.value = "";
  document.RechneA.Durchmesser.value = Wertin[0];
  document.RechneA.AbstandA.value = Wertin[1];
  document.RechneA.AbstandB.value = Wertin[2];
  document.RechneA.Epsilon.value = Wertin[3];   
 }
// Ende function CalcA



// Funktion Berechnung von Z, L' und C' 


function CalcB ()
 {
  var dtxt="", atxt="", btxt="", etxt="", ksptxt="";

  RefSystem = document.WahlB.RefSysB.value;
  k = Kwerte[RefSystem];
  Formel = document.WahlB.Formeln.value;

  dtxt = document.RechneB.Durchmesser.value;
  atxt = document.RechneB.AbstandA.value;
  btxt = document.RechneB.AbstandB.value;
  etxt = document.RechneB.Epsilon.value;
  ksptxt = document.RechneB.kSpeziell.value;

  CalcZ (dtxt, atxt, btxt, etxt, ksptxt);

  document.RechneB.Zett.value = Ztxt;
  document.RechneB.Lstrich.value = Lstxt; 
  document.RechneB.Cstrich.value = Cstxt; 
  document.RechneB.Kstrich.value = Ktxt;
  document.RechneB.Warnung.value = Hinweis;
  document.RechneB.kSpeziell.value = "";
  document.RechneB.Durchmesser.value = Wertin[0];
  document.RechneB.AbstandA.value = Wertin[1];
  document.RechneB.AbstandB.value = Wertin[2];
  document.RechneB.Epsilon.value = Wertin[3];
 }


// function delspaces (txt) loescht leading spaces aus einem String
// wenn der String nur Spaces enthaelt, wird ein leerer String zurueckgegeben

function delspaces (txt)
 {
  var txtout = "", lgt=0, cnt=0;
  txtout = txt;
  lgt=txtout.length;
  for (cnt=0; cnt<lgt; cnt++)
   {
    if (txtout.substr(0,1) == " ")
     {
      if (txtout.length == 1)
        txtout = "";
      else
        txtout = txtout.substr(1); 	
     }
   }
  return txtout;
 }

// function checkvalidnumber (txt) testet, ob ein String ungueltige Zeichen enthaelt, d. h.
// andere Zeichen als 0...9 und .(Punkt); ein leerer String ist ebenfalls ungueltig (-3)


function checkvalidnumber (txt)
 {
  var gueltig = 1, lgt = 0, cnt = 0, tmp = 0, tx="", text = "", textneu = "";
  var Zeichen = "0123456789.";
  var punkte = 0;
  text = txt;
  korrtxt = txt;  // merken in globaler Variablen
  lgt = text.length;
  if (lgt == 0) 
    gueltig = -3;
  else
   {
    for (cnt=0; cnt<lgt; cnt++)
     { 
      tx = text.substr(cnt,1);
      if (tx == ",")
       {
        // alert ("Hinweis: Komma wird in " + text +" durch Dezimalpunkt ersetzt");
        korrtxt = text.replace(/,/g, ".");
        text = korrtxt;                   // zurueckspeichern fuer Ausgabe
       }
     }   
    for (cnt=0; cnt<lgt; cnt++)
     {
      tx = text.substr(cnt,1);
      tmp = Zeichen.lastIndexOf(tx);
      if (tmp == 10) punkte = punkte + 1; // zaehlt die Anzahl der Punkte (darf nur einer sein)
      gueltig = Math.min(gueltig,tmp); 	// wenn Zeichen nicht in Tabelle steht, ist tmp = -1
     }
   }
  if (punkte > 1) gueltig = -2; 	// zu viele Punkte (gueltig = -2)
  return gueltig;			// 1: keine Null gefunden, 0: mindestens eine Null, -1: falsches Zeichen
 }


// fuer die Kommunikation mit Autor (023751);
  var IMehl=new Array ("mai", "de", "lto:", "dh2mic", "harm", "darc.", "hartwig.", "@", "t-online.", ".", "http://");
  var Mehl = "";
  Mehl = IMehl[0]+IMehl[2]+IMehl[3]+IMehl[7]+IMehl[5]+IMehl[1];


function Runden2(Zahl)
{
  var Ziel = 0.0;
  var Tmp = 3;
  Ziel = Zahl;
  if (Ziel > 0.0) Tmp = Math.floor(Math.log(Ziel)/Math.log(10)+3);
  if (Tmp < 3) Tmp = 3;
  if (Ziel > 0.0)  Ziel = Ziel.toPrecision(Tmp);           // gerundet auf 2 Nachkommastellen
  return Ziel;
}

function Runden4(Zahl)
{
  var Ziel = 0.0;
  var Tmp = 5;
  Ziel = Zahl;
  if (Ziel > 0.0) Tmp = Math.floor(Math.log(Ziel)/Math.log(10)+5);
  if (Tmp < 5) Tmp = 5;
  if (Ziel > 0.0)  Ziel = Ziel.toPrecision(Tmp);           // gerundet auf 4 Nachkommastellen
  return Ziel;
}


function Runden5(Zahl)
{
  var Ziel = 0.0;
  var Tmp = 6;
  Ziel = Zahl;
  if (Ziel > 0.0) Tmp = Math.floor(Math.log(Ziel)/Math.log(10)+6);
  if (Tmp < 6) Tmp = 6;
  if (Ziel > 0.0)  Ziel = Ziel.toPrecision(Tmp);           // gerundet auf 5 Nachkommastellen
  return Ziel;
}
