import java.lang.*;
import java.io.*;
import java.util.*; 

import java.awt.*;
import java.awt.event.*;


class JM extends Frame {
    
    private static final String VersionsDatum = "29. September 2004";
    
    private static String  Titel = "Julia und Mandelbrot Demo";
    
    private static boolean	    		farbig  = true;  // Farbig oder Schwarz/Weiß
	  private final static int				fOffset = 28; // Platz für die Menüleiste 
	  private static int				      xMax = 350;   // Fensterbreite für Ausgabe
	  private static int				      yMax = 260;   // Fensterhöhe für Ausgabe
	  private final static int				nMax = 255;   // Maximalzahl der Iterationen

    private static final int yOffset1 = 42;
    private static final int yOffset2 = 28;
    
    private static int XredMax = xMax/2;
    private static int YredMax = (yMax-yOffset2)/2;
        
    private final static double amin = -2.2;  // Mandelbrot Rechteck
	  private final static double amax =  1.8;
	  private final static double bmin = -1.5;
	  private final static double bmax =  1.5;
	  //private final static double deltaA = (amax - amin) / xMax;
	  //private final static double deltaB = (bmax - bmin) / yMax;

    private static final double deltaA = (amax - amin) / XredMax;
    private static final double deltaB = (bmax - bmin) / YredMax;
    
	private static final double xMinJ = -1.3;  // Julia Rechteck
	private static final double xMaxJ =  1.2;
	private static final double yMinJ = -1.4;
	private static final double yMaxJ =  1.4;
	private static final double deltaX = (xMaxJ - xMinJ) / XredMax;
	private static final double deltaY = (yMaxJ - yMinJ) / YredMax;
	
    private static Color [] farben  = new Color[nMax+1];  // Farben
	
    
    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 Mandel1 = new MenuItem("mandelbrot1");
    private static MenuItem Mandel2 = new MenuItem("mandelbrot2");
    private static MenuItem Julia1 = new MenuItem("Julia1");
    private static MenuItem Julia2 = new MenuItem("Julia2");
      
    private static final String MitFarbe  = "farbig";
    private static final String OhneFarbe = "s/w";
    
    private static Menu OptionenMenu = new Menu("Optionen");
    private static MenuItem OptionenFarbig = !farbig ? new MenuItem(MitFarbe) : new MenuItem(OhneFarbe);  
    private static MenuItem OptionenLoe = new MenuItem("Löschen!");
    
    private static Menu HilfeMenu = new Menu("Hilfe");
    private static MenuItem Hilfe = new MenuItem("Es gibt keine Hilfe...");
    private static MenuItem AboutBox = new MenuItem("About");
        
 JM() {
    super(Titel);
	
	setFont(FontMono);
	DateiMenu.setFont(FontSansSerif);
	Beenden.setFont(FontSansSerif);
	
	GrafikDemoMenu.setFont(FontSansSerif);
	Mandel1.setFont(FontSansSerif);
	Mandel2.setFont(FontSansSerif);
	Julia1.setFont(FontSansSerif);
	Julia2.setFont(FontSansSerif);
	
	OptionenMenu.setFont(FontSansSerif);
	OptionenFarbig.setFont(FontSansSerif);
	OptionenLoe.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(Mandel1);
	GrafikDemoMenu.add(Mandel2);
	GrafikDemoMenu.add(Julia1);
	GrafikDemoMenu.add(Julia2);
	
	MainMenuBar.add(OptionenMenu);
	OptionenMenu.add(OptionenFarbig);
	OptionenMenu.add(OptionenLoe);
	
	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(); }
	    });
	    
	Mandel1.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        mandelbrot(1000, nMax, 1);
	        }
	    });
	    
	Mandel2.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        mandelbrot(1000, nMax, 2);
	        }
	    });    
	    
	Julia1.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        Julia(1000, 0.3, 0.6, nMax, 1);
	        }
	    }); 
	    
	Julia2.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        Julia(1000, 0.3, 0.6, nMax, 2);
	        }
	    });    
	    
	OptionenFarbig.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ 
	        farbig = !farbig;
	        OptionenFarbig.setLabel( !farbig ? MitFarbe : OhneFarbe);
	        }
	    });
	    	
	OptionenLoe.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){
	        Graphics g = getGraphics();
	        Loeschen(g);
	        }
	    });    
	
	        	    	    
	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);

}

