import java.lang.*;
import java.util.*;
import java.awt.*;
import java.applet.*;



public class ParamPassing extends Applet { 
  Button go;
  ProgramWindows p;

  public ParamPassing() {
    add(go = new Button("Parameter Passing Demo"));
    p = new ProgramWindows(this);
  }

  public boolean action(Event e, Object arg) {

    if (e.target instanceof Button) {
      if (((String)arg).equals("Parameter Passing Demo")) {
        go.disable();
        p.show();
        p.Explain.show();
      }
    }
   
    return true;
  }

}	/* End class ParamPassing */


class ProgramWindows extends Frame {
  public DrawingArea MainArea;
  public Description Explain;
  public ControlPanel Control;

  public ProgramWindows(Applet app) {
    MainArea = new DrawingArea(app);
    Explain = new Description();
    Control = new ControlPanel(MainArea, Explain, app);

    MainArea.SetControl(Control);

    setLayout(new BorderLayout());
    add("North", Control);
    add("Center", MainArea);
    resize(600, 650);
    hide();
  }
}


class ControlPanel extends Panel {
  DrawingArea Main;
  Description Desc;
  public Button bnext, bseeDesc, bplaySound, bclose;
  public boolean voice=false;
  Applet app;
  public Checkbox cb_sound;


  ControlPanel(DrawingArea m, Description d, Applet a) {
    app = a;
    Main = m;
    Desc = d;
    setLayout(new FlowLayout(FlowLayout.LEFT));
    add(bnext = new Button("  Next  "));
    add(bseeDesc = new Button("Hide Description"));
    add(bclose = new Button("Close"));
    cb_sound = new Checkbox("Voice Description");
    cb_sound.setState(false);
    add(cb_sound);
  }

  void Reset() {
    bnext.setLabel("  Next  ");
    bseeDesc.setLabel("Hide Description");
/*    bplaySound.setLabel("Enable Voice"); */
  }

  public boolean action(Event e, Object arg) {
   
    if (e.target instanceof Button) {

      if (((String)arg).equals("  Next  ")) {
        bnext.disable();
        Desc.Next();
        Main.Next();
        if (voice) Main.PlaySound();
      } else if (((String)arg).equals("Hide Description")) {
        bseeDesc.setLabel("Show Description");
        Desc.hide();
      } else if (((String)arg).equals("Show Description")) {
        bseeDesc.setLabel("Hide Description");
        Desc.show();
      } else if (((String)arg).equals("Disable Voice")) {
        voice = false;
        bplaySound.setLabel("Enable Voice");
      } else if (((String)arg).equals("Enable Voice")) {
        voice = true;
        bplaySound.setLabel("Disable Voice");
        Main.PlaySound();
      } else if (((String)arg).equals("Restart")) {
        bnext.setLabel("  Next  ");
        Main.Reset();
        Desc.Reset();
      } else if (((String)arg).equals("Close")) {
        ((ParamPassing)app).p.hide();
        Desc.hide();
        this.Reset();
        Main.Reset();
        Desc.Reset();
        ((ParamPassing)app).go.enable();
      }

    } else if (e.target instanceof Checkbox) {
     Checkbox cb = (Checkbox)e.target;
     String str = cb.getLabel();
     
     if (str.equals("Voice Description")) {
       if (cb.getState()) {
         voice = true;
         Main.PlaySound();
       } else {
         voice = false;
         Main.StopSound();
       }
     }
 
   }

    return true;
  }	/* End Method action() */

}	/* End Class ControlPanel */


class DrawingArea extends Canvas {
  Image img=null;
  ControlPanel cp;
  Color bgColor;
  Font font = new Font("Courier", Font.PLAIN, 18);
  Font outputfont = new Font("TimesRoman", Font.BOLD+Font.ITALIC, 24);
  Font memoryfont = new Font("TimesRoman", Font.ITALIC, 16);
  FontMetrics fm;
  public int status=0;
  int LM=25;		/* Left Margin */
  int TM=40;		/* Top Margin */
  int hseparation=25;
  int cWidth, cHeight;
  Applet app;
  String sound[] = new String[20];
  AudioClip ac=null;

