package fplot;

import java.awt.*;
import java.awt.event.*;
/**
 * Das Dialogfenster, in dem der Darstellungsbereich und die Funktionen
 * angegeben werden.
 * @author Christian Semrau
 * <a href="mailto:Christian.Semrau@student.uni-magdeburg.de">
 * Christian.Semrau@student.uni-magdeburg.de</a>
 * <br><a href="http://chsemrau.de">Homepage</a>
 */
class DialogFenster extends Frame
implements ActionListener, ItemListener, FocusListener{
	private PlotFrame applet;
	private GraphFlaeche flaeche;
	private int numFormeln;
	private boolean extended;
	private boolean wantExtended;

	private Panel theContentsPane = null;
	private Panel extendedPane = null;
	private Panel parameterPane = null;
	private BorderLayout theLayout = null;

	private Button SetButton = null;
	private Button GetButton = null;
	private Button ExtendedButton = null;
	private Checkbox PostfixCheckbox = null;
	private CheckboxGroup KlammerungCbg = null;
	private Checkbox[] KlammerungCheckbox = null;
	private Checkbox EinheitskreisCheckbox = null;

	private Label xMaxLabel = null;
	private Label xMinLabel = null;
	private Label yMaxLabel = null;
	private Label yMinLabel = null;
	private TextField xMaxField = null;
	private TextField xMinField = null;
	private TextField yMaxField = null;
	private TextField yMinField = null;

	private Label[] FormelLabel = null;
	private TextField[] FormelField = null;
	private Checkbox[] ShowFormelCheckbox = null;

	private Label pLabel = null;
	private TextField pField = null;
	private Label qLabel = null;
	private TextField qField = null;

	private Choice NumFormelnChoice = null;

	private Label XYKoordLabel = null;
	private Choice XKoordChoice = null;
	private Choice YKoordChoice = null;
	private Label TLabel = null;
	private TextField TStartField = null;
	private TextField TStopField = null;
	private TextField TStepField = null;

	private int __sy_e; // Zeile des erweiterten Panels
	private int __sy_f; // Zeile der Funktion 0
	private int __cc_f; // ComponentCount der ersten Funktion
	private GridBagLayout __gbl; // Layoutmanager

	// einige Konstanten die das Leben erleichtern
	final int NONE = GridBagConstraints.NONE;
	final int HORIZONTAL = GridBagConstraints.HORIZONTAL;
	final int VERTICAL = GridBagConstraints.VERTICAL;
	final int CENTER = GridBagConstraints.CENTER;
	final int WEST = GridBagConstraints.WEST;
	final int EAST = GridBagConstraints.EAST;
	final int NORTH = GridBagConstraints.NORTH;
	final int SOUTH = GridBagConstraints.SOUTH;
	final int NORTHWEST = GridBagConstraints.NORTHWEST;
	final int NORTHEAST = GridBagConstraints.NORTHEAST;
	final int SOUTHWEST = GridBagConstraints.SOUTHWEST;
	final int SOUTHEAST = GridBagConstraints.SOUTHEAST;


/** Konstruktor des Dialogfensters */
public DialogFenster(PlotFrame app, boolean ext) {
	super();
	applet = app;
	flaeche = (app!=null) ? applet.getFlaeche() : null;
	numFormeln = applet==null ? 3 : flaeche.getNumFormeln();
	wantExtended = extended = ext;
	initialize();
}

/** Debugging-Methode. */
private void a() {
//	if (applet!=null) System.out.println(applet.getFlaeche());
}

/** Reagiert auf die Buttons */
public void actionPerformed(ActionEvent e) {
	if (e.getSource() == getSetButton()) {
		// bei Fehlern wird das entsprechende Feld fokussiert
		if (setzeFormel() && schreibeBereich() && setzeT()){
			if (flaeche!=null){
				flaeche.repaint();
			}
		}
a();
		return;
	}

	if (e.getSource() == getGetButton()) {
		holeBereich();
		holeT();
		return;
	}

	if (e.getSource() == getExtendedButton()) {
		wantExtended = !extended;
		if (extended) {
			closeExtended();
		}else{
			openExtended();
		}
		packHeight();
		return;
	}

	for (int index=0; index<FormelField.length; index++)
	if (e.getSource() == getFormelField(index)) {
		if (flaeche!=null)
			flaeche.setShowfunc(index,true);
		if (setzeFormel(index)){
			if (flaeche!=null){
				getShowFormelCheckbox(index).setState(
					flaeche.getShowfunc(index));
				flaeche.repaint();
			}
		}
a();
		return;
	}

	if (e.getSource() == getPField()){
		setzeP();
		if (flaeche!=null){
			flaeche.repaint();
		}
		return;
	}

	if (e.getSource() == getQField()){
		setzeQ();
		if (flaeche!=null){
			flaeche.repaint();
		}
		return;
	}

	if (e.getSource() == getTStartField()
	|| e.getSource() == getTStopField()
	|| e.getSource() == getTStepField()){
		if (setzeT())
		if (flaeche!=null){
			flaeche.repaint();
		}
		return;
	}

a();
} // actionPerformed

/** Schliesst den erweiterten Panel. */
private void closeExtended() {
	if (!extended) return;
	getTheContentsPane().remove(getExtendedPane());
	extended = false;
}

/**
 * Entfernt die angegebene Formel.
 * @param index int
 */
private void closeFormula(int index) {
	getTheContentsPane().remove(getFormelLabel(index));
	getTheContentsPane().remove(getFormelPanel(index));
	getFormelField(index).removeActionListener(this);
	getShowFormelCheckbox(index).removeItemListener(this);
}

/**
 * Markiert den gesamten Text eines Textfields, wenn es fokussiert wird.
 * @param event java.awt.event.FocusEvent
 */
public void focusGained(FocusEvent event) {
	Object src = event.getSource();
	if (src instanceof TextField){
		((TextField)src).selectAll();
	}
	
}

/**
 * 
 * @param event java.awt.event.FocusEvent
 */
public void focusLost(FocusEvent event) {
}

/** Konstruiert und liefert die EinheitskreisCheckbox */
private Checkbox getEinheitskreisCheckbox() {
	if (EinheitskreisCheckbox == null) {
		EinheitskreisCheckbox = new java.awt.Checkbox("EK");
		EinheitskreisCheckbox.setState(false);
		EinheitskreisCheckbox.addItemListener(this);
	}
	return EinheitskreisCheckbox;
}

/** Konstruiert und liefert den ExtendedButton */
private Button getExtendedButton() {
	if (ExtendedButton == null) {
		ExtendedButton = new java.awt.Button("Mehr");
		ExtendedButton.setActionCommand("Extended");
		ExtendedButton.addActionListener(this);
	}
	return ExtendedButton;
}

/** Konstruiert und liefert den Inhalt des erweiterten Dialogfensters */
private Panel getExtendedPane() {
	if (extendedPane != null) return extendedPane;

	GridBagLayout gbl = new GridBagLayout();
	GridBagConstraints gbc;
	Panel p;
	Component co;
	FlowLayout l = new FlowLayout(FlowLayout.LEFT,5,5);

	extendedPane = new java.awt.Panel();
	extendedPane.setName("extendedPane");
	extendedPane.setLayout(gbl);

	int sy = 0;

	gbc = makegbc(0,sy,4,1,NONE,WEST);
	gbc.weightx = 100;
	p = new Panel(l);
	//
	//  SETBUTTON
	//
	p.add(getPostfixCheckbox());
	p.add(getEinheitskreisCheckbox());
	p.add(getNumFormelnChoice());
	co = p;
	gbl.setConstraints(co, gbc);
	extendedPane.add(co);
	sy++;

	gbc = makegbc(0,sy,4,1,NONE,WEST);
	gbc.weightx = 100;
	p = new Panel(l);
	KlammerungCbg = new CheckboxGroup();
	p.add(new Label("Klammerung"));
	p.add(getKlammerungCheckbox(0));
	p.add(getKlammerungCheckbox(1));
	p.add(getKlammerungCheckbox(2));
	co = p;
	gbl.setConstraints(co, gbc);
	extendedPane.add(co);
	sy++;

	gbc = makegbc(0,sy,4,1,NONE,WEST);
	gbc.weightx = 100;
	p = new Panel(l);
	p.add(getPLabel());
	p.add(getPField());
	p.add(getQLabel());
	p.add(getQField());
	co = p;
	gbl.setConstraints(co, gbc);
	extendedPane.add(co);
	sy++;

	gbc = makegbc(0,sy,4,1,NONE,NORTHWEST);
	gbc.weightx = 100;
	gbc.weighty = 100;
	p = new Panel(l);
	p.add(getXYKoordLabel());
	p.add(getXKoordChoice());
	p.add(getYKoordChoice());
	p.add(getTLabel());
	co = p;
	gbl.setConstraints(co, gbc);
	extendedPane.add(co);
	sy++;

	gbc = makegbc(0,sy,4,1,NONE,NORTHWEST);
	gbc.weightx = 100;
	gbc.weighty = 100;
	p = new Panel(l);
	p.add(getTStartField());
	p.add(getTStopField());
	p.add(getTStepField());
	co = p;
	gbl.setConstraints(co, gbc);
	extendedPane.add(co);
	sy++;

	return extendedPane;
}

/** Konstruiert und liefert ein FormelField */
private TextField getFormelField(int index) {
	if (index<0) throw new IllegalArgumentException(index+"<0");
	if (FormelField == null) {
		FormelField = new TextField[Math.max(index+1, numFormeln)];
		for(int i=0; i<FormelField.length; i++)
			FormelField[i] = new TextField();
	}else
	if (index>=FormelField.length){
		TextField[] ff = new TextField[Math.max(index+1, numFormeln)];
		for(int i=0; i<FormelField.length; i++)
			ff[i] = FormelField[i];
		for(int i=FormelField.length; i<ff.length; i++)
			ff[i] = new TextField();
		FormelField = ff;
	}
	return FormelField[index];
}

/** Konstruiert und liefert ein FormelLabel */
private Label getFormelLabel(int index) {
	if (index<0) throw new IllegalArgumentException(index+"<0");

	if (FormelLabel == null) {
		FormelLabel = new Label[Math.max(index+1, numFormeln)];
		for(int i=0; i<FormelLabel.length; i++)
			FormelLabel[i] = new Label("Funktion "+(i+1), Label.RIGHT);
	}else
	if (index>=FormelLabel.length){
		Label[] fl = new Label[Math.max(index+1, numFormeln)];
		for(int i=0; i<FormelLabel.length; i++)
			fl[i] = FormelLabel[i];
		for(int i=FormelLabel.length; i<fl.length; i++)
			fl[i] = new Label("Funktion "+(i+1), Label.RIGHT);
		FormelLabel = fl;
	}

	return FormelLabel[index];
}

/** Konstruiert und liefert ein FormelPanel */
private Component getFormelPanel(int index) {
	GridBagConstraints gbc;
	Component co;

	// FormelField und ShowFormelCheckbox
	GridBagLayout gbl2 = new GridBagLayout();
	Panel p = new Panel(gbl2);

	gbc = makegbc(0,0,1,1,HORIZONTAL,CENTER);
	gbc.weightx = 100;
	co = getFormelField(index);
	gbl2.setConstraints(co, gbc);
	p.add(co);

	gbc = makegbc(1,0,1,1,HORIZONTAL,WEST);
	co = getShowFormelCheckbox(index);
	gbl2.setConstraints(co, gbc);
	p.add(co);

	co = p;
	return co;
}

/** Konstruiert und liefert den GetButton */
private Button getGetButton() {
	if (GetButton == null) {
		GetButton = new java.awt.Button("Lesen");
		GetButton.setActionCommand("Get");
		GetButton.addActionListener(this);
	}
	return GetButton;
}

/** Liefert die ausgewaehlte Klammerungsstufe. */
private int getKlammerung() {
	if (getKlammerungCheckbox(0).getState())
		return FuncNode.KLAMMERUNG_ALLES;
	if (getKlammerungCheckbox(1).getState())
		return FuncNode.KLAMMERUNG_MITTEL;
	if (getKlammerungCheckbox(2).getState())
		return FuncNode.KLAMMERUNG_WENIG;

	return FuncNode.KLAMMERUNG_ALLES;
}

/** Konstruiert und liefert die KlammerungCheckbox */
private Checkbox getKlammerungCheckbox(int index) {
	if (index<0) throw new IllegalArgumentException(index+"<0");
	if (KlammerungCheckbox == null) {
		KlammerungCheckbox = new Checkbox[3];
		KlammerungCheckbox[0] = new Checkbox("Alles", KlammerungCbg, false);
		KlammerungCheckbox[1] = new Checkbox("Mittel", KlammerungCbg, false);
		KlammerungCheckbox[2] = new Checkbox("Wenig", KlammerungCbg, false);
		/*
		KlammerungCheckbox[0].addItemListener(this);
		KlammerungCheckbox[1].addItemListener(this);
		KlammerungCheckbox[2].addItemListener(this);
		*/
	}else
	if (index>=KlammerungCheckbox.length){
		throw new IllegalArgumentException(
		index+">"+KlammerungCheckbox.length);
	}

	return KlammerungCheckbox[index];
}

/** Konstruiert und liefert die NumFormelChoice */
private Choice getNumFormelnChoice() {
	if (NumFormelnChoice == null) {
		NumFormelnChoice = new Choice();
		NumFormelnChoice.addItem(1+" Funktion");
		for (int i=2; i<=5; i++)
			NumFormelnChoice.addItem(i+" Funktionen");
		NumFormelnChoice.select(0);
		NumFormelnChoice.addItemListener(this);
	}
	return NumFormelnChoice;
}

/** Konstruiert und liefert das pField */
private TextField getPField() {
	if (pField == null) {
		pField = new java.awt.TextField(8);
		pField.addActionListener(this);
	}
	return pField;
}

/** Konstruiert und liefert das pLabel */
private Label getPLabel() {
	if (pLabel == null) {
		pLabel = new java.awt.Label("p", Label.RIGHT);
	}
	return pLabel;
}

/** Konstruiert und liefert die PostfixCheckbox */
private Checkbox getPostfixCheckbox() {
	if (PostfixCheckbox == null) {
		PostfixCheckbox = new java.awt.Checkbox("Postfix");
		PostfixCheckbox.setState(false);
	}
	return PostfixCheckbox;
}

/** Konstruiert und liefert das qField */
private TextField getQField() {
	if (qField == null) {
		qField = new java.awt.TextField(8);
		qField.addActionListener(this);
	}
	return qField;
}

/** Konstruiert und liefert das qLabel */
private Label getQLabel() {
	if (qLabel == null) {
		qLabel = new java.awt.Label("q", Label.RIGHT);
	}
	return qLabel;
}

/** Konstruiert und liefert den SetButton */
private Button getSetButton() {
	if (SetButton == null) {
		SetButton = new java.awt.Button("Setzen");
		SetButton.setActionCommand("Set");
		SetButton.addActionListener(this);
	}
	return SetButton;
}

/** Konstruiert und liefert eine ShowFormelCheckbox */
private Checkbox getShowFormelCheckbox(int index) {
	if (index<0) throw new IllegalArgumentException(index+"<0");
	if (ShowFormelCheckbox == null) {
		ShowFormelCheckbox = new Checkbox[Math.max(index+1, numFormeln)];
		for(int i=0; i<ShowFormelCheckbox.length; i++)
			ShowFormelCheckbox[i] = new Checkbox();
	}else
	if (index>=ShowFormelCheckbox.length){
		Checkbox[] sf = new Checkbox[Math.max(index+1, numFormeln)];
		for(int i=0; i<ShowFormelCheckbox.length; i++)
			sf[i] = ShowFormelCheckbox[i];
		for(int i=ShowFormelCheckbox.length; i<sf.length; i++)
			sf[i] = new Checkbox();
		ShowFormelCheckbox = sf;
	}
	return ShowFormelCheckbox[index];
}

/** Konstruiert und liefert den Inhalt des Dialogfensters */
private Panel getTheContentsPane() {
	if (theContentsPane != null) return theContentsPane;

	GridBagLayout gbl = new GridBagLayout();
	__gbl = gbl;
	GridBagConstraints gbc;
	Panel p;
	Component co;
	FlowLayout l = new FlowLayout(FlowLayout.LEFT,5,5);
	FlowLayout l0 = new FlowLayout(FlowLayout.LEFT,0,0);

	theContentsPane = new java.awt.Panel();
	theContentsPane.setName("ContentsPane");
	theContentsPane.setLayout(gbl);

	int sy = 0;

	gbc = makegbc(0,sy,1,1,NONE,EAST);
	co = getxMinLabel();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(1,sy,1,1,HORIZONTAL,WEST);
	gbc.weightx = 100;
	co = getxMinField();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(2,sy,1,1,NONE,EAST);
	co = getyMinLabel();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(3,sy,1,1,HORIZONTAL,WEST);
	gbc.weightx = 100;
	co = getyMinField();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);
	sy++;

	gbc = makegbc(0,sy,1,1,NONE,EAST);
	co = getxMaxLabel();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(1,sy,1,1,HORIZONTAL,WEST);
	gbc.weightx = 100;
	co = getxMaxField();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(2,sy,1,1,NONE,EAST);
	co = getyMaxLabel();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);

	gbc = makegbc(3,sy,1,1,HORIZONTAL,WEST);
	gbc.weightx = 100;
	co = getyMaxField();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);
	sy++;

	// die Formeln konstruieren und einfuegen
	__sy_f = sy;
	__cc_f = theContentsPane.getComponentCount();
	for (int index=0; index<numFormeln; index++){
		openFormula(index);
	}
	for (int index=numFormeln; index<10; index++)
		sy++;


	gbc = makegbc(0,sy,4,1,NONE,NORTHWEST);
	gbc.weightx = 100;
	gbc.weighty = 100;
	p = new Panel(l);
	p.add(getSetButton());
	p.add(getGetButton());
	p.add(getExtendedButton());
	co = p;
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);
	sy++;

	if (extended){
		gbc = makegbc(0,sy,4,1,NONE,NORTHWEST);
		gbc.weightx = 100;
		gbc.weighty = 100;
		co = getExtendedPane();
		gbl.setConstraints(co, gbc);
		theContentsPane.add(co);
		sy++;
	}else
		getExtendedPane();

	__sy_e = sy;
	return theContentsPane;
}

