import java.awt.*;

class DrawSim extends java.awt.Canvas {

//double-buffering

public boolean xplot=false;
public boolean vplot=true;

private Image image2;
private Graphics g2;

private Dimension mySize;

private int XSIZE,YSIZE,XOFFSET,YOFFSET;
private int MAXPOINTS=2000;
private double xscale,yscale,XMAX,YMAX,YMIN;
private int xpoints[],xvpoints[];
private int ypoints[],yvpoints[];
private int lastXPoint,lastVPoint;


DrawSim(){
  xpoints = new int[MAXPOINTS];
  ypoints = new int[MAXPOINTS];
  xvpoints = new int[MAXPOINTS];
  yvpoints = new int[MAXPOINTS];
  setBackground(Color.white);
}

public void paint(Graphics g){

// setup offscreen graphics object, setup axes and scale parameters
// resize background size if necessary 

  if (g2 == null) {determineSize();paintSetup();}
  else if ((this.size().width!=mySize.width) ||
           (this.size().height!=mySize.height)) paintSetup();

// paint background

  g2.setColor(this.getBackground());
  g2.fillRect(0,0,mySize.width,mySize.height);

// graph axes etc
  myAxes();


// go through all points and paint
  if(xplot){
  g2.setColor(Color.blue);
  
  for(int i=0;i<lastXPoint;i++) 
  g2.drawLine(xpoints[i],ypoints[i],xpoints[i+1],ypoints[i+1]);
  }

  if(vplot){ 
  g2.setColor(Color.red);

  for(int i=0;i<lastVPoint;i++)
  g2.drawLine(xvpoints[i],yvpoints[i],xvpoints[i+1],yvpoints[i+1]);
  }

// copy image to live version

  g.drawImage(image2,0,0,this); 
}
 

private void paintSetup() {

  mySize=this.size();

// Create second image space 

  image2 = createImage(mySize.width,mySize.height);
  g2=image2.getGraphics();
}

private void determineSize(){

  XOFFSET=80;
  YOFFSET=40;
  YSIZE=this.size().height-2*YOFFSET;
  YOFFSET=YSIZE+YOFFSET;
  XSIZE=this.size().width-2*XOFFSET;
  XMAX=10.0;

  if(xplot){
  YMAX=4.0;
  YMIN=-4.0;
  }
  else{
  YMAX=50.0;
  YMIN=-10.0;
  }
  
  xscale=(double)XSIZE/XMAX;
  yscale=-(double)YSIZE/(YMAX-YMIN);

}


private void myAxes(){
double x;

g2.setColor(Color.black);
  g2.drawLine(XOFFSET,YOFFSET+(int)(yscale*-YMIN),XSIZE+XOFFSET,
                      YOFFSET+(int)(yscale*-YMIN));
  g2.drawLine(XOFFSET,YOFFSET,XOFFSET,YOFFSET-YSIZE);

  for(int i=0;i<=4;i++){
  x=myformat(i*XMAX/4.0,1000);
  g2.drawString(String.valueOf(x),
  (int)(i*XMAX/4.0*xscale+XOFFSET), YOFFSET+20);}

  for(int i=0;i<=6;i++){
  x=myformat(i*(YMAX-YMIN)/6.0+YMIN,1000);
  g2.drawString(String.valueOf(x),
  20,(int)(YOFFSET+(int)(i*yscale*(YMAX-YMIN)/6.0+10)));}

}

public void update(Graphics g){
  paint(g);
}

public void addXToScreen(double x, double y){
  int ix, iy;
  ix=(int)(x*xscale)+XOFFSET;
  iy=(int)((y-YMIN)*yscale)+YOFFSET;


// only plot new pixels to screen

  if ( !( (lastXPoint>=0) &&
          (ix==xpoints[lastXPoint]))) 
           {

// wrap arrays around to avoid out-of-bounds problems

    if (++lastXPoint>=MAXPOINTS) lastXPoint=0;
    xpoints[lastXPoint]=ix;
    ypoints[lastXPoint]=iy;
  }

  repaint();
}

public void addVToScreen(double x, double y){
  int ix, iy;
  ix=(int)(x*xscale)+XOFFSET;
  iy=(int)((y-YMIN)*yscale)+YOFFSET;


// only plot new pixels to screen

  if ( !( (lastVPoint>=0) &&
          (ix==xvpoints[lastVPoint])))
           {

// wrap arrays around to avoid out-of-bounds problems

    if (++lastVPoint>=MAXPOINTS) lastVPoint=0;
    xvpoints[lastVPoint]=ix;
    yvpoints[lastVPoint]=iy;
  }

  repaint();
}


private double myformat(double x, int n){
double d;
int i;
d=x*n;
i=(int)d;
d=(double)i/(double)n;
return(d);
}

public void clearScreen(){
lastXPoint=-1;
lastVPoint=-1;}

} 

