import java.util.*;

class Liiguta /*extends Louend*/{
	boolean[][]						tabelis = new boolean[20][10];
	boolean[][]						liikuv_kujund=new boolean[4][4];
	boolean[][]						jargmine=new boolean[4][4];
	Kujundid						objektid=new Kujundid();
	Salvestamine					seivi;
	int 							x=4;
	int 							y=19;
	int								skoor=0;		
	int								boonus=0;
	int 							boonuse_loendur=0;	
	Random 							arv;
	int 							nr;	
	int 							asend=0;
	boolean							manglabi=false;
	String 							nimi="mängija";
	int 							praegune=7;
			
// kujundi laius ja kõrgus	
	
	public Liiguta(boolean [][] x){
		tabelis=x;
		jargmine=objektid.nr8(asend);
		liikuv_kujund=tee_uus_kujund();
		seivi=new Salvestamine();		
	}
	protected synchronized boolean[][] alla (int kujundiX,int kujundiY,boolean[][] kujund){
		int kujundi_korgus=korgus(kujund);	
		int kujundi_laius=laius(kujund);			
			boolean OK=true;
			
			/***********************************************/
			if((kujundiY-(kujundi_korgus+1))<0){
				OK=false;							
			}else{										
				int suurim=0;				
				for(int k=0;k<kujundi_korgus;k++){					
					for(int j=0;j<kujundi_laius;j++){						
						if(kujund[k][j]==true){							
							suurim=0;							
							for(int i=0;i<veeru_korgus(kujund,j);i++){
								// saab igast tulbast kõrguse								
								if((i==3)||(kujund[i+1][j]==false)){suurim=i;}																
							}
								// kui mõni tulp jätkata ei saa, katkestatakse liikumine kogu tulbale
								if(tabelis[kujundiY-(suurim+2)][kujundiX+j]==true){
									OK=false;
									//System.out.println("Tekkis kollisioon");									
								}								
						}
					}
				}											
			}
			/*************************************************/
			if(OK){
				// liiguta kujund alla (kustuta vana asukoht|kirjuta uus)			
				kustuta_kujundi_asukoht(kujundiX,kujundiY,kujund);
				for(int i=0;i<kujundi_korgus;i++){
					int Y=kujundiY-(i+2);
					for(int j=0;j<kujundi_laius;j++){
						if(kujund[i][j]==true){							
							tabelis[Y][kujundiX+j]=true;
						}
					}
				}
				y=kujundiY-1;
			}else{
				//System.out.println("lõpus");
				if(kujundiY>=17){
					try{
						seivi.seiv(nimi,skoor);
						seivi.info();	
					}catch(Exception e){}
					manglabi=true;				
				}else{
					ridade_kontroll(kujundiY-(kujundi_korgus));
					//ridade_kontroll(kujundiY-4);
					// uus kujund
					liikuv_kujund=tee_uus_kujund();
					//System.out.println("Uus kujund");
				}
			}						
			return tabelis;
		
	}
	/*
	 * Liigutab etteantud kujutise 1 ruudu võrra vasakule
	 */
	
