// design_toroid applet
// Jack W Ponton, August 1996
// Copying permitted with acknowledgement

import java.awt.* ;
import java.lang.Math ;

public class design_toroid extends java.applet.Applet 
{
 private Button clear, design ;  // Not used now
 private Choice size, material ;
 private TextField inductance ;
 private TextArea results ; // not used
//
 private Integer Size = new Integer (50) ;
 private Integer Material = new Integer (2) ;
 private Double Inductance = new Double (0.0) ;
 private String Message = new String ("No Specification") ;
 private String Turns = new String ("") ;
 private double exact ;
 private double max_wiresize ;
 private int inner_diam ;
 private Color colour ;
//


 public void init () // set up the applet
 { 
  super.init();

  inductance = new TextField (5);
  inductance.setBackground(Color.green) ;
  this.add (new Label("Required Inductance, microHenries:")) ;
  this.add(inductance) ;

  size = new Choice ();
  size.addItem ("T-50") ;
  size.addItem ("T-20") ;
  size.addItem ("T-37") ;
  size.addItem ("T-68") ;
  size.addItem ("T-94") ;
  size.addItem ("T-157") ;
  size.addItem ("T-200") ;
  this.add(size) ;


  material = new Choice ();
  material.addItem ("2") ;
  material.addItem ("6") ;
  material.addItem ("3") ;
  material.addItem ("1") ;
  material.addItem ("10") ;
  material.addItem ("41") ;
  this.add(material) ;

 }  // end init method


 public boolean action (Event event, Object arg) 
 {

  if (event.target==size)
  {
    String sval ;
    sval = (String) event.arg ;
    sval = sval.substring (2) ;
    Size = Integer.valueOf (sval) ;
    Graphics g = this.getGraphics();
    paint (g) ;
    return true ;
  }

  if (event.target==material)
  {
    Material = Integer.valueOf ((String) event.arg) ;
    Graphics g = this.getGraphics();
    paint (g) ;
    return true ;
  }

  if (event.target==inductance)
  {
    Inductance = Double.valueOf ((String) event.arg) ;
    System.out.println ("Inductance set to " + ((String) event.arg)) ;
//  ....System.out is the Java console, used for testing
    Graphics g = this.getGraphics();
    paint (g) ;
    return true ;
  }

  // default return...
  return super.action(event,arg);

 } // end method action

// 


 public void paint (Graphics g)
 {
  String induct, mat, core, turns ;
  int material, size ;
  double inductance ;

  g.setColor(Color.white) ;
  g.fillRect (1,1, 500,500) ;
  g.setColor(Color.black) ;

  inductance = Inductance.doubleValue() ;
  size = Size.intValue() ;
  material = Material.intValue() ;

//  induct = Double.toString(inductance)  ;
//  core = Integer.toString(size) ;
//  mat = Integer.toString(material) ;

int left, top ;
left=50 ;
top=50 ;

  g.drawString ("Design is for " + inductance + " microHenries", left, top) ;
  g.drawString ("Using T-"+size+"-"+material, left,top+20) ;
 
  do_calcs (inductance, size, material) ;

  if (Turns != "")
  { 
    g.drawString( "Number of turns is "+ Turns, left, top+40) ;
    g.drawString ("Exact inductance is "+exact+" microHenries", left, top+60) ;
    if (max_wiresize>0) 
     {
      int swg ; String SWG ;
      swg = wire_swg(max_wiresize) ;
      SWG = "(< 40 swg))" ;
      if (swg>0) {SWG = "(>" + Integer.toString(swg) +" swg)" ;}
      g.drawString 
       ("Maximum wire diameter is "+ max_wiresize + " inches "+ SWG,
       left, top+80) ; 
     }
  }
  
  g.drawString(Message, left, top+100) ;
   
// draw diagram..

  if (inductance!=0) 
   {draw_diagram (size, material, Integer.parseInt(Turns), g) ;}

   } // end paint

 private void draw_diagram (int size, int material, int nturns, Graphics g)
 {
  int x, y, d1, d2, r1, r2, x1, y1, x2, y2;
  double X,Y, X1,Y1, X2,Y2, R1, R2, theta, dtheta ;

  x=250 ; y= 220;
  d1 = (2*size/3) ; d2=Math.round(2*inner_diam/30) ;

  r1=(d1/2) ; r2=(d2/2) ;
  R1 = r1 ; R2 = r2 ;

  colour = toroid_colour(material); ;
  g.setColor (colour) ;
  g.fillOval (x-r1,y-r1,d1, d1) ; 

  g.setColor (Color.white) ;
  g.fillOval (x-r2,y-r2, d2, d2) ;
  g.setColor (Color.black) ;

  dtheta = 2*Math.PI/(nturns) ;
  theta = 0.0 ;
  g.drawLine (x-r1-(r1-r2)*2, y, x-r1, y) ;
  for (int i=0 ; i<=nturns-1 ; i++)
  {X1 = R1*Math.cos(theta) ; Y1 = R1*Math.sin(theta) ;
   x1 = (int) Math.round (X1) ; y1 = (int) Math.round(Y1) ;
   X2 = R2*Math.cos(theta) ; Y2 = R2*Math.sin(theta) ;
   x2 = (int) Math.round (X2) ; y2 = (int) Math.round(Y2) ;
   g.drawLine (x-x1, y-y1, x-x2, y-y2) ;
   theta = theta+dtheta ;
   if (i==nturns-1) {  g.drawLine (x-x1, y-y1, x-x1-(r1-r2)*2, y-y1) ;}
  }

      
 } // end draw diagram