  public DrawingArea(Applet a) {
    app = a;
    sound[0] = "sound/desc1.au";
    sound[1] = "sound/desc2.au";
    sound[2] = "sound/desc3.au";
    sound[3] = "sound/desc4.au";
    sound[4] = "sound/desc5.au";
    sound[5] = "sound/desc6.au";
    sound[6] = "sound/desc7.au";
    sound[7] = "sound/desc8.au";
    sound[8] = "sound/desc9.au";
    sound[9] = "sound/desc10.au";
    sound[10] = "sound/desc11.au";
    sound[11] = "sound/desc12.au";
    sound[12] = "sound/desc13.au";
    sound[13] = "sound/desc14.au";
    sound[14] = "sound/desc15.au";
    sound[15] = "sound/desc16.au";
    sound[16] = "sound/desc17.au";

    fm = getFontMetrics(font);
    cWidth = fm.charWidth(' ');
    cHeight = fm.getHeight();
    bgColor = new Color(170, 170, 170);    /* set background as gray */
    System.out.println("Constructor of DrawingArea");
  }

  public void PlaySound() {
    if (status == 0) return;
    if (ac != null) StopSound();
    ac = app.getAudioClip(app.getCodeBase(), sound[status-1]);
    ac.play();
/*    app.play(app.getCodeBase(), sound[status-1]); */
  }

  public void StopSound() {
    ac.stop();
  }

  public boolean mouseDown(Event e, int x, int y) { 
	System.out.println("Mouse Down at ("+x+", "+y+")");
	return true;
  }

  public void SetControl(ControlPanel c) {
    cp = c;
  }

  public void Reset() {
    status=0;
    repaint();
  }

  public void Next() {
    status++;
    repaint();
  }