/** Konstruiert und liefert das Layout des Dialogfensters */
private BorderLayout getTheLayout() {
	if (theLayout == null) {
		theLayout = new java.awt.BorderLayout(5,5);
	}
	return theLayout;
}

/** Konstruiert und liefert das TLabel */
private Label getTLabel() {
	if (TLabel == null) {
		TLabel = new java.awt.Label("T: (Start,Stop,Step)", Label.RIGHT);
	}
	return TLabel;
}

/** Konstruiert und liefert das TStartField */
private TextField getTStartField() {
	if (TStartField == null) {
		TStartField = new java.awt.TextField(8);
		TStartField.addActionListener(this);
	}
	return TStartField;
}

/** Konstruiert und liefert das TStepField */
private TextField getTStepField() {
	if (TStepField == null) {
		TStepField = new java.awt.TextField(6);
		TStepField.addActionListener(this);
	}
	return TStepField;
}

/** Konstruiert und liefert das TStopField */
private TextField getTStopField() {
	if (TStopField == null) {
		TStopField = new java.awt.TextField(8);
		TStopField.addActionListener(this);
	}
	return TStopField;
}

/** Konstruiert und liefert die XKoordChoice */
private Choice getXKoordChoice() {
	if (XKoordChoice == null) {
		XKoordChoice = new Choice();
		XKoordChoice.addItem("-");
		for (int i=1; i<=5; i++)
			XKoordChoice.addItem(i+"");
		XKoordChoice.select(0);
//		XKoordChoice.addItemListener(this);
	}
	return XKoordChoice;
}