 private void do_calcs (double inductance, int size, int material)
 {
  double avalue, turns;
  long nturns ;
  Message = " " ;
  avalue = getA (size, material) ;
  if (avalue<=0.0) 
  {
   avalue = estA (size, material) ;
   if (avalue<=0) 
   {
     Message = "Cannot find toroid size and/or material in databank" ; 
     Turns = "" ; return ;
   }
   Message = "Approximate data for given core was estimated" ;
  }
  
  turns = 100*Math.sqrt(inductance/avalue) ;
  nturns = Math.round (turns) ;
  Turns = Long.toString(nturns) ;
  exact = avalue * (nturns/100.0) * (nturns/100.0) ;
  max_wiresize = wiremax (size, nturns) ;

 } // end do_calcs

 private double getA (int size, int material)
 {
  int toroid [][] =
  {
   {50, 2, 49}, {37, 2, 40}, {68, 2, 57}, {157, 2, 140}, {200, 2, 120},
   {20, 2, 25}, {94, 2, 84},
   {37, 6, 30}, {50, 6, 46}, {68, 6, 47}, {157, 6, 115}, {200, 6, 100},
   {37, 3, 120}, {50, 3, 175}, {68, 3, 195}, {157, 3, 420},
   {50, 1, 100}, {50, 10, 31}, {50, 41, 320},


   {0, 0, 0},
   
  } ;
// All data for selected sizes in type 2 material, 
// all selected materials for size 50

  int i ;
  double avalue = 0 ;
  System.out.println ("Searching for "+size+"  "+material) ;
  for (i=0 ; i<=1000; i++) 
  {
    if (toroid[i][0] == 0) { break ;}
    if ( (toroid[i][0]==size) && (toroid[i][1]==material) )
     { avalue = toroid[i][2] ; break ;}
  }

  System.out.println("Searched DB to entry " + i) ;
  System.out.println("Got A of "+avalue) ;
  return avalue ;

 } // end getA

 private double estA (int size, int material)
 {  // Estimate A from size 50, type 2 data
   double A50, A2, avalue, aref, mu, muref ;
   avalue=0 ;
   muref = 10 ; aref=49 ; // for type 2 material, 50 core
   A50 = getA (50, material) ;
   if (A50 == 0) {return 0 ;}
   A2 = getA (size, 2) ;
   if (A2 == 0) {return 0 ;}
   mu = toroid_mu (material) ;
   if (mu == 0) {return 0 ;}
   avalue = A2 * mu / muref ; // scale by permeability
//   avalue = A50 * (A2/aref) ; // size correction ??
   return avalue ;
 } // end estA

 private double toroid_mu (int m)
 {
  double  c ;
  c = 0;
  if (m==2) {c=10;}
  if (m==6) {c=8;}
  if (m==3) {c=35;}
  if (m==1) {c=20;}
  if (m==10) {c=6;}
  if (m==41) {c=75;}
  return c;
 } // end toroid_mu

 private double wiremax (int size, long nturns)
 {
  int inner [][] = 
  { {200, 1250}, {157, 950}, {94, 560}, {68, 370}, {50, 303}, 
  {37, 205}, {20, 88}, {0,0}} ;
  double max ;
  max = -1 ;
  int thous ;
  thous = 0 ;
  inner_diam=thous ; // global for graphics
  for (int i=0 ; i<100 ; i++)
  {
   if (inner[i][0]==0) {break;}
   if (inner[i][0]==size) {thous=inner[i][1] ; break ;}
  }
  if (thous==0 || nturns==0) {return max;}
  double circum = 3.14159*thous/1000.0 ;
  max = circum / nturns ;
  inner_diam=thous ;
  return max ;
 } // end wiremax

 private Color toroid_colour (int m)
 {
  Color c ;
  c = Color.white ;
  if (m==2) {c=Color.red;}
  if (m==6) {c=Color.yellow;}
  if (m==3) {c=Color.gray;}
  if (m==1) {c=Color.blue;}
  if (m==10) {c=Color.black;}
  if (m==41) {c=Color.green;}
  return c;
 } // end toroid_colour
 
//

 private int wire_swg (double dia)
 {
  int gauge ;
  double size ;
  int swg [][] = {
   {12, 1040}, {14, 800}, {16, 640}, {18, 480}, {22, 280}, {24, 220}, 
   {26, 180}, {28, 148},
   {30, 124}, {34, 92}, {36, 76}, {38, 60}, {40, 48}, {0,0} } ;
  
  gauge=0 ;
  for (int i=0 ; i<=100 ; i++)
  {
   size=swg[i][1]/10000.0 ; 
   if (size<=dia) {gauge=swg[i][0] ; break ;}
  }  
  
  return gauge ;
 } // end wire_swg


} // end class design_toroid
