import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import java.awt.Graphics;

//Author:H.Hakan GENÇ - December 2015 - Turkiye
//GSM: +905052610452, E-mail:hasanhakangenc@hotmail.com

public class Finite_Random_Walk extends Applet{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String deger, deger2, deger3;
	int sayac=0; 
	double x, y;
	boolean akis=false, aralik1=false, aralik2=false;
	Grafik grafik;
	Thread XY_hareket;
	Panel panel1, panel2, panel3, panel4;

	public void init(){
		System.out.println(getCodeBase());
		Label sayacEtiketi = new Label("250 ile 1000 arası N Değerini Gir:                   ");
		TextField sayacDegeri = new TextField(10);
		Button tamam = new Button("Tamam");
		
		TextField xDegeri = new TextField(10);
		TextField yDegeri = new TextField(10);
		
		Label xyEtiketi = new Label ("0.0 - 1.0 arasında bir X-Y değeri girin:");
		Button tamam2 = new Button ("Tamam");
		
		Label X = new Label("X:");
		Label Y = new Label("Y:");
		

		grafik = new Grafik("f0f0f0");
		add(grafik);
		
		panel1 = new Panel();
		panel2 = new Panel();
		panel3 = new Panel();
		panel4 = new Panel();
		
		panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
		panel2.setLayout(new FlowLayout(FlowLayout.LEFT));
		panel3.setLayout(new FlowLayout(FlowLayout.LEFT));
		panel4.setLayout(new BorderLayout());
		
		panel1.add(sayacEtiketi);
		panel1.add(sayacDegeri);
		panel1.add(tamam);
		
		panel2.add(xyEtiketi);
		
		panel3.add(X);
		panel3.add(xDegeri);
		panel3.add(Y);
		panel3.add(yDegeri);
		panel3.add(tamam2);
				
	//	panel3.setLayout(new GridLayout(2,1));
		panel4.add(panel1,"North");
		panel4.add(panel2,"Center");
		panel4.add(panel3,"South");
		
		setLayout(new BorderLayout());
		add(grafik,"South");
		add(panel4,"North");
		
		
		sayacDegeri.setText("");
		tamam.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){	
					deger = sayacDegeri.getText();
					sayac = Integer.parseInt(deger);
					if(sayac>=250 && sayac <=1000 && sayac%250 == 0 ){
						sayacEtiketi.setText("Uygun Değer Girildi:                                 ");
						akis=true;
						aralik1=true;
						if(aralik1 && aralik2){
							grafik.guncelle(sayac,akis,XY_hareket,x,y);
						}
					}
					else{
						sayacEtiketi.setText("Lütfen Aralık İçinde ve 250'nin katı bir değer girin");
						akis=false;
						aralik1=false;
					}
			}
		});
		
		tamam2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				deger2 = xDegeri.getText();
				deger3 = yDegeri.getText();
				x = Double.parseDouble(deger2);
				y = Double.parseDouble(deger3);
				if(x>=0.0 && x<=1.0 && y>=0.0 && y<=1.0){
					xyEtiketi.setText("Uygun Değer Girildi:                    ");
					akis=false;
					aralik2=true;
					sayac=0;
					grafik.guncelle(sayac,akis,XY_hareket,x,y);
				}
				else{
					xyEtiketi.setText("Lütfen 0.0 - 1.0 aralığında değer girin.");
					akis=false;
					aralik2=false;
				}
				
			}
		});
	}
	public void paint(Graphics g){
	}

}

