import java.applet.Applet;
import java.awt.*;
import java.util.Random;

public class Batcher extends Applet 
  {
    static int N = 10000;
    static int dotsize = 4;
    static Graphics g;

    static void clear(Color c)
      { 
        int h = g.getClipRect().height;
        int w = g.getClipRect().width;
        g.setColor(c);
        g.fillRect(0, 0, w, h);
      }
    static void paint(int i, double x, Color c)
      { 
        int h = g.getClipRect().height;
        int w = g.getClipRect().width;
        g.setColor(c);
        g.fillOval( (i*w)/(N+N), h - (int) (x*h), dotsize, dotsize);
      }
    static void exch(double [] a, int i, int j)
      { double t = a[i]; a[i] = a[j]; a[j] = t;
        paint(i, a[j], Color.white);
        paint(j, a[i], Color.white);
        paint(i, a[i], Color.black);
        paint(j, a[j], Color.black);
      }
    static boolean less(double [] a, int i, int j)
      { 
        paint(i, a[i], Color.red);
        paint(j, a[j], Color.red);
        return a[i] < a[j];
      }
    static void compexch(double [] a, int i, int j)
      {
        if (!less(a, i, j)) exch(a, i, j);
      }
    static void shuffle(double a[], int l, int r)
      { int i, j, m = (l+r)/2;
        for (i = l, j = 0; i <= r; i+=2, j++)
          { exch(a, N+i, l+j); exch(a, N+i+1, m+1+j); }
        for (i = l; i <= r; i++) exch(a, i, N+i);
      }
    static void unshuffle(double a[], int l, int r)
      { int i, j, m = (l+r)/2;
        for (i = l, j = 0; i <= r; i+=2, j++)
          { exch(a, N+l+j, i); exch(a, N+m+1+j, i+1); }
        for (i = l; i <= r; i++) exch(a, i, N+i);
      }
    static void mergeTD(double a[], int l, int r)
      { int i, m = (l+r)/2;
        if (r == l+1) compexch(a, l, r);
        if (r < l+2) return;
        unshuffle(a, l, r);
        mergeTD(a, l, m); 
        mergeTD(a, m+1, r);
        shuffle(a, l, r);
        for (i = l+1; i < r; i+=2) 
          compexch(a, i, i+1);
      }
    static void mergesort(double[] a, int l, int r)
      { int m = (r+l)/2;
        if (r <= l) return;
        mergesort(a, l, m);
        mergesort(a, m+1, r);
        mergeTD(a, l, r);
      }

    static void arrayInitRand(double a[], int l, int r)
      { int i; 
        for (i = l; i <= r; i++)
          {
            a[i] =  Math.random(); 
            paint(i, a[i], Color.black);
          }
      }
    static void arrayInitRev(double a[], int l, int r)
      { int i; 
        for (i = l; i <= r; i++)
          {
            a[i] =  ((double) (r-i))/((double) (r-l)); 
            paint(i, a[i], Color.black);
          }
      }
    public void paint(Graphics page)
      {
        int alg = Integer.parseInt(getParameter("algorithm"));
        double[] a = new double[N+N];
        g = page;
        N = Integer.parseInt(getParameter("N"));
        dotsize = Integer.parseInt(getParameter("dotsize"));
        arrayInitRand(a, 0, N-1);
        if (alg == 1)
          {
            mergesort(a, 0, N-1);
          }
      }
  }