/** Konstruiert und liefert das xMaxField */
private TextField getxMaxField() {
	if (xMaxField == null) {
		xMaxField = new java.awt.TextField(8);
		xMaxField.addFocusListener(this);
	}
	return xMaxField;
}

/** Konstruiert und liefert das xMaxLabel */
private Label getxMaxLabel() {
	if (xMaxLabel == null) {
		xMaxLabel = new java.awt.Label("xMax", Label.RIGHT);
	}
	return xMaxLabel;
}

/** Konstruiert und liefert das xMinField */
private TextField getxMinField() {
	if (xMinField == null) {
		xMinField = new java.awt.TextField(8);
		xMinField.addFocusListener(this);
	}
	return xMinField;
}

/** Konstruiert und liefert das xMinLabel */
private Label getxMinLabel() {
	if (xMinLabel == null) {
		xMinLabel = new java.awt.Label("xMin", Label.RIGHT);
	}
	return xMinLabel;
}

/** Konstruiert und liefert das XYKoordLabel */
private Label getXYKoordLabel() {
	if (XYKoordLabel == null) {
		XYKoordLabel = new java.awt.Label("X(t),Y(t)", Label.RIGHT);
	}
	return XYKoordLabel;
}

/** Konstruiert und liefert die YKoordChoice */
private Choice getYKoordChoice() {
	if (YKoordChoice == null) {
		YKoordChoice = new Choice();
		YKoordChoice.addItem("-");
		for (int i=1; i<=5; i++)
			YKoordChoice.addItem(i+"");
		YKoordChoice.select(0);
//		YKoordChoice.addItemListener(this);
	}
	return YKoordChoice;
}

