public class Dzbany {

	/** Promenne nesene v kazde instanci tridy A
	* a= mnozstvi vody ve dzbanu A
	* b= mnozstvi vody ve dzbanu B
	* aMax= velikost dzbanu A
	* bMax= velikost dzbanu B
	* c= mnozstvi vody ktere chceme odmerit do dzbanu A
	* operace kterou jsme provedli abychom se dostali do tohoto stavu A,B
	*/
	final int a,b, aMax, bMax, c, operace;
	
	// Pojmenovani operaci ktere je se dzbany mozno provest
	static final String[] nazvyOperaci= new String[]{
		"",
		"naplnA",
		"naplnB",
		"vylejA",
		"vylejB",
		"zAdoB ",
		"zBdoA "		
	};
	
	// Konstrultor tridy dzbany
	public Dzbany(int a,int b,int aMax, int bMax, int c,int operace) {	
		this.a=a;
		this.b=b;
		this.aMax=aMax;
		this.bMax=bMax;
		this.c=c;
		this.operace=operace;
	}	
	
	// Napln dzban A
	Dzbany naplnA(){
		// nedelej nesmyslnou operaci
		if (a==aMax) return null;
		return new Dzbany(aMax,b,aMax,bMax,c,1);
	}
	
	// Napln dzban B
	Dzbany naplnB(){
		// nedelej nesmyslnou operaci
		if (b==bMax) return null;
		return new Dzbany(a,bMax,aMax,bMax,c,2);
	}
	
	// Vylej dzban A
	Dzbany vylejA(){
		// nedelej nesmyslnou operaci
		if (b==0) return null;
		return new Dzbany(0,b,aMax,bMax,c,3);
	}

	// Vylej dzban B
	Dzbany vylejB(){
		// nedelej nesmyslnou operaci
		if (a==0) return null;
		return new Dzbany(a,0,aMax,bMax,c,4);
	}
	
	// Prelej dzban A do dzbanu B
	Dzbany prelejAdoB(){
		// nedelej nesmyslnou operaci
		if (a==0) return null;
		if ((a+b) > bMax) {
			return new Dzbany(a-(bMax-b),bMax,aMax,bMax,c,5);
		}
		else {
			return new Dzbany(0,a+b,aMax,bMax,c,5);
		}
	}
	
	// Prelej dzban B do dzbanu A
	Dzbany prelejBdoA(){
		// nedelej nesmyslnou operaci
		if (b==0) return null;
		if ((a+b) > aMax) {
			return new Dzbany(aMax,b-(aMax-a),aMax,bMax,c,6);
		}
		else {
			return new Dzbany(a+b,0,aMax,bMax,c,6);
		}
	}

	// V pripade ze ve dzbanu A je C vody, mame vyherni stav
	boolean vyhra(){
		return (a==c);
	}
	
	// Vypise provedenou operaci a stav dzbanu jako string
	public String toString() {
		// TODO Auto-generated method stub
		return nazvyOperaci[operace]+ "-> ("+a+","+b+")";
	}

	// Porovna zda jsou situace ve dzbanech stejne (smycka v ceste, spatne)
	public boolean equals(Object arg0) {
		if (!(arg0 instanceof Dzbany)) return false;
		Dzbany druhy=(Dzbany)arg0;
		return ((druhy.a==a)&&(druhy.b==b));
	}
	
	// Vola postupne operace ciselne (kvuli prochazeni v cyklu
	Dzbany operace(int i){
		switch (i) {
		case 1:		return naplnA();
		case 2:		return naplnB();
		case 3:		return vylejA();
		case 4:		return vylejB();
		case 5:		return prelejAdoB();
		case 6:		return prelejBdoA();
		default: return null;
		}
	}
}
