/** Copyright Henry Bottomley March 2002
    More added on distinct partitions May 2002
*/

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.math.BigInteger;


public class partitionmulti extends Applet
 implements ActionListener
    {TextField box0, box1, messagebox;
     CheckboxGroup chooseRadio;
             
     public void init()
        {
         box0 = new TextField(10); 
         add (box0); 
         Button calculate = new Button("Calculate partitions");
         calculate.addActionListener(this);
         add (calculate);
         chooseRadio = new CheckboxGroup();
         add(new Checkbox("All partitions",chooseRadio,true));
         add(new Checkbox("Distinct terms",chooseRadio,false));
         add(new Checkbox("Odd terms",chooseRadio,false));
         add(new Checkbox("Largest term equal to ...",chooseRadio,false));
         add(new Checkbox("Largest term up to ...",chooseRadio,false));
         add(new Checkbox("Exactly ... terms",chooseRadio,false));
         add(new Checkbox("No more than ... terms",chooseRadio,false));
         add(new Checkbox("Exactly ... terms, all distinct",chooseRadio,false));
         add(new Checkbox("No more than ... terms, all distinct",chooseRadio,false));
         add(new Checkbox("Largest term equal to ..., all distinct",chooseRadio,false));
         add(new Checkbox("Largest term up to ..., all distinct",chooseRadio,false));
         box1 = new TextField(6); 
         add (box1); 
         messagebox = new TextField(90); 
         add (messagebox);
        }    
                 
     public void actionPerformed(ActionEvent event)
        {String arg=event.getActionCommand();
                         
        if (arg=="Calculate partitions")
            {int n=Integer.parseInt(box0.getText().trim());
             int total=n;
             int limit=n;
             BigInteger partitionArray[] = new BigInteger[n+1];             
             partitionArray[0]=BigInteger.valueOf(1l);
                                                    
             String labelRadio=chooseRadio.getCurrent().getLabel();
             if (labelRadio=="Largest term up to ..." 
              || labelRadio=="No more than ... terms" 
              || labelRadio=="Largest term up to ..., all distinct") 
                {limit=Integer.parseInt(box1.getText().trim());
                } 
             else if (labelRadio=="Largest term equal to ..." 
                   || labelRadio=="Exactly ... terms" ) 
                {limit=Integer.parseInt(box1.getText().trim());
                 total=n-limit;
                } 
             else if (labelRadio=="Largest term equal to ..., all distinct" ) 
                {limit=Integer.parseInt(box1.getText().trim())-1;
                 total=n-limit-1;
                } 
             else if (labelRadio=="Distinct terms" 
                    || labelRadio=="Odd terms") 
                {limit=(int) (Math.sqrt(2.0d*total)) ;
                }
             else if (labelRadio=="Exactly ... terms, all distinct") 
                {limit=Integer.parseInt(box1.getText().trim());
                 total=n-((limit*(limit+1))/2);
                } 
             else if (labelRadio=="No more than ... terms, all distinct") 
                {limit=Integer.parseInt(box1.getText().trim());
                 int altlim=(int) (Math.sqrt(2.0d*total));
		 if (altlim<limit)
                    {limit=altlim;
                    }
                } 
                                                                        
             for (int k=1; k<=total; k++)
                {partitionArray[k]=BigInteger.valueOf(0l);
                }
             BigInteger partsumDistinct=BigInteger.valueOf(0l);
                                                            
             if (labelRadio=="Largest term equal to ..., all distinct" 
              || labelRadio=="Largest term up to ..., all distinct"  )
                {if (total*2<=limit*(limit+1) && total>=0)
                    {
                     for (int j=1; j<=limit; j++)
                        {int totallimit=(j*(j+1))/2;
                         if (total<totallimit)
                            {totallimit=total;
                            }   
                         for (int k=totallimit; k>=j; k--) // note the subtle differences
                            {partitionArray[k]=partitionArray[k].add(partitionArray[k-j]);
                            }   // end of k loop
                         messagebox.setText(Integer.toString(j));
                        }       // end of j loop 
                    }           // end of sensible total if
                 else
                    {messagebox.setText(Integer.toString(n) + "    " + Integer.toString(0));
                    }           // end of useless total else
                }               // end of distinct if
             else
                {if (total>=0)
                    {for (int j=1; j<=limit; j++)
                        {for (int k=j; k<=total; k++)      // note the subtle differences
                            {partitionArray[k]=partitionArray[k].add(partitionArray[k-j]);
                            }   // end of k loop
                         if (j*(j+1)<=2*total) 
                            {partsumDistinct=partsumDistinct.add(
                                             partitionArray[total-((j*(j+1))/2)]);
                            }   // for some of the distinct terms calculations
                         messagebox.setText(Integer.toString(j));
                        }       // end of j loop 
                    }           // end of sensible total if
                 else
                    {messagebox.setText(Integer.toString(n) + "    " + Integer.toString(0));
                    }           // end of useless total else
                }               // end of distinct else                                     
                                                            
             if (labelRadio=="Distinct terms" 
              || labelRadio=="Odd terms" 
              || labelRadio=="No more than ... terms, all distinct") 
                {messagebox.setText(Integer.toString(n) + 
                                    "    " + partsumDistinct.toString());
                }
             else
                {messagebox.setText(Integer.toString(n) + 
                                    "    " + partitionArray[total].toString());
                }
            }            // end of calculate partitions
        }                // end of actionPerormed
    }                    // end of class partitionmulti



 