/** Konstruiert und liefert das yMaxField */
private TextField getyMaxField() {
	if (yMaxField == null) {
		yMaxField = new java.awt.TextField(8);
		yMaxField.addFocusListener(this);
	}
	return yMaxField;
}

/** Konstruiert und liefert das yMaxLabel */
private Label getyMaxLabel() {
	if (yMaxLabel == null) {
		yMaxLabel = new java.awt.Label("yMax", Label.RIGHT);
	}
	return yMaxLabel;
}

/** Konstruiert und liefert das yMinField */
private TextField getyMinField() {
	if (yMinField == null) {
		yMinField = new java.awt.TextField(8);
		yMinField.addFocusListener(this);
	}
	return yMinField;
}

/** Konstruiert und liefert das yMinLabel */
private Label getyMinLabel() {
	if (yMinLabel == null) {
		yMinLabel = new java.awt.Label("yMin", Label.RIGHT);
	}
	return yMinLabel;
}

/**
 * Holt den Darstellungsbereich und die Formel aus dem Anzeigefenster
 * und schreibt sie in das DialogFenster.
 * Rundet den Darstellungsbereich sinnvoll.
 */
public void holeBereich() {
	if (flaeche==null) {
		getxMinField().setText("-10");
		getxMaxField().setText("10");
		getyMinField().setText("-10");
		getyMaxField().setText("10");
	
		getPField().setText("0");
		getQField().setText("0");
		setKlammerung(FuncNode.KLAMMERUNG_MITTEL);
		getNumFormelnChoice().select(numFormeln-1);
		for (int index=0; index<FormelField.length; index++)
			holeFormel(index);
		return;
	}

	double xmi = flaeche.getXmin();
	double xma = flaeche.getXmax();
	double ymi = flaeche.getYmin();
	double yma = flaeche.getYmax();
	double p = flaeche.getP();
	double q = flaeche.getQ();

	double dx = xma - xmi;
	int ex = GraphFlaeche.potenzVon(10, dx);
	double px = Math.pow(10, ex-2);
	xmi = Math.round(xmi/px)*px;
	xma = Math.round(xma/px)*px;

	double dy = yma - ymi;
	int ey = GraphFlaeche.potenzVon(10, dy);
	double py = Math.pow(10, ey-2);
	ymi = Math.round(ymi/py)*py;
	yma = Math.round(yma/py)*py;

	// durch die Verwendung der eigenen Methode round passiert es nicht mehr,
	// dass die Zahl eine lange Reihe von Nullen hat, (z.B. 7.800000000000001)

	getxMinField().setText(round(""+xmi));
	getxMaxField().setText(round(""+xma));
	getyMinField().setText(round(""+ymi));
	getyMaxField().setText(round(""+yma));

	if (KlammerungCbg.getSelectedCheckbox()==null)
		setKlammerung(flaeche.getKlammerung());
	else
		flaeche.setKlammerung(getKlammerung());
	getNumFormelnChoice().select(flaeche.getNumFormeln()-1);
	for (int index=0; index<FormelField.length; index++)
		holeFormel(index);

	getEinheitskreisCheckbox().setState(flaeche.getEinheitskreis());
	getPField().setText(""+p);
	getQField().setText(""+q);
}

