package lsystem;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
/**
 * Lindenmayer-System <br>
 * Belegarbeit AlgoDat WS99/SS2000, Aufgabe 8
 * <p>
 * Panel, welches LSystemChoice-Objekte verwaltet.
 *
 * @author Christian Semrau<br>
 * Christian.Semrau@student.uni-magdeburg.de<br>
 */
public class LSystemChoiceGroup extends Panel implements ItemListener {
	/** die einzelnen Choices */
	Hashtable choices;
	/** die aktuell ausgewaehlte Choice */
	LSystemChoice aktChoice;
	/** die Choice, die zur Auswahl der Choices dient */
	Choice selecter;
	/** das Kontroll-Panel */
	LSystemControls controls;
/**
 * Legt eine leere ChoiceGroup an.
 */
public LSystemChoiceGroup(LSystemControls con, Choice sel) {
	super();
	setLayout(new CardLayout(5,5));

	choices = new Hashtable();
	aktChoice = null;
	selecter = sel;
	controls = con;
	selecter.addItemListener(this);
}
/**
 * Fuegt eine LSystemChoice hinzu.
 * @param LSC belegLsystem.LSystemChoice
 */
private void addChoice(LSystemChoice LSC) {
	choices.put(LSC.Name, LSC);
	add(LSC.Name, LSC);
	LSC.addItemListener(this);
	selecter.addItem(LSC.Name);
//	selecter.invalidate(); // selecter wird automatisch vergroessert, warum auch immer
}
/**
 * Fuegt ein LSystem in die gewuenschte Choice ein.
 * Die Choice wird ggf. neu angelegt.
 * @param gr java.lang.String
 * @param LS belegLsystem.LSystem
 */
public void addLSystem(String gr, LSystem LS) {
	if (gr==null||gr.length()<=0) gr="default";
	LSystemChoice LSC = getChoice(gr);
	LSC.addLSystem(LS);
}
/**
 * 
 */
public void copyToTextFields() {
	controls.copyLSystemToTextFields(getSelectedLSystem());
}
/**
 * Liefert die LSystemChoice mit dem gesuchten Namen. Es wird gegebenenfalls
 * eine neue angelegt.
 * @return belegLsystem.LSystemChoice
 * @param name java.lang.String
 */
public LSystemChoice getChoice(String name) {
	LSystemChoice LSC = (LSystemChoice)choices.get(name);
	if (LSC==null) {
		LSC = new LSystemChoice(name);
		addChoice(LSC);
	}
	return LSC;
}
/**
 * Liefert das ausgewaehlte LSystem der aktuellen Choice. Liefert null,
 * wenn keine Choice ausgewaehlt ist.
 * @return belegLsystem2.LSystem
 */
public LSystem getSelectedLSystem() {
	if (aktChoice==null) return null;
	return aktChoice.getSelectedLSystem();
}
/**
 * Reagiert auf ItemEvents der Choices und des <code>selecter</code>.
 * @param event java.awt.event.ItemEvent
 */
public void itemStateChanged(ItemEvent event) {
	ItemSelectable source = event.getItemSelectable();
	
	if (source==selecter){
		String arg = (String)event.getItem();
		this.selectChoice(arg);
		copyToTextFields();
	}else
	if (source==this.aktChoice){
		copyToTextFields();
	}
}
/**
 * Liefert einen String mit allen Choices.
 * @return java.lang.String
 */
public String listLSystems() {
	StringBuffer sb = new StringBuffer();
	for(Enumeration gr = choices.elements(); gr.hasMoreElements(); ){
		LSystemChoice Gr = (LSystemChoice)gr.nextElement();
		sb.append(Gr.listLSystems());
	}
	return sb.toString();
}
/**
 * Entfernt eine Choice aus der ChoiceGroup.
 * Wenn aber nur noch eine Choice vorhanden ist, wird diese NICHT entfernt!
 * @param LSC belegLsystem2.LSystemChoice
 */
public void removeChoice(LSystemChoice LSC) {
	if (choices.size()>1){
		// nur entfernen, wenn mehr als eine da ist
		LSC.removeItemListener(this);
		selecter.remove(LSC.Name);
		choices.remove(LSC.Name);
		selectChoice(selecter.getSelectedItem());
		remove(LSC);
	}
}
/**
 * Entfernt das gewuenschte LSystem aus der angegebenen Choice.
 * @param gr java.lang.String
 * @param name java.lang.String
 */
public void removeLSystem(String gr, String name) {
	if (gr==null||gr.length()<=0) gr="default";
	LSystemChoice LSC = (LSystemChoice)choices.get(gr);
	if (LSC!=null){
		LSC.removeLSystem(name);
		if (LSC.getItemCount()<=0){
			// wenn die Choice leer ist, wird sie entfernt
			removeChoice(LSC);
		}
		copyToTextFields();
	}
}
/**
 * Ersetzt das LSystem in der gewuenschten Choice.
 * @param gr java.lang.String
 * @param LS belegLsystem.LSystem
 */
public void replaceLSystem(String gr, LSystem LS) {
	if (gr==null||gr.length()<=0) gr="default";
	LSystemChoice LSC = getChoice(gr);
	LSC.replaceLSystem(LS);

	// wenn das zu ersetzende LSystem gerade ausgewaehlt ist,
	// muessen die TextFields aktualisiert werden
	LSystem L = getSelectedLSystem();
	if (L!=null && L.compareName(LS.getName())==0){
		controls.copyLSystemToTextFields(L);
	}
}
/**
 * Waehlt eine Choice aus und zeigt sie an.
 * @param name java.lang.String
 */
public void selectChoice(String name) throws IllegalArgumentException {
	if (name==null)
		throw new IllegalArgumentException("name==null");
	Object o = choices.get(name);
	if (o!=null){
		aktChoice = (LSystemChoice)o;
		selecter.select(name);
		((CardLayout)getLayout()).show(this, name);
	}else
		throw new IllegalArgumentException("nicht gefunden: "+name);
}
/**
 * Waehlt die erste Choice aus. Wenn keine Choice existiert, wird eine
 * default-Choice neu angelegt und ausgewaehlt.
 */
public void selectFirst() {
	if (selecter.getItemCount()>0)
		selectChoice(selecter.getItem(0));
	else{
		selectChoice(getChoice("default").Name);
	}
}
}