class Grafik extends Canvas implements Runnable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	double v1=0, v2=0, v3=100, v4=0, v;
	double p1=0.25, p2=0.5, p3=0.75;
	double delta=0.01;
	double xo, yo, io=xo/delta, jo=yo/delta;
	double imax = 1/delta, jmax = 1/delta, sum = 0.0;
	int m1=0, m2=0, m3=0, m4=0, x_kor=0, y_kor=0, sayac=0;
	double r;
	double k,i,j,m;
	boolean akis=false;
	long ns;
	

	int yukseklik, genislik;
	String renk;
	Thread XY_hareket;
	Image winBellek;
	Graphics gBellek;
	
	public Grafik (String renk){
		i=io;
		j=jo;
		this.renk = renk;
		setBackground(Color.decode("#"+renk));
		
	}
	public void guncelle(int sayac, boolean akis, Thread XY_hareket, double x, double y){
		this.sayac = sayac;
		this.XY_hareket = XY_hareket;
		this.akis = akis;
		xo=x;
		yo=y;
		io=xo/delta;
		jo=yo/delta;
		m1=m2=m3=m4=0;
		v=sum=0;
		ns=0;
	
		if(akis){
			XY_hareket = new Thread(this);
			XY_hareket.start();
			repaint();
		}
		else{
	//		XY_hareket.stop();
			x_kor = (int)(io*4*delta/0.01)+250;
			y_kor = (int)(400-jo*4*delta/0.01)+10;
			repaint();
		}
	}

	public void run() {
		for (k=1;k<=sayac;k++){
			i=io;
			j=jo;	
			while(akis){
				r=Math.random();
				ns++;
				if(r>=0 && r<p1)
					i++;
				else if(r>=p1 && r<p2)
					j++;
				else if(r>=p2 && r<p3)
					i--;
				else if(r>=p3)
					j--;
				if(i==0){			// -x sol sınır
					sum+=v4;
					m4++;
					akis=false;
				}
				else if(i>imax){ 	// +x sağ sınır
					sum+=v2;
					m2++;
					akis=false;	
				}
				else if(j==0){		// -y alt sınır
					sum+=v1;
					m1++;
					akis=false;
				}
				else if(j>jmax){	// +y üst sınır
					sum+=v3;
					m3++;
					akis=false;
				}
				x_kor = (int)(i*4*delta/0.01)+250;
				y_kor = (int)(400-j*4*delta/0.01)+10;
				v=(double)sum/this.sayac;
				repaint();
				try{
					Thread.sleep(1, 1);
					}
				catch(InterruptedException e){
				}
			}
			akis=true;
		}
		v=(double)sum/this.sayac;
		
		repaint();
	}
	
	public void paint(Graphics g){
		setBackground(Color.decode("#"+renk));
		yukseklik = this.getSize().height;
		genislik = this.getSize().width;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		
		Font currentFont = g.getFont();
		Font newFont = currentFont.deriveFont(currentFont.getSize() * 1.2F);
		gBellek.setFont(newFont);
		gBellek.drawString("------------------------------",5,10);
		gBellek.drawString("------------------------------",5,20);
		gBellek.drawString("Nokta: "+Double.toString(xo)+", "+Double.toString(yo)+" Voltaj: "+v,5,35);
		gBellek.drawString("--------------------------------------",5,50);
		gBellek.drawString("X Y bileşenlerine göre yürüyüş dağılımı ",5,65);
		gBellek.drawString("------------------------------",5,80);
		gBellek.drawString("1'nci Sınır  "+"  : "+m1,5,90);
		gBellek.drawString("2'nci Sınır  "+"  : "+m2,5,105);
		gBellek.drawString("3'üncü Sınır "+": "+m3,5,120);
		gBellek.drawString("4'üncü Sınır "+": "+m4,5,135);
		gBellek.drawString("Adım Sayısı= "+ns,5,150);
	
		gBellek.setColor(Color.decode("#d7d7d8"));
		for(int i=1;i<=41;i++){
			gBellek.drawLine(250, 10+(10*i), 660, 10+(10*i));
			gBellek.drawLine(250+(10*i), 10, 250+(10*i), 420);
		}
		gBellek.drawLine(250, 10, 660, 10);
		gBellek.setColor(Color.decode("#000000"));
		gBellek.drawLine(250, 0, 250, 440);
		gBellek.drawLine(230,420,670,420);
		gBellek.fill3DRect(x_kor, y_kor, 10, 10,true);
		gBellek.drawString("0.0", 230, 435);
		gBellek.drawString("1.0", 630, 435);
		gBellek.drawString("1.0", 230, 25);
		
		g.drawImage(winBellek,0,0,this);
	}
	
	public void update(Graphics g){
		paint(g);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(550,500);
	}
}