	protected boolean[][] vasakule(int kujundiX,int kujundiY,boolean[][] kujund){
		// kontrolli, kas kujund on vasakust piirdest väljas ja kas vasakul pole juba kujundit
		
		int kujundi_korgus=korgus(kujund);	
		int kujundi_laius=laius(kujund);
		boolean OK=true;
		if((kujundiX-1)<0){
			OK=false;			
		}else{
			
			for(int k=0;k<kujundi_korgus;k++){
					for(int j=0;j<kujundi_laius;j++){						
						if(kujund[k][j]==true){							
						
							// kontroll ainult kõige vasakpoolsema ruudu puhul
							if(vasakpoolseim(k,j)){
								if(tabelis[kujundiY-(k+1)][kujundiX-(1)+j]==true){
									OK=false;
								}
							}
						}
					}
				}
		}
		//kustuta vana asukoht / kirjuta uus
		if(OK){			
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(kujund[i][j]==true){
						tabelis[kujundiY-(i+1)][kujundiX+j]=false;
					}
				}
			}
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(kujund[i][j]==true){
						tabelis[kujundiY-(i+1)][kujundiX+(j-1)]=true;
					}
				}
			}
			x=kujundiX-1;
		}else{
			//System.out.println("seis_vasemal");
		}
		return tabelis;
	}
	
	boolean vasakpoolseim(int rida,int veerg){
		int x=0;
		int y=0;
		for(int i=veerg;i>=0;i--){			
			if(liikuv_kujund[rida][i]==true){
				y=i;
			}
		}
		
		if(y==veerg){
			return true;			
		}else{
			return false;
		}
		
	}
	boolean parempoolseim(int rida,int veerg){
		int x=0;
		int y=0;
		for(int i=0;i<4;i++){			
			if(liikuv_kujund[rida][i]==true){
				y=i;
			}
		}
		
		if(y==veerg){
			return true;			
		}else{
			return false;
		}
		
	}
	
	/*
	 * Liigutab ette antud ruudu 1 võrra paremale
	 */
	protected boolean[][] paremale(int kujundiX,int kujundiY,boolean[][] kujund){	
		int kujundi_korgus=korgus(kujund);					
		int kujundi_laius=laius(kujund);
		boolean OK=true;
		if((kujundiX+(kujundi_laius))>9){
			OK=false;
		}else{
			
			
			
			for(int k=0;k<kujundi_korgus;k++){
				for(int j=0;j<kujundi_laius;j++){						
					if(kujund[k][j]==true){							
					
						// kontroll ainult kõige vasakpoolsema ruudu puhul
						if(parempoolseim(k,j)){
							if(tabelis[kujundiY-(k+1)][kujundiX+1+j]==true){
								OK=false;
							}
						}
					}
				}
			}
			
			
			
		}
		if(OK){
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(kujund[i][j]==true){						
						tabelis[kujundiY-(i+1)][kujundiX+j]=false;
					}
				}
			}
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(kujund[i][j]==true){
						tabelis[kujundiY-(i+1)][kujundiX+(j+1)]=true;
					}
				}
			}
			x=kujundiX+1;
		}else{
			//System.out.println("seis_paremal");
		}
		return tabelis;
	}
	/*
	 * Pöörab liikuvat kujundit päripäeva
	 */
	protected synchronized boolean[][] poora(int kujundiX,int kujundiY,boolean[][] kujund){		
	int l=laius(kujund);
	int k=korgus(kujund);
		if((kujundiX+laius(kujund))>9){			
						
			
			
			kustuta_kujundi_asukoht(kujundiX,kujundiY,kujund);
			kujundiX=9-(laius(kujund));
			
			
		}
			kustuta_kujundi_asukoht(kujundiX,kujundiY,kujund);
			
			asend++;
			if(asend==4)asend=0;		
			//System.out.println("Pööramise asend:"+asend);
			switch(praegune){
				case 1: kujund=objektid.nr1(asend);break;
				case 2: kujund=objektid.nr2(asend);break;
				case 3: kujund=objektid.nr3(asend);break;
				case 4: kujund=objektid.nr4(asend);break;
				case 5: kujund=objektid.nr5(asend);break;
				case 6: kujund=objektid.nr6(asend);break;
				case 7: kujund=objektid.nr7(asend);break;
				case 8: kujund=objektid.nr8(asend);break;
				case 0: kujund=objektid.nr9(asend);break;
			}
			
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(kujund[i][j]==true){
						tabelis[kujundiY-(i+1)][kujundiX+j]=true;
						//System.out.println("tabelis["+(kujundiY-(i+1))+"]["+(kujundiX+j)+"]=true;");
					}
				}
			}
			//System.out.println("#");
			liikuv_kujund=kujund;
			//System.out.println("##");
		return kujund;
	}
	/*
	 * Kustutab kujundi asukoha
	 */
	protected synchronized void kustuta_kujundi_asukoht(int kujundiX,int kujundiY,boolean[][] kujund){
		int l=laius(kujund);
		int k=korgus(kujund);
		
		for(int i=0;i<k;i++){
			for(int j=0;j<l;j++){
				if(kujund[i][j]==true){
					tabelis[kujundiY-(i+1)][kujundiX+j]=false;
				}
			}
		}
	}
	/*
	 * Kustutatakse kogu etteantud rida ning nihutatakse ülejäänud kujundid ühe rea võrra alla
	 */
	protected void kustuta_rida(int rida){
				
		// nulli terve rida	
		for(int i=rida;i<(19-rida);i++){		
			for(int j=0;j<10;j++){
				//tabelis[(rida+i)][j]=false;
				tabelis[i][j]=false;
				// nihuta kõik ülejäänud alla				
				//tabelis[rida+i][j]=tabelis[(rida+i)+1][j];
				tabelis[i][j]=tabelis[i+1][j];
			}
		}
		//System.out.println("Rida kustutatud");
	}
	/*
	 * Vaadatakse alates etteantud reast läbi kõik read ülespoole
	 * Kus kogu rea kontrollsumma klapib, kutsutakse välja kustutamine.	 
	 */	
	protected void ridade_kontroll(int rida){	
			int kontrollsumma=0;									
			for(int i=0;i<10;i++){
				if(tabelis[rida][i]==true){
					kontrollsumma++;
				}
			}
			if(kontrollsumma==10){				
				skoor+=25;
				boonuse_loendur++;				
				kustuta_rida(rida);
				ridade_kontroll(rida);
			}else if(kontrollsumma<1){
				int koefitsent=boonuse_loendur;
				if(boonuse_loendur==1){
					koefitsent=0;
				}
				
				boonus=boonus+(5*boonuse_loendur*koefitsent);
				kontrollsumma=0;
				boonuse_loendur=0;
				//System.out.println("rekursiooni lõpp");
			}else{
				ridade_kontroll(rida+1);
			}
	}
	/*
	 * Leiab käesoleva kujundi kõrguse
	 */
	private int korgus(boolean[][] kujund){
		int x=0;
		int y=0;
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(kujund[i][j]==true)y=i;
				if(x<y)x=y;
			}
		}
		return x+1;
	}
	/*
	 * Leiab käesoleva kujundi laiuse
	 */
	private int laius(boolean[][] kujund){
		int x=0;
		int y=0;
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(kujund[i][j]==true)y=j;
					if(x<y)x=y;
			}
		}
		return x+1;
	}
	/*
	 * Genereeritakse uus kujund
	 */
	boolean[][] tee_uus_kujund(){
		asend=0;
		x=4;y=19;
		liikuv_kujund=jargmine;		
		praegune=nr;
		// Tehakse juhuslik kujund
		// juhuarv		
		arv=new Random();
		nr=Math.abs((arv.nextInt()%9));  			
		//System.out.println("juhuslik uus kujund (nr:"+nr+")");						
		
		switch(nr){
	       case  0: jargmine=objektid.nr9(asend);break;
	       case  1: jargmine=objektid.nr1(asend);break;
	       case  2: jargmine=objektid.nr2(asend);break;
	       case  3: jargmine=objektid.nr3(asend);break;
	       case  4: jargmine=objektid.nr4(asend);break;
	       case  5: jargmine=objektid.nr5(asend);break;
	       case  6: jargmine=objektid.nr6(asend);break;
	       case  7: jargmine=objektid.nr7(asend);break;
	       case  8: jargmine=objektid.nr8(asend);break;
    	}    	    			    	    	
		return liikuv_kujund;		
	}
	
	private int veeru_korgus(boolean[][] kujund,int veerg){
		int x=0;
		int y=0;
		for(int i=0;i<4;i++){			
			if(kujund[i][veerg]==true)y=i;
				if(x<y)x=y;
		}
		return x+1;
	}
	private int rea_laius(boolean[][] kujund,int rida){
		int x=0;
		int y=0;
		for(int i=0;i<4;i++){			
			if(kujund[rida][i]==true)y=i;
				if(x<y)x=y;
		}
		return x+1;		
	}
}