////  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("Mandelbrot und Juliamengen", 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);
	}	

    void FensterBeenden() {		        
	dispose();
	System.exit(0);
    }
    
    void doMinMax(){
        Dimension d = getSize();
	      xMax = d.width-1;
	      yMax = d.height-1;
        XredMax = xMax/2;
        YredMax = (yMax-yOffset2)/2;
	    
	    }
	    
	void Loeschen(Graphics g){
        g.clearRect(0, 0, xMax, yMax);
	    }
	        
   /* 
   { //static initializer für die Farben Version 1
        for (int n = 0; n < 10; n++)
          Farben[n] = new Color(0,0, 255 - 10*n);
        for (int n = 10; n < 40; n++)
          Farben[n] = new Color(0, 4*n, 155 - 2*n); 
        for (int n = 40; n < 100; n++)
          Farben[n] = new Color(0, 155+n, 60 -(n/2)); 
        for (int n = 100; n < nMax; n++)
          Farben[n] = new Color(n/8, 220+n/8, 0); 
        for (int n = nMax; n < nMax+1; n++)
          Farben[n] = new Color(0, 0, 0);  
        } 
    */    
   
        
    
	
	{ //static initializer für die Farben
		for (int n = 0; n < nMax; n++)
		farben[n] = new Color((n*26)%250,(n*2)%250, (n*35)%250);
		
		farben[nMax] = Color.black;  
	} 

  void putPixel(Graphics g, int x, int y, int n, int nMax, int pixSize){
		g.setColor(farbig ? farben[n] : Color.black);
		g.drawRect(x*pixSize, yOffset1 + y*pixSize, 
							pixSize - 1, pixSize - 1);   
		}
                
    void mandelbrot(double limit, int nMax, int pixSize){
		Graphics g = getGraphics();
		for (int i = 0; i <= xMax; i++){
			double A = amin+i*deltaA;
			for (int j = 0; j <= yMax; j++){
    				double B = bmin + j*deltaB;
    				double x = 0;
    				double y = 0;
    				double x2n = 0;
    				double y2n = 0;
    				int n = 0;
				do {
    					double xneu = x2n-y2n+A;
    					double yneu = 2*x*y+B;
					if (( x == xneu) && (y == yneu)){
						n = nMax; 
						break;
					}
    					x = xneu;
    					y = yneu;
    					x2n  =  x*x;
					y2n  =  y*y;
					n++;
					} while ((n < nMax) && ((x2n+y2n) <= limit));
				putPixel(g, i, j, n, nMax, pixSize);
				}//j
			}//i
		}//mandelbrot 
	
        
	void Julia(double limit, double a, double b, int nMax, int PixSize){
      Graphics g = getGraphics();
      for (int i = 0; i <= XredMax; i++){
		for (int j = 0; j <= YredMax; j++){
			double x = xMinJ+i*deltaX;
			double y = yMinJ+j*deltaY;
			double x2n = x*x;
			double y2n = y*y;
			int n = 0;
			do {
				double xneu = x2n-y2n+a;
				double yneu = 2*x*y+b;
				if (( x == xneu) && (y == yneu)){
    				    n = nMax; 
    				    break;
    				    }
				x = xneu;
				y = yneu;
				x2n  =  x*x;
				y2n  =  y*y;
				n++;
			} while (( n < nMax) && ((x2n+y2n) <= limit));
			putPixel(g, i, j, n, nMax, PixSize);
			}//j
		}//i
    g = null;		
    }//Julia    }
    
    public static void main(String args[]) {
    new JM();
    }
    
}
