import java.util.*;

public class ConBoard {
	public String baslangicDurumu = "";
	public final double e = 2.718281828;
	public final double pi = 3.141592654;
	public double p1, p2;
	public boolean kontrolGirdi = false;
	public int satirLen=99, sutunLen=99, hucreSayisi, adimSayisi = 0,
			   countT = 0, countT1 = 0, countT2 = 0, countAlive = 0,
			   hucreTipi = 0;
	public int[][] kullaniciBaslangicVeri; // başlangıç durumundaki verileri tut [2,4,1]
	public T[][] HUCRE = new T[satirLen][sutunLen]; // hücreleri tut
	public T[][] tmp = new T[satirLen][sutunLen]; // yedek array
	
	Grid grid;
	
	public void getUserInput() {
		while(kontrolGirdi == false) {
			try {
				Scanner input = new Scanner(System.in);
				Scanner input2 = new Scanner(System.in);
				System.out.print("Grid boyutlarını girin: ");
				satirLen = input.nextInt();
				sutunLen = input.nextInt();
				if(satirLen<0||sutunLen<0) {
					throw new Exception("Negatif uzunluk olmaz olsun..");
				}
				
				System.out.print("p1 ve p2: ");
				p1 = input.nextDouble();
				p2 = input.nextDouble();
				if(p1>1||p1<0||p2>1||p2<0) {
					throw new Exception("p1 ve p2 değerleri 0 ve 1 aralığında olsun plz.");
				}
				
				System.out.print("Adım sayısı: ");
				adimSayisi = input.nextInt();
				if(adimSayisi<0) {
					throw new Exception("Adım sayısı negatif. Geri Geri mi gitsin program? hayret bişey.");
				}
				
				System.out.print("Baslangic durumu: ");
				baslangicDurumu = input2.nextLine();	
				
				kontrolGirdi = true;
			} catch(Exception e) {
				System.out.println("Uygun veri girmediniz;");
				System.out.println("\tHata: "+e);
			}
			
		}
		
	}
	
	public void divideBaslangicDurumu(String baslangic) {
		// başlangıç durumundan kordinatları ve türü çekmek için parçalama metodu!
		
		String[] hucreler = baslangic.split(", ");
		// başlangıç durumu "(2,4) t" , "(2,3) t2" gibi değerlere bölündü! 
		
		hucreSayisi = hucreler.length; 
		kullaniciBaslangicVeri = new int[hucreSayisi][3];
		
		for(int i = 0; i<hucreler.length; i++) {
			String[] hucrelerFoo = hucreler[i].split(" ");
			// hucrelerFoo arrayi, "(4,4) t" gibi bir değeri " " e bölerek
			// {"(4,4)" , "t"} gibi stringler tutuyor. 
			
			String[] Turler = new String[hucreler.length];
			String[] KordinatFoo = new String[hucreler.length];
			
			for(int k=0; k<2; k++) {
				if(k==0) {
					KordinatFoo[i] = hucrelerFoo[k];
					String[] kordinatlar = KordinatFoo[i].split(",");
					int len1 = kordinatlar[0].length();
					int len2 = kordinatlar[1].length();
					kullaniciBaslangicVeri[i][0] = Integer.parseInt(kordinatlar[0].substring(1,len1));
					kullaniciBaslangicVeri[i][1] = Integer.parseInt(kordinatlar[1].substring(0,len2-1));
				}
				
				if(k==1) {
					Turler[i] = hucrelerFoo[k];
					if(Turler[i].equals("t")) {
						kullaniciBaslangicVeri[i][2] = 1;
					} else if(Turler[i].equals("t1")) {
						kullaniciBaslangicVeri[i][2] = 2;
					} else if(Turler[i].equals("t2")) {
						kullaniciBaslangicVeri[i][2] = 3;
					}	
				}								
				
			} // nested for bitti--------------
			
//			System.out.println("Tür: "+Turler[i]+" | id: "+kullaniciBaslangicVeri[i][2]);
//			System.out.println("Kordinatlar: "+kullaniciBaslangicVeri[i][0]+"-"+kullaniciBaslangicVeri[i][1]);
		} // dış for bitti--------------				
		
	}//divide işlemi bitti
	
	public void hucreOlustur(int[] hcr) {	//başlangıç durumunu set ediyor //Done
		if(hcr[2] == 1) {
			HUCRE[hcr[0]][hcr[1]] = new T(hcr[0],hcr[1], true, "T"); 
			tmp[hcr[0]][hcr[1]] = new T(hcr[0],hcr[1], true, "T"); 
		}
		else if(hcr[2] == 2) {
			HUCRE[hcr[0]][hcr[1]] = new T1(hcr[0],hcr[1], true, "T1");
			tmp[hcr[0]][hcr[1]] = new T1(hcr[0],hcr[1], true, "T1");
		}
			
		else{
			HUCRE[hcr[0]][hcr[1]] = new T2(hcr[0],hcr[1], true, "T2");
			tmp[hcr[0]][hcr[1]] = new T2(hcr[0],hcr[1], true, "T2");
		}
			
	}
	
	
	public void checkTypeCount(T type) {
		if(type.tur.equalsIgnoreCase("T")) {
			countT++;
		} 
		
		if(type.tur.equalsIgnoreCase("T1")) {
			countT1++;
		}
		
		if(type.tur.equalsIgnoreCase("T2")) {
			countT2++;
		}
	}
	