/** Holt eine Formel aus dem Anzeigefenster. */
private void holeFormel(int index) {
	if (flaeche==null){
		getFormelField(index).setText(index==0?"x":"");
		getShowFormelCheckbox(index).setState(index==0);
	}else{
		String func = flaeche.getFormula(index, getPostfixCheckbox().getState());
		getFormelField(index).setText(func);
		getShowFormelCheckbox(index).setState(flaeche.getShowfunc(index));
	}
}

/**
 * Holt die Werte des Parameters T.
 */
private void holeT() {
	if (flaeche!=null){
		getXKoordChoice().select(flaeche.getTXi()+1);
		getYKoordChoice().select(flaeche.getTYi()+1);
		getTStartField().setText(round(""+flaeche.getTstart()));
		getTStopField().setText(round(""+flaeche.getTstop()));
		getTStepField().setText(""+flaeche.getTstep());
	}else{
		getXKoordChoice().select(0);
		getYKoordChoice().select(0);
		getTStartField().setText("0.0");
		getTStopField().setText("1.0");
		getTStepField().setText("100");
	}
}

/** Initialisiert das Fenster */
private void initialize() {
	setTitle("Einstellungen");
	setName("DialogFenster");
	setLayout(getTheLayout());
	setBackground(java.awt.Color.white);
	add(getTheContentsPane(), "Center");
	initWindowListener();
	pack();
	holeBereich();
	holeT();
}

