import java.awt.*;
import java.applet.*;
import java.util.Date;
public class auto3 extends Applet implements Runnable{
 Image pilt, apilt, jpilt, veopilt;
 Graphics piltg, seegr, jpiltg;
 Thread tr;
 valik3 
        kv=new valik3(this, "kiirus", 0, 5, 300, 0.5), pv=new valik3(this, "pikkus", 0.5, 4, 35, 0.1);
 Label vl=new Label("d(m)="), kl=new Label("v(m/s)="), pl=new Label("l(m)="),
       vv=new Label();
 Panel vp=new Panel();
 masin3 masinad[]=new masin3[40];
 int  pikkus, algus=0, ots=0; 
 float avahe=3, pm=10, v=5, apikkus=4;
 long aeg1=0, aeg2;
 int vahe=0;

 public void init(){
 aeg1=(new Date()).getTime();
 apilt=getImage(getCodeBase(), "auto03.gif");
 veopilt=getImage(getCodeBase(), "auto1.gif");
 pikkus=(this.size()).width;
 pilt=createImage(pikkus, 100);
 piltg=pilt.getGraphics();
 jpilt=createImage(pikkus, 210);
 jpiltg=jpilt.getGraphics();
 seegr=this.getGraphics();
 for(int i=0; i<40; i++)masinad[i]=new masin3(this);
 vp.setLayout(new GridLayout(2, 3));
 vp.add(vl); vp.add(kl); vp.add(pl);
 vp.add(vv); vp.add(kv); vp.add(pv);
 setLayout(new BorderLayout());
 add("South", vp);
 avahe=leiavahe(v); vv.setText(Double.toString(avahe));
 joonis();
 }

void liiguta(){
piltg.setColor(Color.white);
piltg.fillRect(0, 0, 500, 100);
piltg.setColor(Color.black);
if(masinad[algus].x-apikkus>500/pm)if(algus!=ots){if(algus<39)algus++ ; else algus=0;}
 if(masinad[ots].x>apikkus+avahe){
  if(ots<39) ots++; else ots=0;
  masinad[ots].x=masinad[(ots>0)? ots-1 : 39].x-apikkus-avahe;}
for(int i=algus; i!=ots; ) {masinad[i].edasi(piltg);if(i<39)i++; else i=0;}
masinad[ots].edasi(piltg);
seegr.drawImage(pilt, 0, 0, this);
}
void seaVaartus(valik3 vl){
 if(vl.ise=="kiirus")v=(float)vl.vaartus;
 if(vl.ise=="pikkus")apikkus=(float)vl.vaartus;
 avahe=leiavahe(v);
 vv.setText(Double.toString(avahe));
 joonis();
}
float leiavahe(float kr){
return (float)(kr*kr/5.0+0.8*kr);
}
void joonis(){
 int kiirus, voog, ux, uy, vx=50, vy=200 ;
 double svahe;
 jpiltg.setColor(Color.white);
 jpiltg.fillRect(0, 0, 400, 200);
 jpiltg.setColor(Color.black);
 jpiltg.drawLine(50, 200, 50, 15);
 jpiltg.drawLine(50, 10, 48, 18);
 jpiltg.drawLine(50, 10, 52, 18);
 jpiltg.drawLine(50, 200, 350, 200);
 for(voog=0; voog<200; voog+=25){
  jpiltg.drawString(Integer.toString(voog), 20, 200-voog );
  jpiltg.drawLine(45, 200-voog, 55, 200-voog);}
  jpiltg.drawString("f auto/min", 10, 15);
 for(kiirus=20; kiirus<160; kiirus+=20)
  jpiltg.drawString(Integer.toString(kiirus), 50+2*kiirus, 200);
  jpiltg.drawString("v (km/h)", 350, 190);
 for(kiirus=0; kiirus<=150; kiirus++){
 ux=(int)(50+7.2*kiirus);
 svahe=leiavahe(kiirus);
 uy=200-(int)(60*kiirus/(apikkus+svahe));
 if(ux<350&uy>10)jpiltg.drawLine(vx, vy, ux, uy); vx=ux; vy=uy;}
 jpiltg.setColor(Color.red);
 jpiltg.fillOval((int)(47+7.2*v), 197-(int)(60*v/(apikkus+avahe)), 6, 6);
 repaint();
}

public void paint(Graphics g){
g.drawImage(pilt, 0, 0, this);
g.drawImage(jpilt, 0, 100, this);
}
public void update(Graphics g){paint(g);}
public void start(){if(tr==null)tr=new Thread(this);  tr.start();}
public void stop(){tr=null;}
public void run(){while(tr!=null){
 liiguta();
 tr.yield();
 aeg2=(new Date()).getTime();
 vahe=(int)(aeg2-aeg1);
 if(vahe>25)vahe=25;
 aeg1=aeg2;
try{ tr.sleep(20);}catch(Exception e){}
}}


}


class masin3{
 float x=0;
 int y=2;
 auto3 ap;
 masin3(auto3 at){ap=at;}
public void joonista(){
 if(ap.apikkus<5)
ap.piltg.drawImage(ap.apilt, (int)((x-ap.apikkus)*ap.pm),20+(int)((y-ap.apikkus/5.0)*ap.pm),
                     (int)(ap.apikkus*ap.pm), (int)((y+ap.apikkus/5.0)*ap.pm), ap);
else
  ap.piltg.drawImage(ap.veopilt, (int)((x-ap.apikkus)*ap.pm),20+(int)((y-ap.apikkus/5.0)*ap.pm),
                     (int)(ap.apikkus*ap.pm), (int)((y+ap.apikkus/5.0)*ap.pm), ap); 

                     }
public boolean edasi(Graphics g){
 x+=(ap.v/40.0); joonista(); return true;
}
}

class valik3 extends Panel{
double min=0, alg=1, max=100;
TextField tf=new TextField(5);
double vaartus=1, vahe=1;
Button nv=new Button("<"), np=new Button(">");
String ise="";
auto3 ap;
public valik3(auto3 at, String st){
 ap=at;
 ise=st;
 setLayout(new BorderLayout());
 add("West", nv);
 add("Center", tf);
 add("East", np);
 vaartus=alg;
 tf.setText(Double.toString(vaartus));
}
public valik3(auto3 at, String st, double mv, double av, double sv, double vv){
 min=mv; alg=av; max=sv; vahe=vv;
 ap=at;
 ise=st;
 setLayout(new BorderLayout());
 add("West", nv);
 add("Center", tf);
 add("East", np);
 vaartus=alg;
 tf.setText(Double.toString(vaartus));

}

public boolean action(Event e, Object arg){
double abi;
 if(e.target==nv){abi=vaartus-vahe;if(abi>=min)vaartus-=vahe;}
 if(e.target==np){abi=vaartus+vahe;if(abi<=max)vaartus+=vahe;}
 if(e.target==tf){abi=Double.valueOf(tf.getText()).doubleValue();
                 if(!Double.isNaN(abi)&(abi>=min)&(abi<=max))vaartus=abi;}
 tf.setText(Double.toString(vaartus));
 ap.seaVaartus(this);
 return true;
}
public boolean keyUp(Event e, int key){
double abi;
 if(e.target==tf){abi=Double.valueOf(tf.getText()).doubleValue();
                 if(!Double.isNaN(abi)&(abi>=min)&(abi<=max))vaartus=abi;}
 tf.setText(Double.toString(vaartus));
 ap.seaVaartus(this);
 return true;
 
}
}
