/*
   Calculation of the digits of pi
   by the spigot algorithm of Rabinowitz and Wagon
   98-07-05
*/

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.text.*;


public class pispigot extends Applet implements ActionListener {
   int         noofdigits = 1000;  // initial value
   TextArea    taPiDigits;
   int         height = 15;
   int         width = 82;
   int         currpos;
   TextField   tfNoOfDigits;
   Button      btnStart;

   // initialize the applet
   public void init() {
      add(new Label("The first "));
      tfNoOfDigits = new TextField("  " + String.valueOf(noofdigits), 3);
      add(tfNoOfDigits);
      add(new Label(" digits of pi:"));
      taPiDigits = new TextArea("", height, width);
      add(taPiDigits);
      btnStart = new Button("Start");
      add(btnStart);
      btnStart.addActionListener(this);
   }

   // Get user argument
   public void actionPerformed(ActionEvent ev) {
      if (ev.getSource() == btnStart) {
         noofdigits = Integer.parseInt(tfNoOfDigits.getText().trim());
         if (noofdigits < 4)     noofdigits = 4;
         if (noofdigits > 30000) noofdigits = 30000;
         noofdigits = (noofdigits/4)*4;
         tfNoOfDigits.setText("  " + String.valueOf(noofdigits));
         taPiDigits.setText("");    
         currpos = 0;
         spigot(noofdigits);
      } // end if
   }

   // perform the spigot algorithm
   void spigot(int noofdigits)
   {
      int a = 10000,b,c,d,e,f[],g,h,i;

      b = c = (noofdigits/4 + 1) * 14;
      f = new int[c];
      d = e = h = i = 0;
      while ((c-=14) > 0) {
         while((g = --b * 2) != 0) {
            d = h*b+a*(i==0 ? a/5 : f[b]);
            h = d/(--g);
            f[b]=d%g;
         }
         i = printChunk(e + d/a);
         e = d % a;
         b = c;
     }
   }

   // print the 4 digits just computed 
   int printChunk(int digits)
   {
      int digits1;

      currpos += 4;
      if (currpos > width) {
         taPiDigits.append("\n");
         currpos = 4;
      }
      digits1 = digits;
      digits1 |= 1;  // ensure nonzero
      while (digits1 < 1000) {
         taPiDigits.append("0");
         digits1 *= 10;
      }
      taPiDigits.append(String.valueOf(digits));
      return 4;
   }

}