  public void update(Graphics g) {
    int i;
    int start;
    Dimension dim;
    Graphics gc;
    int startx, starty, endx, endy, incrementx, incrementy;

    switch (status) {
     case 0:
      paint(g);
      break;

     case 1:
      g.setColor(Color.red);
      g.drawRect(88, 200, 37, 20);
      g.drawLine(105, 200, 105, 190);
      getToolkit().sync();

      for (i=0; i<70; i++) {
        try { Thread.sleep(10); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 195);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 185);
  
        g.setColor(Color.red);
        g.drawLine(105+i*5, 190,  105+i*5+5, 190);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 195);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 185);
        getToolkit().sync();
      }


      for (i=0; i<5; i++) {
        g.setColor(Color.magenta);
        g.fill3DRect(460, 170, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
        g.setColor(Color.cyan);
        g.fill3DRect(460, 170, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
      }

      
      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);
      starty = 6*hseparation+TM;
      startx = fm.stringWidth("  int val = ")+LM;
      endy = 185+5;
      endx = 470;

      for (i=1; i<=40; i++) {
        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        gc.setColor(Color.black);
        DrawProgram(gc);
        DrawMainAlloc(gc);

        gc.setColor(Color.green);
        gc.setFont(font);
        try { Thread.sleep(30); } catch (Exception e1){}
        gc.drawString("0", startx+((endx - startx)*i)/40, starty+((endy - starty)*i)/40);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
      }
      g.setColor(Color.black);
      g.setFont(font);
      g.drawString("0", endx, endy);

      cp.bnext.enable();
      break;

     case 2:
      g.setColor(Color.red);
      g.drawLine(195, 95, 195, 120);
      g.drawRect(177, 95-20, 37, 20);
      getToolkit().sync();

      for (i=0; i<52; i++) {
        try {
          Thread.sleep(20);
        } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(195+(i-1)*5+5, 120, 195+(i-1)*5+1, 125);
        g.drawLine(195+(i-1)*5+5, 120, 195+(i-1)*5+1, 115);

        g.setColor(Color.red);
        g.drawLine(195+i*5, 120,  195+i*5+5, 120);
        g.drawLine(195+i*5+5, 120, 195+i*5+1, 125);
        g.drawLine(195+i*5+5, 120, 195+i*5+1, 115);
        getToolkit().sync();
      }

      for (i=0; i<5; i++) {
        g.setColor(Color.cyan);
        g.fill3DRect(460, 110, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
        g.setColor(Color.magenta);
        g.fill3DRect(460, 110, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
      }

      cp.bnext.enable();
      break;

     case 3:
      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);
      starty = 2*hseparation+TM;
      startx = fm.stringWidth("void fun(int  val) { val = ")+LM; 	/*}*/
      endy = 125+5;
      endx = 470;

      for (i=1; i<=15; i++) {
        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        DrawProgram(gc);
        DrawMainAlloc(gc);
        gc.setColor(Color.black);
        gc.setFont(font);
        gc.drawString("0", 470, 190);
        DrawFunAlloc(gc);

        gc.setColor(Color.green);
        try { Thread.sleep(50); } catch (Exception e1){}
        gc.drawString("1", startx+((endx - startx)*i)/15, starty+((endy - starty
)*i)/15);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
      }
      g.setColor(Color.black);
      g.setFont(font);
      g.drawString("1", endx, endy);

      cp.bnext.enable();
      break;

     case 4:
      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);

      for (i=0; i<7; i++) {
        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        DrawProgram(gc);
        DrawMainAlloc(gc);
        gc.setColor(Color.black);
        gc.setFont(font);
        gc.drawString("0", 470, 190);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
        if (i==6) break;

        try { Thread.sleep(80); } catch (Exception e1){}

        DrawFunAlloc(gc);
        gc.setColor(Color.black);
        gc.drawString("1", 470, 130);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();


        try { Thread.sleep(80); } catch (Exception e1){}
      }

      cp.bnext.enable();
      break;

     case 5:
      dim = size();
      g.setColor(Color.orange);
      g.fillRect(0, 420, dim.width, dim.height);
      g.setColor(Color.black);
      g.setFont(outputfont);
      g.drawString("Output:", LM, 430+hseparation);
      g.setFont(font);
      g.drawString("Before the function call, val is 0", LM, 430+3*hseparation);
      g.drawString("After the function call, val is 0", LM, 430+4*hseparation);

      cp.bnext.enable();
      break;

     case 6:
      dim = size();
      g.setColor(bgColor);
      g.setFont(font);
      g.fillRect(0, 0, dim.width, dim.height);
      DrawProgram(g);

      for (i=0; i<10; i++) {
        try { Thread.sleep(150); } catch (Exception e1){}
        g.setColor(bgColor);
        g.setFont(font);
        g.drawString("&", LM+fm.stringWidth("void fun(int "), TM+2*hseparation);
        getToolkit().sync();

        try { Thread.sleep(150); } catch (Exception e1){}
        g.setColor(Color.green);
        g.drawString("&", LM+fm.stringWidth("void fun(int "), TM+2*hseparation);
        getToolkit().sync();
      }

      cp.bnext.enable();
      break;



     case 7:
      g.setColor(Color.red);
      g.drawRect(88, 200, 37, 20);
      g.drawLine(105, 200, 105, 190);
      getToolkit().sync();

      for (i=0; i<70; i++) {
        try { Thread.sleep(20); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 195);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 185);
 
        g.setColor(Color.red);
        g.drawLine(105+i*5, 190,  105+i*5+5, 190);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 195);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 185);
        getToolkit().sync();
      }
 
      for (i=0; i<5; i++) {
        g.setColor(Color.cyan);
        g.fill3DRect(460, 170, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
        g.setColor(Color.magenta);
        g.fill3DRect(460, 170, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
      }

      g.setColor(Color.black);
      g.setFont(font);
      g.drawString("0", 470, 190);

      cp.bnext.enable();
      break;

     case 8:
      g.setColor(Color.red);
      g.drawLine(195, 95, 195, 180);
      g.drawRect(177, 95-20, 37, 20);
      getToolkit().sync();

      for (i=0; i<52; i++) {
        try { Thread.sleep(20); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(195+(i-1)*5+5, 180, 195+(i-1)*5+1, 185);
        g.drawLine(195+(i-1)*5+5, 180, 195+(i-1)*5+1, 175);

        g.setColor(Color.red);
        g.drawLine(195+i*5, 180,  195+i*5+5, 180);
        g.drawLine(195+i*5+5, 180, 195+i*5+1, 185);
        g.drawLine(195+i*5+5, 180, 195+i*5+1, 175);
        getToolkit().sync();
      }
/*      g.setColor(bgColor);
      g.drawLine(195+(i-1)*5+5, 180, 195+(i-1)*5+1, 185);
      g.drawLine(195+(i-1)*5+5, 180, 195+(i-1)*5+1, 175); */

/*      start=195+i*5;
      for (i=0; i<9; i++) {
        try { Thread.sleep(20); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(start, 125+i*5, start-5, 125+(i-1)*5+1);
        g.drawLine(start, 125+i*5, start+5, 125+(i-1)*5+1);

        g.setColor(Color.red);
        g.drawLine(start, 125+(i+1)*5, start, 125+i*5);
        g.drawLine(start, 125+(i+1)*5, start-5, 125+i*5+1);
        g.drawLine(start, 125+(i+1)*5, start+5, 125+i*5+1);
        getToolkit().sync();
      } */

      cp.bnext.enable();
      break;


     case 9:
      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);
      starty = 2*hseparation+TM;
      startx = fm.stringWidth("void fun(int &val) { val = ")+LM; 	/*}*/
      endy = 185+5;
      endx = 470;

      for (i=1; i<=15; i++) {
        try { Thread.sleep(50); } catch (Exception e1){}

        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        DrawProgram(gc);
        gc.setColor(Color.green);
        gc.drawString("&", LM+fm.stringWidth("void fun(int "),TM+2*hseparation);
        DrawMainAlloc(gc);
        gc.setColor(Color.black);
        if (i!=15) gc.drawString("0", 470, 190);
        DrawFunReference(gc);

        if (i!=15) 
          gc.setColor(Color.green);
        else
          gc.setColor(Color.black);
        gc.drawString("1", startx+((endx - startx)*i)/15, starty+((endy - starty
)*i)/15);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
      }

      cp.bnext.enable();
      break;

     case 10:
      dim = size();
      g.setColor(Color.orange);
      g.fillRect(0, 420, dim.width, dim.height);
      g.setColor(Color.black);
      g.setFont(outputfont);
      g.drawString("Output:", LM, 430+hseparation);
      g.setFont(font);
      g.drawString("Before the function call, val is 0", LM, 430+3*hseparation);
      g.drawString("After the function call, val is 1", LM, 430+4*hseparation);
      
      cp.bnext.enable();
      break;

     case 11:
     case 12:
      paint(g);
      cp.bnext.enable();
      break;

     case 13:
      paint(g);
      cp.bnext.enable();
      break;

     case 14:
      g.setColor(Color.red);
      g.drawRect(88, 200, 37, 20);
      g.drawLine(105, 200, 105, 190);
      getToolkit().sync();

      for (i=0; i<35; i++) {
        try { Thread.sleep(10); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 195);
        g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 185);

        g.setColor(Color.red);
        g.drawLine(105+i*5, 190,  105+i*5+5, 190);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 195);
        g.drawLine(105+i*5+5, 190, 105+i*5+1, 185);
        getToolkit().sync();
      }
      g.setColor(bgColor);
      g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 195);
      g.drawLine(105+(i-1)*5+5, 190, 105+(i-1)*5+1, 185);
      getToolkit().sync();

      int tmpx = 105+35*5;
      for (i=0; i<2*30/5; i++) {
        try { Thread.sleep(10); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(tmpx, 190-(i-1)*5-5, tmpx-5, 190-(i-1)*5-1);
        g.drawLine(tmpx, 190-(i-1)*5-5, tmpx+5, 190-(i-1)*5-1);

        g.setColor(Color.red);
        g.drawLine(tmpx, 190-i*5, tmpx, 190-i*5-5);
        g.drawLine(tmpx, 190-i*5-5, tmpx-5, 190-i*5-1);
        g.drawLine(tmpx, 190-i*5-5, tmpx+5, 190-i*5-1);
        getToolkit().sync();
      }
      g.setColor(bgColor);
      g.drawLine(tmpx, 190-(i-1)*5-5, tmpx-5, 190-(i-1)*5-1);
      g.drawLine(tmpx, 190-(i-1)*5-5, tmpx+5, 190-(i-1)*5-1);
      getToolkit().sync();

      for (i=35; i<70; i++) {
        try { Thread.sleep(10); } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(105+(i-1)*5+5, 190-2*30, 105+(i-1)*5+1, 195-2*30);
        g.drawLine(105+(i-1)*5+5, 190-2*30, 105+(i-1)*5+1, 185-2*30);

        g.setColor(Color.red);
        g.drawLine(105+i*5, 190-2*30,  105+i*5+5, 190-2*30);
        g.drawLine(105+i*5+5, 190-2*30, 105+i*5+1, 195-2*30);
        g.drawLine(105+i*5+5, 190-2*30, 105+i*5+1, 185-2*30);
        getToolkit().sync();
      }


      for (i=0; i<5; i++) {
        g.setColor(Color.magenta);
        g.fill3DRect(460, 110, 30, 30, true);
        g.fill3DRect(460, 140, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
        g.setColor(Color.cyan);
        g.fill3DRect(460, 110, 30, 30, true);
        g.fill3DRect(460, 140, 30, 30, true);
        getToolkit().sync();
        try { Thread.sleep(80); } catch (Exception e1){}
      }
      DrawArrayDescription(g);

      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);
      starty = 7*hseparation+TM;
      startx = fm.stringWidth("  val[1] = ")+LM;
      endy = 155+5;
      endx = 470;

      for (i=1; i<=40; i++) {
        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        gc.setColor(Color.black);
        DrawProgram_Array(gc);
        DrawArrayAlloc(gc);
        DrawArrayDescription(gc);

        gc.setColor(Color.green);
        gc.setFont(font);
        try { Thread.sleep(30); } catch (Exception e1){}
        gc.drawString("0", startx+((endx - startx)*i)/40, starty+((endy - starty)*i)/40);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
      }
      g.setColor(Color.black);
      g.setFont(font);
      g.drawString("0", endx, endy);

      cp.bnext.enable();
      break;


     case 15:
      g.setColor(Color.red);
      g.drawLine(195, 95, 195, 120);
      g.drawRect(177, 95-20, 37, 20);
      getToolkit().sync();

      for (i=0; i<52; i++) {
        try {
          Thread.sleep(20);
        } catch (Exception e1){}
        g.setColor(bgColor);
        g.drawLine(195+(i-1)*5+5, 120, 195+(i-1)*5+1, 125);
        g.drawLine(195+(i-1)*5+5, 120, 195+(i-1)*5+1, 115);

        g.setColor(Color.red);
        g.drawLine(195+i*5, 120,  195+i*5+5, 120);
        g.drawLine(195+i*5+5, 120, 195+i*5+1, 125);
        g.drawLine(195+i*5+5, 120, 195+i*5+1, 115);
        getToolkit().sync();
      }

      cp.bnext.enable();
      break;


     case 16:
      dim = size();
      gc = img.getGraphics();
      gc.setFont(font);
      starty = 2*hseparation+TM;
      startx = fm.stringWidth("void fun(int  val[]) { val[1] = ")+LM;     /*}*/
      endy = 155+5;
      endx = 470;

      for (i=1; i<=15; i++) {
        gc.setColor(bgColor);
        gc.fillRect(0, 0, dim.width, dim.height);
        DrawProgram_Array(gc);
        DrawArrayAlloc(gc);
        DrawFunAlloc(gc);
        DrawArrayDescription(gc);
        gc.setColor(Color.black);
        gc.setFont(font);
        if (i!=15) gc.drawString("0", endx, endy);

        gc.setColor(Color.green);
        try { Thread.sleep(50); } catch (Exception e1){}
        gc.drawString("1", startx+((endx - startx)*i)/15, starty+((endy - starty
)*i)/15);
        g.drawImage(img, 0, 0, this);
        getToolkit().sync();
      }
      g.setColor(Color.black);
      g.setFont(font);
      g.drawString("1", endx, endy);

      cp.bnext.enable();
      break;


     case 17:
      paint(g);
      cp.bnext.enable();
      break;



     case 18:
      cp.bnext.setLabel("Restart");
      cp.bnext.enable();
      break;


     default:
      break;
    }


  }	/* End Method Update() */


  void DrawMainAlloc(Graphics g) {

    g.setColor(Color.red);
    g.drawRect(90, 200, 35, 20);
    g.drawLine(105, 200, 105, 190);
 
    g.drawLine(105, 190, 455, 190);
    g.drawLine(455, 190, 455-4, 195);
    g.drawLine(455, 190, 455-4, 185);
    g.setColor(Color.magenta);
    g.fill3DRect(460, 170, 30, 30, true);
  }

  void DrawFunAlloc(Graphics g) {

    g.setColor(Color.red);
    g.drawLine(195, 95, 195, 120);
    g.drawRect(177, 95-20, 37, 20);

    g.drawLine(195, 120,  455, 120);
    g.drawLine(455, 120, 455-4, 125);
    g.drawLine(455, 120, 455-4, 115);

    g.setColor(Color.magenta);
    g.fill3DRect(460, 110, 30, 30, true);
  }

  void DrawArrayAlloc(Graphics g) {
    g.setColor(Color.red);
    g.drawRect(90, 200, 35, 20);
    g.drawLine(105, 200, 105, 190);

    g.drawLine(105, 190, 105+35*5, 190);
    g.drawLine(105+35*5, 190, 105+35*5, 190-60);

    g.drawLine(105+35*5, 190-60, 105+70*5, 190-60);
    g.drawLine(455, 190-60, 455-4, 195-60);
    g.drawLine(455, 190-60, 455-4, 185-60);

    g.setColor(Color.magenta);
    g.fill3DRect(460, 110, 30, 30, true);
    g.fill3DRect(460, 140, 30, 30, true);
  }


  void DrawFunReference(Graphics g) {
      g.setColor(Color.red);
      g.drawLine(195, 95, 195, 180);
      g.drawRect(177, 95-20, 37, 20);
      getToolkit().sync();

      g.drawLine(195, 180, 455, 180);
      g.drawLine(455, 180, 455-4, 185);
      g.drawLine(455, 180, 455-4, 175);
  }


  public void paint(Graphics g) { 
    Dimension dim = size(); 

    if (dim.width <= 0 || dim.height <= 0) return; 
    if (img==null) img = createImage(dim.width, dim.height);

    Graphics gc = img.getGraphics();
    gc.setFont(font);
    

    gc.setColor(bgColor);
    gc.fillRect(0, 0, dim.width, dim.height);

    gc.setColor(Color.black);
    switch (status) {
     case 0:
      DrawProgram(gc);
      break;

     case 1:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);
      break;

     case 2:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);
      DrawFunAlloc(gc);
      break;

     case 3:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);
      DrawFunAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("1", 470, 130);
      break;

     case 4:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);
      break;


     case 5:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);

      dim = size();
      gc.setColor(Color.orange);
      gc.fillRect(0, 420, dim.width, dim.height);
      gc.setColor(Color.black);
      gc.setFont(outputfont);
      gc.drawString("Output:", LM, 430+hseparation);
      gc.setFont(font);
      gc.drawString("Before the function call, val is 0",LM, 430+3*hseparation);
      gc.drawString("After the function call, val is 0",LM, 430+4*hseparation);
      break;

     case 6:
      DrawProgram(gc);
      gc.setColor(Color.green);
      gc.setFont(font);
      gc.drawString("&", LM+fm.stringWidth("void fun(int "),TM+2*hseparation);
      break;

     case 7:
      DrawProgram(gc);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.setFont(font);
      gc.drawString("0", 470, 190);
      break;

     case 8:
      DrawProgram(gc);
      gc.setColor(Color.green);
      gc.setFont(font);
      gc.drawString("&", LM+fm.stringWidth("void fun(int "),TM+2*hseparation);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.drawString("0", 470, 190);
      DrawFunReference(gc);
      break;

     case 9:
      DrawProgram(gc);
      gc.setColor(Color.green);
      gc.setFont(font);
      gc.drawString("&", LM+fm.stringWidth("void fun(int "),TM+2*hseparation);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.drawString("1", 470, 190);
      DrawFunReference(gc);
      break;

     case 10:
      DrawProgram(gc);
      gc.setColor(Color.green);
      gc.setFont(font);
      gc.drawString("&", LM+fm.stringWidth("void fun(int "),TM+2*hseparation);
      DrawMainAlloc(gc);
      gc.setColor(Color.black);
      gc.drawString("1", 470, 190);
      DrawFunReference(gc);

      dim = size();
      gc.setColor(Color.orange);
      gc.fillRect(0, 420, dim.width, dim.height);
      gc.setColor(Color.black);
      gc.setFont(outputfont);
      gc.drawString("Output:", LM, 430+hseparation);
      gc.setFont(font);
      gc.drawString("Before the function call, val is 0",LM, 430+3*hseparation);
      gc.drawString("After the function call, val is 1",LM, 430+4*hseparation);
      break;

     case 11:
     case 12:
      DrawProgram_DifferentName(gc);
      break;

     case 13:
      DrawProgram_Array(gc);
      break;

     case 14:
      DrawProgram_Array(gc);
      DrawArrayAlloc(gc);
      DrawArrayDescription(gc);
      gc.setColor(Color.black);
      gc.drawString("0", 470, 155+5);
      break;

     case 15:
      DrawProgram_Array(gc);
      DrawArrayAlloc(gc);
      DrawFunAlloc(gc);
      DrawArrayDescription(gc);
      gc.setColor(Color.black);
      gc.drawString("0", 470, 155+5);
      break;

     case 16:
      DrawProgram_Array(gc);
      DrawArrayAlloc(gc);
      DrawFunAlloc(gc);
      DrawArrayDescription(gc);
      gc.setColor(Color.black);
      gc.drawString("1", 470, 155+5);
      break;

     case 17:
     case 18:
      DrawProgram_Array(gc);
      DrawArrayAlloc(gc);
      DrawFunAlloc(gc);
      DrawArrayDescription(gc);
      gc.setColor(Color.black);
      gc.drawString("1", 470, 155+5);

      dim = size();
      gc.setColor(Color.orange);
      gc.fillRect(0, 420, dim.width, dim.height);
      gc.setColor(Color.black);
      gc.setFont(outputfont);
      gc.drawString("Output:", LM, 430+hseparation);
      gc.setFont(font);
      gc.drawString("Before the function call, val[1] is 0", LM, 430+3*hseparation);
      gc.drawString("After the function call, val[1] is 1", LM, 430+4*hseparation);
      break;

     default:
      break;
    }



    g.drawImage(img, 0, 0, this);

  }	/* End Method paint() */


  void DrawProgram(Graphics gc) {

      gc.setColor(Color.black);
      gc.setFont(font);

      gc.drawString("#include <iostream.h>", LM, TM);

      gc.drawString("void fun(int  val) { val = 1; }", LM, TM+2*hseparation);

      gc.drawString("void main()", LM, TM+5*hseparation);
      gc.drawString("{", LM, TM+6*hseparation);
      gc.drawString("  int val = 0;", LM, TM+7*hseparation);

      gc.drawString("  cout << \"Before the function call, val is \"", LM, TM+9*hseparation);
      gc.drawString("       << val << \"\\n\";", LM, TM+10*hseparation);
      gc.drawString("  fun(val);", LM, TM+11*hseparation);
      gc.drawString("  cout << \"After the function call, val is \"", LM, TM+12*hseparation);
      gc.drawString("       << val << \"\\n\";", LM, TM+13*hseparation);
      gc.drawString("}", LM, TM+14*hseparation);

      DrawStorage(gc);
  }


  void DrawProgram_DifferentName(Graphics gc) {

      gc.setColor(Color.black);
      gc.setFont(font);

      gc.drawString("#include <iostream.h>", LM, TM);


      int w1 = fm.stringWidth("void fun(int  ");
      int w2 = fm.stringWidth("void fun(int  par");
      int w3 = fm.stringWidth("void fun(int  par) { ");	/* } */
      int w4 = fm.stringWidth("void fun(int  par) { par"); /* } */

      gc.drawString("void fun(int  ", LM, TM+2*hseparation);
      gc.setColor(Color.green);
      gc.drawString("par", LM+w1, TM+2*hseparation);
      gc.setColor(Color.black);
      gc.drawString(") { ", LM+w2, TM+2*hseparation);
      gc.setColor(Color.green);
      gc.drawString("par", LM+w3, TM+2*hseparation);
      gc.setColor(Color.black);
      gc.drawString(" = 1; }", LM+w4, TM+2*hseparation);

      gc.drawString("void main()", LM, TM+5*hseparation);
      gc.drawString("{", LM, TM+6*hseparation);
      gc.drawString("  int val = 0;", LM, TM+7*hseparation);

      gc.drawString("  cout << \"Before the function call, val is \"", LM, TM+9*hseparation);
      gc.drawString("       << val << \"\\n\";", LM, TM+10*hseparation);
      gc.drawString("  fun(val);", LM, TM+11*hseparation);
      gc.drawString("  cout << \"After the function call, val is \"", LM, TM+12*hseparation);
      gc.drawString("       << val << \"\\n\";", LM, TM+13*hseparation);
      gc.drawString("}", LM, TM+14*hseparation);

      DrawStorage(gc);

  }	/* End Method DrawProgram_DifferentName() */


  void DrawProgram_Array(Graphics gc) {

      gc.setColor(Color.black);
      gc.setFont(font);

      gc.drawString("#include <iostream.h>", LM, TM);

      gc.drawString("void fun(int  par[]) { par[1] = 1; }", LM, TM+2*hseparation);

      gc.drawString("void main()", LM, TM+5*hseparation);
      gc.drawString("{", LM, TM+6*hseparation);
      gc.drawString("  int val[2];", LM, TM+7*hseparation);
      gc.drawString("  val[1] = 0;", LM, TM+8*hseparation);

      gc.drawString("  cout << \"Before the function call, val[1] is \"", LM, TM+10*hseparation);
      gc.drawString("       << val[1] << \"\\n\";", LM, TM+11*hseparation);
      gc.drawString("  fun(val);", LM, TM+12*hseparation);
      gc.drawString("  cout << \"After the function call, val[1] is \"", LM, TM+13*hseparation);
      gc.drawString("       << val[1] << \"\\n\";", LM, TM+14*hseparation);
      gc.drawString("}", LM, TM+15*hseparation);

      DrawStorage(gc);
  }



  void DrawStorage(Graphics gc) {
      gc.setColor(Color.cyan);
      gc.fill3DRect(460, 170+30, 30, 30, true);
      gc.fill3DRect(460, 170, 30, 30, true);
      gc.fill3DRect(460, 170-30, 30, 30, true);
      gc.fill3DRect(460, 170-2*30, 30, 30, true);
      gc.fill3DRect(460, 170-3*30, 30, 30, true);
      gc.fill3DRect(460, 170-4*30, 30, 30, true);

      gc.setColor(Color.black);
      gc.setFont(memoryfont);
      gc.drawString("Computer", 445, 170-4*30-(18+5));
      gc.drawString("Memory", 450, 170-4*30-5);
      gc.setFont(font);
  }


  void DrawArrayDescription(Graphics gc) {
      gc.setColor(Color.black);
      gc.drawString("val[0]", 470+30, 130);
      gc.drawString("val[1]", 470+30, 160);
  }


}	/* End Class DrawingArea */




