/**
 * TBD Genc Ankara Mayis 2010 Bulteni 
 * Odullu Programlama Sorusu-3
 * Java(TM) $ablonu
 * www.tbdgenc.com
 */

/*
 * Uyari: Lutfen main ve yerlestir metodunun aciklamasini okuyunuz.
 */
public class Soru3Test {
	private class Dikdortgen{
		/* 	Bu obje bu dosya icinde gorulebilir. Ek
			property'ler tanimlamak serbesttir.
		*/
		public int x,y,genislik, yukseklik; // disaridan erisilebilir
		
		public Dikdortgen(int genislik, int yukseklik){
			this(0,0,genislik,yukseklik);
		}
		
		public Dikdortgen(int x, int y, int genislik, int yukseklik){
			if(x<0 || y<0) System.out.println("## UYARI: x veya y 0'dan kucuk olamaz!");
			if(genislik<0 || yukseklik<0) 
				System.out.println("## UYARI: genislik veya yukseklik 0'dan kucuk olamaz!");
			
			this.x = x;
			this.y = y;
			this.genislik = genislik;
			this.yukseklik = yukseklik;
		}
		
		/**
		 * mevcut dikdortgenle digerinin kesisip kesismedigini tespit
		 * eder
		 * @param diger
		 * @return kesi$iyorlarsa true döner
		 * @author Sami Shaio (from java.awt.Rectangle), Ahmet Alp Balkan
		 * 	(modified) 
		 */
		public boolean kesisiyorMu(Dikdortgen d){
			if (this==d){
				return false; //dikdortgeni kendisiyle karsilastirmasini onleyelim
			} else {
				int tw, th, dw, dh;
				tw = this.genislik;
				th = this.yukseklik;
				dw = d.genislik;
				dh = d.yukseklik;
				
				if (dw <= 0 || dh <= 0 || tw <= 0 || th <= 0) {
				    return false;
				}
				
				int tx, ty, dx, dy;
				tx = this.x;
				ty = this.y;
				dx = d.x;
				dy = d.y;
				
				tw += tx;
				th += ty;
				dw += dx;
				dh += dy;
				
				return ((dw < dx || dw > tx) &&
						(dh < dy || dh > ty) &&
						(tw < tx || tw > dx) &&
						(th < ty || th > dy));
			}
		}
		
		
		@Override
		public String toString() {
			return "[X="+x+", Y="+y+", W="+genislik+", Y="+yukseklik+"]";
		}
		
		/**
		 * verilen bir noktanin dikdortgenin icinde veya ustunde
		 * kalip kalmadigini dondurur.
		 * @param X
		 * @param Y
		 * @return icindeyse true doner, degilse false
		 * @author Sami Shaio
		 */
		public boolean icindeMi(int X, int Y){
			int w = this.genislik;
			int h = this.yukseklik;
			
			if(w < 0 || h < 0) return false; // sifirdan kucuk boyut.
			
			if (X < x || Y < y) {
			    return false;
			}
			w += x;
			h += y;
			return ((w < x || w > X) && (h < y || h > Y));
		}
		
		/**
		 * Verilen dikdortgenin baslangic (sol alt, guneybati) 
		 * noktasini verilen koordinata tasir.
		 */
		public void tasi(int X, int Y){
			if(X<0 || Y<0) System.out.println("## UYARI: x veya y 0'dan kucuk olamaz! (tasirken)");
			x = X;
			y = Y;
		}
		
	} // dikdortgen
	

