/*
 *
 * FWTFrEnd - Tim Tyler 2000.
 * 
 * A front end for the Fast Walsh Transform in Java.
 * This code has been placed in the public domain.
 * You can do what you like with it.
 * Note that this code comes with no warranty.
 *
 */

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

   public class FWTFrEnd extends java.applet.Applet implements ActionListener {
      Panel input, output, input1, input2, input3, output1, output2;
      TextArea input_area, output_area;
   
      int data[] = new int[256];
      int data1[];
      int data2[];
   
      static String text_area_contents;
      static int leng;
      static int non_linearity;
      static int total;
   
      int i=0, j=0, k=0, n=0;
   
      Button FWT_button, clear_button;
      final static String FWTSTRING = "Fast Walsh Transform";
      final static String CLEARSTRING = "Clear";
   
   // constructor
      public FWTFrEnd() {
         setLayout(new GridLayout(1,2,5,5));
      
         input = new Panel();
         output = new Panel();
      
         input.setLayout(new BorderLayout());
      
         input1 = new Panel();
         input1.setLayout(new GridLayout(2,1,5,5));
      
         input2 = new Panel();
         input2.setLayout(new GridLayout(1,1));
         input2.add(new Label("Each value on a separate line please",Label.CENTER));
      
         input1.add(new Label("Input",Label.CENTER));
      
         clear_button = new Button(CLEARSTRING);
         clear_button.addActionListener(this);
      
         input1.add(clear_button);
      
         input.add("North",input1);
      
         input_area = new TextArea();
      
         input.add("Center",input_area);
      
      
         output.setLayout(new BorderLayout());
      
         output1=new Panel();
         output1.setLayout(new GridLayout(2,1,5,5));
         output1.add(new Label("Output",Label.CENTER));
      
         FWT_button = new Button(FWTSTRING);
         output1.add(FWT_button);
         FWT_button.addActionListener(this);
      
         output.add("North",output1);
      
         output_area = new TextArea();
         output_area.setEditable(false);
      
         output.add("Center",output_area);
      
         add(input);
         add(output);
      }
   
   
      public void actionPerformed(ActionEvent ev) {
         String label = ev.getActionCommand(); // (String)arg;
      
         if (label.equals(CLEARSTRING)) {
            input_area.setText("");
            output_area.setText("");
         }
      
         if (label.equals(FWTSTRING) && input_area.getText() != "") {
            output_area.setText("");
         
            String ret="";
         
            text_area_contents=input_area.getText();
            text_area_contents.trim();
            leng = text_area_contents.length();
         
            i=0;
            n=0;
         
            while (i < leng) {
               if (charAt(i) == '+' || charAt(i) == '-') {
                  ret += charAt(i); 
                  i++;
               }
            
               while(Character.isDigit(charAt(i)) || charAt(i)=='.') {
                  ret += charAt(i);
                  i++;
               }
            
               data[n++] = (Integer.valueOf(ret.trim())).intValue();
            
               ret="";
            
            
               if (charAt(i) == '\n' || charAt(i)==',' || charAt(i)==' ') {
                  i++;
               }
            
            
            
               if (i < leng-1) 
                  while((i < (leng - 1)) & (charAt(i)==' '
                                         || charAt(i)=='\t'
                                         || charAt(i)=='\n'
                                         || charAt(i)==',')) 
                     i++;
            }
         
            // have now read in information...
         
            data1 = new int[n];
            for (j = 0; j < n; j++) {
               data1[j] = data[j];
            }
         
         
            output_area.append("Input data:\n {");
         
            for (j = 0; j < (n - 1); j++) {
               output_area.append(Integer.toString(data[j]) + ", ");
            }
         
            output_area.append(Integer.toString(data[n - 1]) + "}\n");
         
            if (!Walsh.isBooleanFunction(data1)) {
               output_area.append("\nWarning: this is not a boolean function.\n");
            }
         
         
            output_area.append("\nNumber of elements: " + Integer.toString(n)+"\n");
         
            total = Walsh.totalBits(data1);
         
            output_area.append("\nNumber of non-zero elements: " + Integer.toString(Walsh.totalBits(data1))+"");
         
            if ((n >>> 1) == total) {
               output_area.append(" (balanced)");
            }
         
            if (Walsh.isRightSize(data1)) {
            
               data2 = Walsh.FWT(data1);
            
               output_area.append("\n\nFast Walsh Transform:\n {");
            
               for (j = 0; j < n - 1; j++) {
                  output_area.append(Integer.toString(data2[j]) + ", ");
               }
            
               output_area.append(Integer.toString(data2[n - 1]) + "}\n");
            
               non_linearity = Walsh.nonLinearity(data2);
            
               output_area.append("\nNon-linearity:" + Integer.toString(Walsh.nonLinearity(data2)));
            
               if (non_linearity == 0) {
                  output_area.append(" (i.e. linear)");
               }
               output_area.append("\n");
            }
            else
            {
               output_area.append("\n\nError: the size of the input array (" + Integer.toString(n) + ") is not a power of two.");
            }
         
         }
      }
   
      char charAt(int i) {
         if (i < leng){
            return text_area_contents.charAt(i);
         }
         else
         {
            return '\n';
         }
      }
   
   }

