/*
* Datei: DarstellungsModusEA.java
* Autor(en): Lukas K�nig
* Java-Version: 6.0
* Erstellt (vor): 24.10.2008
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/
package fmg.fmg8.graphVis.darstellungsModi;
import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.Transition;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.graphVis.DargestellterGraph;
import fmg.fmg8.graphVis.graph.Graph;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.umgebung2D.Vektor2D;
import java.awt.Polygon;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Darstellungsmodus f�r die Darstellung eines Graphen, der einen endlichen
* Automaten beschreibt.
*
* Bitte beachten: Wenn die Darstellung von der Festplatte geladen wird, dann
* bewirken �nderungen an der Autoanordnung m�glicherweise
* nicht den gew�nschten Effekt. In diesem Fall m�ssen die
* Koordinatendateien gel�scht werden.
*
* @author Lukas K�nig
*
*/
public class DarstModEA implements DarstellungsKit,
Serializable {
/**
* Die Serial Version ID (generiert am 25. April 2007).
*/
private static final long serialVersionUID = -1466446020836015270L;
/**
* Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
private int links;
/**
* Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
private int oben;
/**
* Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
private int rechts;
/**
* Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
private int unten;
/**
* Die bereits positionierten Knoten.
*/
private HashMap<Integer, Vektor2D> gesetzteKn;
/**
* Standard-Konstruktor.
*
* @param li Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param ob Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param re Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param un Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
public DarstModEA(final int li,
final int ob,
final int re,
final int un) {
this.setAusd(li, ob, re, un);
this.gesetzteKn = new HashMap<Integer, Vektor2D>();
}
/**
* Setzt die Eckpunkte der Darstellung.
*
* @param li Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param ob Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param re Eckpunkt des Rahmens, in dem gezeichnet werden darf.
* @param un Eckpunkt des Rahmens, in dem gezeichnet werden darf.
*/
public void setAusd(final int li,
final int ob,
final int re,
final int un) {
int radius = (int) (
fmg.fmg8.graphVis.zeichenModi.Konstanten.KN_DURCHM / 2);
this.links = li + radius;
this.rechts = re - radius;
this.oben = ob;
this.unten = un - radius;
}
/**
* Setzt einen Knoten mit Beschriftungen auf eine Position.
*
* @param k Der Knoten.
* @param d Die Graphdarstellung.
* @param x Die X-Koordinate.
* @param y Die Y-Koordinate.
* @param ausg Der Ausgangsknoten.
*
* @return Die neue Graphdarstellung.
*/
private DargestellterGraph setzeKnoten(final Knoten k,
final DargestellterGraph d,
final int x,
final int y,
final Knoten ausg) {
d.hinzuKnoten(x, y, k, k == ausg);
d.hinzuBeschr(x - 11,
y - 10,
k.holeName().toString());
d.hinzuBeschr(x - 18,
y + 5,
"("
+ ((ZInfo) k.getInfo()).getAlter()
+ ")");
d.hinzuBeschr(x - 18,
y + 19,
"" + ((ZInfo) k.getInfo()).getAktion()
+ "-"
+ ((ZInfo) k.getInfo()).getParam(),
new Polygon());
return null;
}
/**
* Erzeugt eine Darstellung eines Graphen.
*
* @param g Der darzustellende Graph.
* @param ausgKn Der Name des Knotens, von dem die Zeichnung
* ausgehen soll. Dieser Knoten wird auf der
* Y-Achse platziert.
*
* @return Darstellung des Graphen g.
*/
public DargestellterGraph erzeuge(final EndlicherAutomat g,
final Object ausgKn) {
DargestellterGraph darstellung = new DargestellterGraph();
Iterator<Knoten> it;
Iterator<Knoten> it1;
Iterator<Integer> it2;
Iterator<Transition> it3;
Knoten knot;
Knoten knot1;
Knoten knot2;
Vektor2D koord1;
Vektor2D koord2;
if (!g.istLeer()) {
final ArrayList<Knoten> knotenListe
= new ArrayList<Knoten>(g.holAdj().values());
int knAnzahl = knotenListe.size();
if (knAnzahl < 2) {
knAnzahl = 2;
}
int gitterX = Math.abs(this.rechts - this.links)
/ (int) ((Math.ceil(Math.sqrt(knAnzahl))) - 1);
int gitterY = Math.abs(this.unten - this.oben)
/ (int) ((Math.ceil(Math.sqrt(knAnzahl))) - 1);
int koordX = this.links;
int koordY = this.oben;
int kX;
int kY;
Transition bed;
int folgeZustand;
String bedingung;
int xAusgleich;
int zaehler = 0;
// Knoten
it = knotenListe.iterator();
while (it.hasNext()) {
knot = it.next();
if (this.gesetzteKn.containsKey(knot.holeName())) {
kX = (int) this.gesetzteKn.get(knot.holeName()).x;
kY = (int) this.gesetzteKn.get(knot.holeName()).y;
this.setzeKnoten(knot,
darstellung,
kX,
kY,
(Knoten) ausgKn);
if (g.istStartZ(knot)) {
darstellung.hinzuPfeil(kX - 60,
kY - 60,
kX - 45,
kY - 45,
0.5,
false);
}
} else {
this.setzeKnoten(knot,
darstellung,
koordX,
koordY,
(Knoten) ausgKn);
this.gesetzteKn.put(knot.holeName(),
new Vektor2D(koordX, koordY));
if (g.istStartZ(knot)) {
darstellung.hinzuPfeil(koordX - 60,
koordY - 60,
koordX - 45,
koordY - 45,
0.5,
false);
}
zaehler++;
if (zaehler < Math.ceil(Math.sqrt(knAnzahl))) {
koordX = koordX + gitterX;
} else {
koordX = this.links;
koordY = koordY + gitterY;
zaehler = 0;
}
}
}
// Kanten
it1 = knotenListe.iterator();
while (it1.hasNext()) {
knot1 = (Knoten) it1.next();
koord1 = (Vektor2D) this.gesetzteKn.get(knot1.holeName());
it2 = (new ArrayList<Integer>(
knot1.holeNachfolger().keySet())).iterator();
while (it2.hasNext()) {
boolean gebogen = true;
knot2 = g.holeKnoten((Integer) it2.next());
koord2 = (Vektor2D) this.gesetzteKn.get(knot2.holeName());
Condition cond
= knot1.getInfo().getTransZuZustand(
knot2.holeName()).get(0).getCond();
double staerke = SonstMeth.condStrength(cond,
Konstanten.STAERKE_ERST,
Konstanten.STAERKE_ZWEIT);
if (koord1.distanz(koord2) < 140
&& !koord1.equals(koord2)) {
gebogen = false;
}
darstellung.hinzuPfeil(
(int) koord1.x,
(int) koord1.y,
(int) koord2.x,
(int) koord2.y,
staerke,
gebogen);
}
}
// Kantenbeschriftungen
it1 = knotenListe.iterator();
while (it1.hasNext()) {
int kantAlter;
knot1 = (Knoten) it1.next();
koord1 = this.gesetzteKn.get(knot1.holeName());
it3 = ((ZInfo)
knot1.getInfo()).getBeds().iterator();
while (it3.hasNext()) {
Polygon p = new Polygon();
bed = it3.next();
folgeZustand = bed.getFolgezustand();
kantAlter = bed.getAlter();
bedingung = bed.getCond().toString();
knot2 = g.holeKnoten(new Integer(folgeZustand));
koord2 = this.gesetzteKn.get(knot2.holeName());
p.addPoint((int) koord1.x, (int) koord1.y);
p.addPoint((int) koord2.x, (int) koord2.y);
if (koord1.equals(koord2)) {
xAusgleich = 95;
} else {
xAusgleich = 0;
}
darstellung.hinzuBeschr((int) ((koord1.x + koord2.x) / 2)
+ xAusgleich,
(int) ((koord1.y + koord2.y) / 2),
bedingung + " (" + kantAlter + ")",
p);
}
}
}
return darstellung;
}
/**
* Erzeugt einen Hintergrund und gibt ihn zur�ck.
*
* @return Eine Polygonliste als Hintergrund f�r die Darstellung.
*/
public List<Polygon> hintergrund() {
return new LinkedList<Polygon>();
}
/**
* Weist einem Knoten eine feste Koordinate zu.
*
* @param knoten Der Name des Knotens, dem eine Koordinate zugewiesen
* werden soll.
* @param x X-Koordinate.
* @param y Y-Koordinate.
*/
public void neueKoord(final Knoten knoten, final int x, final int y) {
Vektor2D koord;
if (this.gesetzteKn.containsKey(knoten.holeName())) {
koord = this.gesetzteKn.get(knoten.holeName());
koord.x = x;
koord.y = y;
} else {
this.gesetzteKn.put(knoten.holeName(), new Vektor2D(x, y));
}
}
/**
* L�scht alle zugewiesenen Knoten-Koordinaten. Beim n�chsten Lauf von
* <code>this.erzeuge</code> wird wieder die Standardverteilung der
* Knoten generiert.
*/
public void loescheKnotenKoord() {
this.gesetzteKn.clear();
}
/**
* Gibt die Anzahl der Ebenen zur�ck, die mit dem aktuellen Darstellungs-
* Objekt dargestellt werden. (In der Version f�r den endlichen Automaten
* spielt diese Methode keine Rolle.)
*
* @return Die Anzahl der Ebenen, die this darstellt.
*/
public int holeEbenen() {
return 0;
}
/**
* Gibt eine Identifikation der Klasse als Textausgabe zur�ck.
*
* @return Eine Textausgabe zur Identifikation der Klasse.
*/
public String toString() {
return Messages.getString(
"DarstellungsModusEA.StandardDarstellungEA1");
}
/**
* @return Returns the gesetzteKn.
*/
public HashMap<Integer, Vektor2D> getGesetzteKn() {
return this.gesetzteKn;
}
/**
* Setzt die gesetzten Knoten.
*
* @param gesKn The gesetzteKn to set.
*/
public void setGesetzteKn(final HashMap<Integer, Vektor2D> gesKn) {
this.gesetzteKn = gesKn;
}
/**
* @param g Der Graph, der dargestellt wird.
* @param ausgKn Ausgangsknoten, mit dem bei der Zeichnung
* begonnen wird.
*
* @return Darstellung des Graphen.
*/
@Override
public DargestellterGraph erzeuge(final Graph g, final Object ausgKn) {
if (g.getClass() == EndlicherAutomat.class) {
return this.erzeuge((EndlicherAutomat) g, ausgKn);
}
return null;
}
}