/** Registriert einen WindowListener */
private void initWindowListener() {
	this.addWindowListener(new WindowAdapter(){
		public void windowClosing(WindowEvent e) {
			// das Applet entfernt das Dialogfenster
			if (applet!=null)
				applet.disposeDialog();
			else{
				dispose();
				System.exit(0);
			}
		}	
	});
}

/**
 * Reagiert auf Ereignisse in den Checkboxen und Choice-Listen.
 * @param event java.awt.event.ItemEvent
 */
public void itemStateChanged(ItemEvent e) {
	if (e.getSource() == getEinheitskreisCheckbox()){
		boolean ek = getEinheitskreisCheckbox().getState();
		if (flaeche!=null){
			flaeche.setEinheitskreis(ek);
			flaeche.repaint();
		}
		return;
	}
/*
	if (e.getSource() == getKlammerungCheckbox()){
		boolean kl = getKlammerungCheckbox().getState();
		if (applet!=null){
			applet.getFlaeche().setKlammerung(kl);
			applet.getFlaeche().repaint();
		}
		return;
	}
*/

	if (e.getSource() == getNumFormelnChoice()){
		int num = getNumFormelnChoice().getSelectedIndex()+1;
		if (numFormeln!=num){
			if (numFormeln < num)
			for(int index = numFormeln; index < num; index++){
				openFormula(index);
				holeFormel(index);
			}else
			for(int index = numFormeln-1; index >= num; index--)
				closeFormula(index);
			packHeight();
			if (flaeche!=null){
				flaeche.setNumFormeln(num);
				flaeche.repaint();
a();
			}
			numFormeln = num;
		}
		return;
	}

	for(int index = 0; index<numFormeln; index++){
		if (e.getSource() == getShowFormelCheckbox(index)){
			boolean state = getShowFormelCheckbox(index).getState();
			if (getFormelField(index).getText().length()==0)
				getShowFormelCheckbox(index).setState(state = false);
			if (flaeche!=null){
				if (state) setzeFormel(index);
				flaeche.setShowfunc(index,state);
				flaeche.repaint();
			}
a();
			return;
		}
	}
}

/**  */
public static void main(String args[]) {
	DialogFenster df = new DialogFenster(null, true);
	df.show();
}

/**
 * Liefert ein GridBagConstraints-Objekt mit den uebergebenen Parametern.
 * @return java.awt.GridBagConstraints
 * @param x Linke obere Ecke
 * @param y Linke obere Ecke
 * @param w horizontale Ausdehnung
 * @param h vertikale Ausdehnung
 * @param fill Fuellmodus
 * @param anchor Anker
 */
