package t_particle;

import java.applet.Applet;
import java.awt.Canvas;
import java.awt.Graphics;

public class ParticleApplet extends Applet {


@Override
public void init() {
    // podesavamo velicinu i dodajemo platno za crtanje
    super.init();
    setSize(500,500);
    add(new ParticleCanvas());
}    
}

/*nasledjena klasa jer su nam potrebni
 * specificni podaci o cesticama (particles)
 */
class ParticleCanvas extends Canvas{
    Particle[] particles;
    public ParticleCanvas() {
	setSize(500,500);
	/*alociramo 20 cestica i pokrecemo njihove niti*/
	particles=new Particle[20];
	for(int i=0; i<particles.length; i++){
	    particles[i]=new Particle(this);
	    /*metod start govori JVM da je nit spremna
	     * da udje u stanje izvrsavanja, no to ne znaci
	     * da ce ona nuzno i uci odmah u to stanje
	     * Ona jednostavno ulazi u stanje izvrsivosti (Runnable)
	     */
	    new Thread(particles[i]).start();
	}
	    
    }
    
    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        /* iscrtavamo sve cestice, primetiti da 
         * ovaj metod moze da se izvrsava konkurentno 
         * sa metodom move() iz klase Particle
         */
        for(int i=0; i<particles.length; i++){
            particles[i].draw(g);
        }
    }
}

class Particle implements Runnable{

    /*koordinate cestice*/
    int x;
    int y;
    /*referenca na platno, postavlja se u konstruktoru*/
    Canvas canvas;
    public Particle(Canvas canvas) {
	this.canvas=canvas;
	/*postavljamo cesticu na slucajnu lokaciju*/
	x=(int)(Math.random()*canvas.getWidth());
	y=(int)(Math.random()*canvas.getHeight());
    }
    
    /*synchronized znaci da se ceo sadrzaj metoda, tj.
     * sve njegove naredbe izvrsavaju serijski, ne mogu
     * biti prekinute
     */
    synchronized void move(){
	x = x +(int)((Math.random() - 0.5)*5);
	/*da nema synchronized reci neka druga nit
	 * npr. nit za iscrtavanje bi mogla da prekine 
	 * ovu nit posle promene x koordinate i samim
	 * tim je dovede u nekonzistentno stanje. Ovde to 
	 * naravno nema znacajne posledice, ali zamislimo
	 * da se to desi u toku prenosa novca sa jednog
	 * na drugi racun
	 */
	y = y +(int)((Math.random() - 0.5)*5);
    }
    
    void draw(Graphics g){
	
	g.drawRect(x, y, 10,10);
    }
    
    @Override
    public void run() {
        
	while(true){
	    /*pomeramo slucajno cesticu*/
	    move();
	    /*pozivamo platno da se ponovo iscrta*/
	    canvas.repaint();
	    try {
		/*dajemo pauzu niti, kako ne bi preopterecivala
		 * platno sa stalnim pozivima za iscrtavanje
		 */
		Thread.sleep((long)(Math.random()*100));
	    } catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	}
    }
}



