import java.lang.*;
import java.io.*;
import java.util.*; 

import java.awt.*;
import java.awt.event.*;

class Demo extends Frame{

    private static final String VersionsDatum = "29. September 2004";
    
    private int xMax = 1000;
    private int yMax = 710;
    
    private static final Font FontMono  = new Font("Monospaced", Font.PLAIN, 18);
    private static final Font FontSansSerif = new Font("SansSerif", Font.PLAIN, 14);
    private static final Font BigItalicSansSerif = new Font("SansSerif", Font.ITALIC, 16);
       
    private static MenuBar MainMenuBar = new MenuBar();
    private static Menu DateiMenu = new Menu("Datei");
    private static MenuItem Beenden = new MenuItem("Beenden");
        
    private static Menu GrafikDemoMenu = new Menu("GrafikDemos");
    private static MenuItem Rect1 = new MenuItem("Rechtecke in Zufallsfarben");
    private static MenuItem Oval1 = new MenuItem("Ellipsen in Zufallsfarben");
    private static MenuItem RecOva = new MenuItem("Rechtecke + Ellipsen");
    private static MenuItem Circ1 = new MenuItem("Bunte Kreise");
    private static MenuItem Phyta = new MenuItem("Phytagoras Baum");
    
    private static Menu HilfeMenu = new Menu("Hilfe");
    private static MenuItem Hilfe = new MenuItem("Es gibt keine Hilfe...");
    private static MenuItem AboutBox = new MenuItem("About");
        
  
    private static String Titel = "Grafik2d Kapitel 4";
        
    //// Constructor.
     
    public Demo () {
	super(Titel);
	
	setFont(FontMono);
	DateiMenu.setFont(FontSansSerif);
	Beenden.setFont(FontSansSerif);
	
	GrafikDemoMenu.setFont(FontSansSerif);
	Rect1.setFont(FontSansSerif);
	Oval1.setFont(FontSansSerif);
	RecOva.setFont(FontSansSerif);
	Circ1.setFont(FontSansSerif);
	Phyta.setFont(FontSansSerif);
		
	HilfeMenu.setFont(FontSansSerif);
	Hilfe.setFont(FontSansSerif);
	AboutBox.setFont(FontSansSerif);
	setLayout(null);

	
	//// Menüs
	setMenuBar(MainMenuBar);
	
	MainMenuBar.add(DateiMenu);
	DateiMenu.addSeparator();
	DateiMenu.add(Beenden);
	
	MainMenuBar.add(GrafikDemoMenu);
	GrafikDemoMenu.add(Rect1);
	GrafikDemoMenu.add(Oval1);
	GrafikDemoMenu.add(RecOva);
	GrafikDemoMenu.add(Circ1);
	GrafikDemoMenu.add(Phyta);
	
	MainMenuBar.add(HilfeMenu);
	HilfeMenu.add(Hilfe);
	HilfeMenu.addSeparator();
	HilfeMenu.add(AboutBox);
	
	//// Allgemeine Initialisierung
	
	
	//// Menü Listener
	    
	Beenden.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ FensterBeenden(); }
	    });
	    
	Rect1.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        doRect1();
	        }
	    });
	    
	Oval1.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        doOval1();
	        }
	    });   
	    
	RecOva.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        doRecOva();
	        }
	    });  
	    
	Circ1.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        doCirc1();
	        }
	    });     
	    
	Phyta.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        doPhyta();
	        }
	    });    
	
	        	    	    
	AboutBox.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ showAboutBox(); }
	    });         
	
	//// Window Listener
	addWindowListener(new WindowAdapter() {    
        public void windowClosing(WindowEvent e) { FensterBeenden(); }
	    });
	    
	//// Jetzt Fenster zeigen!
	setBackground(Color.white);    
	setSize(xMax,yMax);
    setVisible(true);
    }
 //// Ende des Konstruktors  
       
 //// Implementierung der Menübefehle    
    
      
    void doRect1(){
        doMinMax(); // xMax und yMax bestimmen
    	Graphics g = getGraphics();
    	Loeschen(g);
        for ( int i=0; i <= 1000; i++ ){
            g.setColor(ZufallsFarbe());
            Rectangle r = ZufallsRechteck(xMax, yMax);
            g.fillRect(r.x, r.y, r.width, r.height);
            }
    	}
    	
    void doOval1(){
        doMinMax(); // xMax und yMax bestimmen
    	Graphics g = getGraphics();
    	Loeschen(g);
        for ( int i=0; i <= 1000; i++ ){
            g.setColor(ZufallsFarbe());
            Rectangle r = ZufallsRechteck(xMax, yMax);
            g.fillOval(r.x, r.y, r.width, r.height);
            }
    	}	
	
	void doRecOva(){	
    	doMinMax(); // xMax und yMax bestimmen
    	Graphics g = getGraphics();
    	Loeschen(g);
        for ( int i=0; i <= 1000; i++ ){
            g.setColor(ZufallsFarbe());
            Rectangle r = ZufallsRechteck(xMax, yMax);
            g.fillRect(r.x, r.y, r.width, r.height);
            g.setColor(ZufallsFarbe());
            g.fillOval(r.x, r.y, r.width, r.height);
            }
        }
        
    void doCirc1(){
      doMinMax(); // xMax und yMax bestimmen
    	Graphics g = getGraphics();
		  int x0 = xMax / 2;
		  int y0 = yMax / 2;
		  for (int i = 255; i > 0; i--){ 
			   g.setColor(new Color(i, 255-i, i));
			   int r =  i + 2;
			   int d =  2*r;
			   g.fillOval(x0-r,y0-r,d,d);
			}
   }       
        
    void doPhyta(){	
    	doMinMax();
    	Graphics g = getGraphics();
    	Loeschen(g);
    	g.setColor(Color.red);
    	InitZufallsFarbe();
    	int lx = (xMax / 2) - (xMax / 16);
	    int dx = (Math.min(xMax, yMax))  / 10;
	    Point P1 = new Point(lx - dx, yMax - 10);
	    Point P2 = new Point(lx + dx, yMax - 10);
	    pythagorasBaum(g, P1, P2);
        }
        
     void pythagoras(){
		  Graphics g = getGraphics();
		  Point p1 = new Point(290, 590); // z.B.
		  Point p2 = new Point(410, 590); // z.B.
		  pythagorasBaum(g, p1, p2);
		} 
		
	void pythagorasBaum(Graphics g, Point p1, Point p2){	
		int dx = p2.x - p1.x;
		int dy = p1.y - p2.y;
		int   hy = dx*dx+dy*dy;
		Point p3 = new Point(p2.x - dy, p2.y - dx);
		Point p4 = new Point(p1.x - dy, p1.y - dx);
		Polygon Poly = new Polygon();
		Poly.addPoint(p1.x, p1.y);
		Poly.addPoint(p2.x, p2.y);
		Poly.addPoint(p3.x, p3.y);
		Poly.addPoint(p4.x, p4.y);
		ZufallsFarbe(g);
		g.fillPolygon(Poly);
		int xneu = (int) (0.64*p1.x + 0.36*p2.x - 1.48*dy);
		int yneu = (int) (0.64*p1.y + 0.36*p2.y - 1.48*dx);
		Point pNeu = new Point( xneu, yneu);
		if (hy > 10) { 
			pythagorasBaum(g, p4, pNeu);
			pythagorasBaum(g, pNeu, p3);
			}
		}           