class Description extends Frame {
  int status=0;
  Font font = new Font("Courier", Font.PLAIN, 18);
  FontMetrics fm;
  int FontHeight;
  int SpaceWidth;
  int LM=20, TM=60;
  int width=400, height=400;
  Color bgColor = new Color(170, 170, 170);    /* set background as cornsilk */

  String str[] = new String[20];

  public Description() {
    super("Description");

    str[0] = "Press Next to begin...";
    str[1] = " By default, C++ passes arguments from one function to another by value. @@ This example show how passing parameter by value works. In main(), a variable val is declared. A memory unit is allocated for the storage of the content of the variable val. val is then initialized to zero.";
    str[2] = " main() then passes val to the function fun() by value. Fun() allocates another memory unit for this parameter and copy the content of val in main() to this memory unit. Thererfore, val in main() and fun() are different variables and have different memory units allocated.";
    str[3] = " The function fun() then modifies its own copy of val and this action does not affect the value of val in main().";
    str[4] = " When fun() is finished, memory unit allocated for the parameter is destroyed.";
    str[5] = " From the output, we see that the function fun() hasn't changed the value of val in main().";

    str[6] = "Now, Let's see how the program works if the function fun() get parameter by reference. A parameter of a function is passed by reference if there is an \"&\" symbol before the variable name in the function declaration.";
    str[7] = "As before, main() allocates a memory unit for the variable val and initializes it to zero.";
    str[8] = "main() then passes val to the function fun() by reference. This time fun() does not allocate another memory unit for the parameter val. Fun() get an alias of the the variable val in main() and the two vals in main() and fun() share the same memory unit. Thus, any modification of val in fun() will also affect the content of val in main().";
    str[9] = "Fun() then modifies the parameter val. Since val in fun() and val in main() share the same memory unit, the value of val in main() is also changed.";
    str[10] = "From the output, we see that after the execution of fun() the value of val in main() has changed from 0 to 1.";
    str[11] = "Next, we will discuss what are formal and actual parameters. The parameter list of a function describes its formal parameters. Each formal parameter is provided storage when the function is called. The expressions found between the parentheses of a function call are referred to as the actual parameters of the call. Parameter passing is the process of initializing the storage of the formal parameters by the actual parameters.";
    str[12] = "In the previous examples, both the formal and actual parameters got the same name. However, even if their names are different (eg, the name of the formal parameter change to par), the results of the examples are still the same. The names of formal and actual parameters do not need to have any relation.";
    str[13] = "Now, we will discuss the last parameter passing method -- passing array as parameter. Passing array parameter is like passing parameter by reference.  The changes to the array content inside a function is still in effect even after the function is finished.";
    str[14] = "In main(), an array variable val[] is declared. Memory units are allocated for the storage of this array. val[1] is then initialized to zero.";
    str[15] = "main() then passes the array val[] to the function fun(). Similar to the case of passing parameters by reference, fun() does not allocate other memory units for the array parameter par[]. Fun() get an alias of the the variable val[] in main() and the val[] in main() and par[] in fun() share the same memory units. Thus, any modification of par[] in fun() will also affect the content of val[] in main().";
    str[16] = "Fun() then modifies par[1] inside the function. Since par[] in fun() and val[] in main() share the same memory units, the value of val[1] in main() is also changed.";
    str[17] = "From the output, we see that after the execution of fun() the value of val[1] in main() has changed from 0 to 1.";
    str[18] = "Press Restart to restart the demo or press Close to close the demo";


    fm = getFontMetrics(font);
    SpaceWidth = fm.charWidth(' ');
    FontHeight = fm.getHeight();

    setBackground(Color.gray);
    setForeground(Color.black);
    resize(width, height);
  }

  public void Reset() {
    status=0;
    repaint();
  }

  void Next() {
    status++;
    repaint();
  }

  public void paint(Graphics g) {

    int x=LM, y=TM;
    int hseparation=FontHeight+5;
    int rowend = width-LM;
    
    g.setColor(bgColor);
    g.setFont(font);
    g.fillRect(0, 0, width-1, height-1);
    g.setColor(Color.black);
    StringTokenizer st = new StringTokenizer(str[status]); 
    while (st.hasMoreTokens()) {
      String s = st.nextToken();

      if (s.equals("@@")) {
        x = LM;
        y += 2*hseparation;
        continue;
      }

      if (x+fm.stringWidth(s) > rowend 
          && (rowend-x < 30 || x+fm.stringWidth(s) >= width)) {
        x = LM;
        y += hseparation;
      }

      g.drawString(s, x, y);
      x += (fm.stringWidth(s)+SpaceWidth);
    }

  }

}	/* End Class Description */