	public void step(T[][] t) {		
	
		for(int k = 0; k<satirLen; k++) { //array'e hücreleri atıyor
			for(int l = 0; l<sutunLen; l++) {
				if (t[k][l]==null) {
					t[k][l] = new T(k,l,false, "t");
				}
				
				if(tmp[k][l]==null) {
					tmp[k][l] = new T(k,l,false, "t");
				}
			}
		}
			
		for(int i = 0; i<satirLen; i++) {		
			for(int j = 0; j<sutunLen; j++) {
				
				countT = 0;
				countT1 = 0;
				countT2 = 0;
				countAlive = 0;
							
				try {
					if (t[i-1][j+1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i-1][j+1]);
					}
				} catch(Exception e) { }
				
				try {				
					if (t[i-1][j-1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i-1][j-1]);
					}						
				} catch(Exception e) { }
				
				try {
					if (t[i-1][j].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i-1][j]);
					}
				} catch(Exception e) { }
				//---------------------------	
				try {
					if (t[i][j+1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i][j+1]);
					}
				} catch(Exception e) { }
				
				try {
					if (t[i][j-1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i][j-1]);
					}
				} catch(Exception e) { }
				//---------------------------	
				try {
					if (t[i+1][j+1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i+1][j+1]);
					}
				} catch(Exception e) { }
				
				try {
					if (t[i+1][j-1].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i+1][j-1]);
					}
				} catch(Exception e) { }
					
				try {
					if (t[i+1][j].isAlive == true) {
						countAlive++;
						checkTypeCount(t[i+1][j]);
					}
				} catch(Exception e) { }
				
				if(t[i][j].isAlive == false) { //ölü ise	

					if(countAlive == 3) { 
						
						if(countT == 3) {
//							System.out.println("-------");					
//							System.out.println(i+", "+j+" ölü");
//							System.out.println(i+"-"+j+" 3 adet T komşusu var");
//							System.out.println(i+"-"+j+" bu hücre canlanır");
							tmp[i][j].isAlive = true;
							double piCheck = Math.random();
							if(piCheck<1/pi) {
								double p1Check = Math.random();
								if(p1Check<p1) {
									tmp[i][j].tur = "t1";
									makeAliveCell(i,j,2);
								} else {
									tmp[i][j].tur = "t";
									makeAliveCell(i,j,1);
								}
							} else {
								tmp[i][j].tur = "t";
								makeAliveCell(i,j,1);
							}
							
							
							
						}else if(countT1 == 3) {
//							System.out.println("-------");					
//							System.out.println(i+", "+j+" ölü");
//							System.out.println(i+"-"+j+" 3 adet T1 komşusu var");
//							System.out.println(i+"-"+j+" bu hücre canlanır");
							tmp[i][j].isAlive = true;
							double piCheck = Math.random();
							if(piCheck<1/pi) {
								double p2Check = Math.random();
								if(p2Check<p2) {
									tmp[i][j].tur = "t2";
									makeAliveCell(i,j,3);
								} else {
									tmp[i][j].tur = "t1";
									makeAliveCell(i,j,2);
								}
							}else {
								tmp[i][j].tur = "t1";
								makeAliveCell(i,j,2);
							}
							
							
							
						}else if(countT2 == 3) {
//							System.out.println("-------");					
//							System.out.println(i+", "+j+" ölü");
//							System.out.println(i+"-"+j+" 3 adet T2 komşusu var");	
//							System.out.println(i+"-"+j+" bu hücre canlanır");
							tmp[i][j].isAlive = true;
							tmp[i][j].tur = "t2";
												
							makeAliveCell(i,j,3);
						}						
						
					}
					
//					System.out.println("-------");					
//					System.out.println(i+", "+j+" ölü");		
								
				} else { //canlı ise
					
					if(t[i][j].tur.equalsIgnoreCase("t1")) { //T1'in yaşını kontrol ediyor
						tmp[i][j].ageOfT1++;
//						System.out.println("YAŞ: "+ t[i][j].ageOfT1);
						double d = Math.random();
						
						if(d<1/Math.exp(5-t[i][j].ageOfT1)){
							tmp[i][j].isAlive = false;
							makeDeadCell(i,j);
						}	
					}					

					if(countAlive > 3 || countAlive < 2) {
//						System.out.println("-------");
//						System.out.println(i+", "+j+" canlı");	
//						System.out.println(countAlive +" adet canlı komşusu var");
//						System.out.println(i+"-"+j+" bu hücre ölür");
						tmp[i][j].isAlive = false;
						tmp[i][j].ageOfT1 = 0;		
						makeDeadCell(i,j);
//						hücre öldür
					} 
					
					if(t[i][j].tur.equalsIgnoreCase("t2")&&(countT<1)) {
						tmp[i][j].isAlive = false;
						makeDeadCell(i,j);
					}
						
//					System.out.println("-------");
//					System.out.println(i+", "+j+" canlı");	
				}
				
			}
		}
		
		for(int i = 0; i<satirLen; i++) { //asıl arrayi güncelliyor
			for(int j = 0; j<sutunLen; j++) {
				t[i][j].isAlive = tmp[i][j].isAlive;
				t[i][j].tur = tmp[i][j].tur;
				t[i][j].ageOfT1 = tmp[i][j].ageOfT1;
			}
		}
		
		
	}

	
	public void createGuiGrid(int i, int k) {
		grid = new Grid(i,k);
	}
	
	public void setFirstGuiGrid(int[] veriler) {
		try{
			grid.alive(veriler[0]-1, veriler[1]-1, veriler[2]);
		} catch(Exception e) { }
	}
	
	public void makeDeadCell(int x, int y) {
		try{
			grid.dead(x-1, y-1);
		} catch(Exception e) { }
	}
	
	public void makeAliveCell(int x, int y, int z) {
		try{
			grid.alive(x-1, y-1, z);
		} catch(Exception e) { }
	}

}