	/**
	 * Verilen Dikdortgen listesinde o noktanin bir dikdortgenin icinde
	 * kalip kalmadigini dondurur.
	 * 
	 * @return bir dikdortgenin icinde kaliyorsa true doner,
	 * 		   o nokta bossa false doner.
	 */
	public static boolean buradaDikdortgenVarMi(Dikdortgen[] liste, int X, int Y){
		for(int i = 0; i < liste.length; i++){
			if(liste[i].icindeMi(X, Y)) {
				System.out.println("(X="+X+", Y="+Y+")'deki: "+liste[i]);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Verilen Dikdortgen listesinde birbirleriyle kesisen dikdortgen
	 * olup olmadigini dondurur.
	 * @param liste
	 * @return kesisen varsa true, yoksa (istenilen durum) false doner
	 */
	public static boolean kesisenDikdortgenVarMi(Dikdortgen[] liste){
		for(int i = 0; i < liste.length; i++){
			for(int j = 0; j < liste.length; j++){
				if(liste[i].kesisiyorMu(liste[j])){
					System.out.println("Kesi$en: "+liste[i]+" ve "+liste[j]);
					return true;
				}
			}
		}
		return false;
	}
	
	public static int maximumX(Dikdortgen[] liste){
		int max = 0; int tmp;
		
		for(int i = 0 ; i < liste.length; i++){
			tmp = liste[i].x + liste[i].genislik;
			if (tmp>max) max = tmp;
		}
		
		return max;
	}
	
	public static int maximumY(Dikdortgen[] liste){
		int max = 0; int tmp;
		
		for(int i = 0 ; i < liste.length; i++){
			tmp = liste[i].y + liste[i].yukseklik;
			if (tmp>max) max = tmp;
		}
		
		return max;
	}
	
	
	public static void dikdortgenleriYazdir(Dikdortgen[] liste){
		for(Dikdortgen d: liste)
			System.out.println(d);
	}
	
	

	/**
	 * Verilen Dikdortgen array'indeki dikdortgenleri
	 * en verimli sekilde yerlestirir ve yeni array'i
	 * dondurur.
	 * """"BU KISIM KODLANACAKTIR""". EK METODLAR TANIMLANABiLiR.
	 * SONRADAN TANIMLI METODLAR DA BURADAN CAGIRILABILIR. 
	 * 
	 * NOT: main tarafindan cagirilacak olan metod budur.
	 * NOT: Dikdortgen.tasi metodu kullanilabilir.
	 * 
	 */
	public static Dikdortgen[] yerlestir(Dikdortgen[] liste){
		/*
		 * Yarismaci tarafindan kodlanacak.
		 */
		
		return liste;
	}
	
	/**
	 * Lutfen algoritmanizi yerlestir metodu icine yaziniz.
	 * Bu metodu sadece algoritmanizi farkli dikdortgenlerle
	 * test etmek icin kullaniniz.
	 */
	public static void main(String[] args) {
		Soru3Test test = new Soru3Test();
		
		Dikdortgen[] liste = new Dikdortgen[3];	// x=0, y=0'da bazi dikdortgenler 
		liste[0] = test.new Dikdortgen(5, 5);	// uretelim. Test esnasinda 
		liste[1] = test.new Dikdortgen(20, 10);	// bu satirlari degistiriyor
		liste[2] = test.new Dikdortgen(10, 20); 	// olacagiz.
		
		System.out.println("Baslangictaki Dikdortgenler:");
		dikdortgenleriYazdir(liste);
		
		System.out.println("\n"); // bosluk
		System.out.println("Kesi$en Dikdortgen?: "+ (kesisenDikdortgenVarMi(liste)?"var":"yok"));
		
		/** BURADA METOD CAGIRILIYOR **/
		liste = yerlestir(liste);
		/** BURADA METOD CAGIRILIYOR **/
		
		System.out.println("\nBitisteki Dikdortgenler:");
		dikdortgenleriYazdir(liste);
		
		System.out.println("\n"); // bosluk
		System.out.println("Ta$ima Sonrasi Kesi$en Dikdortgen?: "+ (kesisenDikdortgenVarMi(liste)?"var (yerlestir'DEN SONRA OLMAMASI GEREK!!!)":"yok (TAMAMDIR)"));
		
		System.out.println("\n"); // bosluk
		int maxX = maximumX(liste);
		int maxY = maximumY(liste);
		System.out.println("Maximum X koordinati: "+maxX+"\nMaximum Y koordinati: "+maxY);
		System.out.println("*** Maliyet = "+ (maxX+maxY) +" TL. ***");
	}
}