public static GridBagConstraints makegbc(int x, int y, int w, int h,
int fill, int anchor) {
	GridBagConstraints gbc = new GridBagConstraints();
	gbc.gridx = x;
	gbc.gridy = y;
	gbc.gridwidth = w;
	gbc.gridheight = h;
	gbc.fill = fill;
	gbc.anchor = anchor;
	gbc.insets = new Insets(1, 1, 1, 1);
	return gbc;
}
/**
 * 
 */
private void openExtended() {
	if (extended) return;
	
	GridBagLayout gbl = __gbl;
	GridBagConstraints gbc;
	Panel p;
	Component co;
	FlowLayout l0 = new FlowLayout(FlowLayout.LEFT,0,0);

	int sy = __sy_e;

	gbc = makegbc(0,sy,4,1,NONE,NORTHWEST);
	gbc.weightx = 100;
	gbc.weighty = 100;
	co = getExtendedPane();
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co);
	sy++;

	extended = true;
}
/**
 * 
 * @param index int
 */
private void openFormula(int index) {

	GridBagLayout gbl = __gbl;
	GridBagConstraints gbc;
	Panel p;
	Component co;
	FlowLayout l = new FlowLayout(FlowLayout.LEFT,5,5);

	int sy = __sy_f+index;

	/*
	Die Angabe __cc_f + index*2 sorgt dafuer, dass die Funktionen
	an der richtigen Stelle eingefuegt werden, wenn die Felder
	lueckenlos eingefuegt werden, ansonsten kommen die Felder
	durcheinander. Die Reihenfolge spielt eine Rolle, wenn man mit
	TAB durch die Felder wechselt.
	*/

	// FormelLabel
	gbc = makegbc(0,sy,1,1,NONE,EAST);
	co = getFormelLabel(index);
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co, __cc_f + index*2);

	// FormelField und ShowFormelCheckbox
	co = getFormelPanel(index);
	gbc = makegbc(1,sy,3,1,HORIZONTAL,WEST);
	gbc.weightx = 100;
	gbl.setConstraints(co, gbc);
	theContentsPane.add(co, __cc_f + index*2+1);

	getFormelField(index).addActionListener(this);
	getShowFormelCheckbox(index).addItemListener(this);
}
/**
 * 
 */
void packHeight() {
	int width = Math.max(getSize().width, getPreferredSize().width);
	setSize(width, getPreferredSize().height);
	validate();
}

/**
 * Entfernt von einer gerundeten double-Zahl die letzten Nullen,
 * wenn durch die Rundung eine Zahl wie 7.800000001 entstanden ist (diese
 * Zahl wird auf 7.8 gekuerzt).
 * Veraendert nichts, wenn am Ende mehr als eine von 0 verschiedene
 * Ziffer steht (z.B. 1.700021), oder nur eine Null am Ende steht (z.B. 1.301)
 * Analoges passiert, wenn die Zahl auf Neunen endet (z.B. 12.3299999994
 * wird auf 12.33 gekuerzt).
 * Das gleiche passiert, wenn die Zahl einen Exponenten enthaelt, z.B.
 * 1.20003E-5 wird auf 1.2E-5 reduziert.
 */
public static String round(String s) {
	String expon = "";
	if (s.indexOf("E")>0){
		expon = s.substring(s.indexOf("E"));
		s = s.substring(0, s.indexOf("E"));
	}
	if (s.substring(0, s.length()-1).endsWith("00")){
		do{
			s = s.substring(0, s.length()-1);
		}while (s.endsWith("0"));
		// am Dezimalpunkt oder einer von 0 verschiedenen Ziffer aufhoeren
		if (s.endsWith(".")){
			// wenn das letzte Zeichen der Punkt ist, entfernen wir ihn
			s = s.substring(0, s.length()-1);
		}
	}else
	if (s.substring(0, s.length()-1).endsWith("99")){
		// sind wir schon vor dem Dezimalpunkt
		boolean nachPunkt = s.indexOf(".")>=0;
		// wenn wir vor dem Komma sind, muessen wir die Neunen mit Nullen nachfuellen
		int vorPunktStellen = 0;
		do{
			s = s.substring(0, s.length()-1);
			if (!nachPunkt) vorPunktStellen++;
			if (s.endsWith(".")){
				s = s.substring(0, s.length()-1);
				nachPunkt = false;
			}
		}while (s.endsWith("9"));

		// das entfernen von Zeichen kostet nichts, aber das anhaengen
		// ist mit Strings eine aufwendige Operation
		StringBuffer sb;
		int len = s.length();
		if (len==0)
			// keine Ziffern mehr da
			sb = new StringBuffer("1");
		else{
			//die letzte Ziffer wird um 1 erhoeht (sie ist ungleich 9)
			sb = new StringBuffer(s);
			sb.setCharAt(len-1, (char)(s.charAt(len-1)+1));
		}
		for(; vorPunktStellen>0; vorPunktStellen--, sb.append("0"));
		s = sb.toString();
	}
	return s + expon;
}