////  About Box
	
    void showAboutBox(){	
	final Frame f = new Frame("About Box");
	final Button Ok = new Button("Ok");

	f.addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent e) {
		f.dispose();
		}
	    });
	    
	 Ok.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
		f.dispose();
		}
	    });
	
	f.setFont(BigItalicSansSerif);
	f.setLayout(new GridLayout(0, 1));

	f.add(new Label(" ", Label.CENTER));
	f.add(new Label("Universität Marburg - Fachbereich Mathematik und Informatik", Label.CENTER));
	f.add(new Label("Rechtecke etc...", Label.CENTER));
	f.add(new Label("Datum der letzten Änderung: " + VersionsDatum, Label.CENTER));
	f.add(new Label("Autor: Prof. Dr. Manfred Sommer", Label.CENTER));
	f.add(new Label(" ", Label.CENTER));
	
	f.add(Ok);
	f.pack(); 
	f.setVisible(true);
	}	
	
////  Programm Beenden
    
    void FensterBeenden() {		        
	dispose();
	System.exit(0);
	}	

////  Programm Starten

    public static void main(String args[]) {
    new Demo();
    }
    
////  Grafik Algorithmen 

    java.util.Random RGen = new java.util.Random();
	
	int random(int max){
	    int i = Math.abs(RGen.nextInt());
	    return i % max;
	    }
	  
	Point ZufallsPunkt(int xm, int ym){
        return new Point(random(xm), random(ym));
        } 

    Color ZufallsFarbe(){ 
        return new Color(random(256), random(256), random(256) );
        }
    
    static Color[]   ZufallsFarben = new Color[1000];
        
    void InitZufallsFarbe(){
        for (int i = 0; i< 1000; i++) ZufallsFarben[i] = 
		new Color(random(128), random(128), random(128));
        } 
    
    void ZufallsFarbe(Graphics g){
        g.setColor(ZufallsFarben[random(1000)]);
        }    
        
    Rectangle ZufallsRechteck(int xm, int ym){
        int x = random(xm-2);
        int y = random(ym-2);
        int w = random(xm - (x+2));
        int h = random(ym - (y+2));
        return new Rectangle(x, y, w, h);
        }     
	  
	void SetPixel(Graphics g, Point P, Color f){
      g.setColor(f);
	  g.drawLine(P.x,P.y,P.x,P.y);
      }
      
    void doMinMax(){
        Dimension d = getSize();
	    xMax = d.width-1;
	    yMax = d.height-1;
	    }
	    
	void Loeschen(Graphics g){
        g.clearRect(0, 0, xMax, yMax);
	    }
}