/**
 * Setzt den Darstellungsbereich des Anzeigefensters auf die aktuellen
 * Werte im Dialogfenster. Liefert false, wenn ein Fehler bei der Zahlen-
 * umwandlung auftrat, und fokussiert das Feld, das den Fehler verursacht.
 */
public boolean schreibeBereich() {
	double xmin, xmax, ymin, ymax;

	if (flaeche!=null) flaeche.setKlammerung(getKlammerung());

	try{
		xmin = Double.valueOf(getxMinField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getxMinField().requestFocus();
		getxMinField().selectAll();
		return false;
	}

	try{
		xmax = Double.valueOf(getxMaxField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getxMaxField().requestFocus();
		getxMaxField().selectAll();
		return false;
	}

	try{
		ymin = Double.valueOf(getyMinField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getyMinField().requestFocus();
		getyMinField().selectAll();
		return false;
	}
	try{
		ymax = Double.valueOf(getyMaxField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getyMaxField().requestFocus();
		getyMaxField().selectAll();
		return false;
	}

	boolean ek = getEinheitskreisCheckbox().getState();
	int kl = getKlammerung();

	if (flaeche!=null){
		flaeche.setCoords(xmin, xmax, ymin, ymax);
		flaeche.setEinheitskreis(ek);
		flaeche.setKlammerung(kl);
	}

	return true;
}
/**
 * 
 * @param kl int
 */
private void setKlammerung(int kl) {
	switch(kl){
		case FuncNode.KLAMMERUNG_ALLES:
			getKlammerungCheckbox(0).setState(true); break;
		case FuncNode.KLAMMERUNG_MITTEL:
			getKlammerungCheckbox(1).setState(true); break;
		case FuncNode.KLAMMERUNG_WENIG:
			getKlammerungCheckbox(2).setState(true); break;
	}
}
/**
 * 
 * @return boolean
 */
boolean setzeFormel() {

	boolean b = true;
	// Rueckwaerts abarbeiten, damit die oberste falsche Formel
	// fokussiert ist
	for (int index=FormelField.length-1; index>=0; index--){
		b = b && setzeFormel(index);
	}
	return b;
}

/**
 * Setzt die Formel des Anzeigefensters, setzt auch den Parameter p.
 * Wenn p fehlerhaft ist, wird p auf 0 gesetzt.
 * Wenn die Formel fehlerhaft ist, wird die Formel fokussiert und false
 * geliefert.
 */
private boolean setzeFormel(int index) {
	if (!setzeP()) return false;
	if (!setzeQ()) return false;

	if (flaeche==null) return true;
	TextField f = getFormelField(index);

	if (flaeche.setFormula(index, f.getText(),
		getPostfixCheckbox().getState())){
		return true;
	}else{
		f.requestFocus();
		f.selectAll();
		return false;
	}
}
/**
 * 
 */
private boolean setzeP() {
	double p = 0;
	try{
		p = new Double(getPField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getPField().requestFocus();
		getPField().selectAll();
		return false;
	}
	if (flaeche!=null)
		flaeche.setP(p);
	return true;
}
/**
 * 
 */
private boolean setzeQ() {
	double q = 0;
	try{
		q = new Double(getQField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getQField().requestFocus();
		getQField().selectAll();
		return false;
	}
	if (flaeche!=null)
		flaeche.setQ(q);
	return true;
}
/**
 * 
 */
private boolean setzeT() {
	double tstart, tstop;
	long tstep;
	int Xi, Yi;

	try{
		tstart = new Double(getTStartField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getTStartField().requestFocus();
		getTStartField().selectAll();
		return false;
	}

	try{
		tstop = new Double(getTStopField().getText()).doubleValue();
	}catch(NumberFormatException exc){
		getTStopField().requestFocus();
		getTStopField().selectAll();
		return false;
	}

	try{
		tstep = new Long(getTStepField().getText()).longValue();
	}catch(NumberFormatException exc){
		getTStepField().requestFocus();
		getTStepField().selectAll();
		return false;
	}

	Xi = getXKoordChoice().getSelectedIndex()-1;
	Yi = getYKoordChoice().getSelectedIndex()-1;

	if (flaeche!=null)
		flaeche.setT(tstart, tstop, tstep, Xi, Yi);
	return true;
}
/**
 * Zeigt das Dialogfenster an. Beim ersten anzeigen wird das
 * erste Formelfeld fokussiert.
 */
public void show() {
	boolean first = !isVisible();
	super.show();
	if (first){
		TextField f = getFormelField(0);
		f.requestFocus();
		f.setCaretPosition(f.getText().length());
	}
}
/**
 * 
 * @return boolean
 */
public boolean wantExtended() {
	return wantExtended;
}
}