package graph;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

/**
 * Diese Klasse Knoten definiert einen Knoten.
 * Knoten haben eine Position, eine Farbe und einen Wert für sonstige Codierungszwecke und sind markiert und/oder besucht.
 * Im Infotext kann eine zusätzliche Information für die Anzeige gespeichert werden.
 * 
 * @author Dirk Zechnall, Thomas Schaller
 * @version 28.02.2023 (v7.0)
 * v7.0: Die Knoteninformationen werden in einer Hashmap gespeichert. Daher können beliebige weitere Informationen abgelegt werden.
 */
public class Knoten extends GraphElement
{


    private int x;
    private int y;

    /**
     * Der Konstruktor erstellt einen neuen Knoten mit einem neuen Namen
     *
     * @param  x  x-Position des Knotens
     * @param  y  y-Position des Knotens
     */
    public Knoten(int x, int y) {
        this(x,y,0);
    }

    /**
     * Der Konstruktor erstellt einen neuen Knoten mit einem Startwert
     *
     * @param  x  x-Position des Knotens
     * @param  y  y-Position des Knotens    
     * @param  neuerWert  Der neue Wert des Knotens 
     */
    public Knoten(int x, int y, double neuerWert) {
        super();
        this.x = x;
        this.y = y;
        set("Wert",neuerWert);
        set("Markiert", false);
        set("Geloescht", false);
        set("Farbe", -1);
        setSortierkriterium("Wert");
    }

    /**
     * Die Methode init initialisiert den Zustand eines Knotens
     */
    protected void init() {
        set("Wert", 0.0);
        set("Farbe", -1);
        set("Markiert", false);
        set("Besucht", false);
    }

    /** 
     * Liefert einen kurzen Text, der den Wert des Knotens angibt und innerhalb der Kreises 
     * des Knotens angezeigt werden kann.
     * @return Array von Anzeigezeilen (dürfen max. 2 sein)
     */
    public List<String> getKurztext(String[] namen) {
        int l = Math.min(namen.length,2);
        List<String> t = new ArrayList<String>();
        for(int i = 0; i<l; i++) {
            String text = getString(namen[i]);
            if(text.length()>3)
                t.add(text.substring(0,3));
            else
                t.add(text);
        }
        return t;
    }

    /**
     * Liefert eine ausführliche Beschreibung der Werte des Knoten. Wird in dem Tooltext Fenster
     * angezeigt, wenn man mit der Maus über den Knoten geht.
     * @return Array von Anzeigezeilen
     */
    public List<String> getLangtext(String[] namen) {
        int l = namen.length;
        List<String> t = new ArrayList<String>();
        t.add("Knoten Nr. "+g.getNummer(this));
        for(int i = 0; i<l; i++) {
            String w =getString(namen[i]);
            if(!w.isEmpty())
                t.add(namen[i]+": "+w);
        }
        return t;
    }


    /** Setzt den Infotext für einen Knoten
     * @param infotext Der neue Text
     */
    public void setInfotext(String infotext) {
        set("Infotext", infotext);
    }

    /** Liefert den Infotext des Knotens
     * @return Der Infotext
     */
    public String getInfotext(){
        return getString("Infotext");
    }

    /**
     * Setzt den Wert beim Knoten
     *
     * @param  neuerWert  Der neu zu setzende Wert
     */
    public void setWert(double neuerWert) {
        set("Wert", neuerWert);
    }

    /**
     * Gibt den Wert vom Knoten als Integer-Wert zurueck
     * 
     * @return  Wert des Knotens
     */
    public int getIntWert() {
        return getInt("Wert");
    }

    /**
     * Gibt den Wert vom Knoten als Double-Wert zurueck
     * 
     * @return  Wert des Knotens
     */    
    public double getDoubleWert() {
        return getDouble("Wert");
    }

    /**
     * Setzt das Markiertattribut vom Knoten
     *
     * @param  markiert  Der neu zu setzende Markiertwert
     */
    public void setMarkiert(boolean markiert) {
        set("Markiert", markiert);
    }

    /**
     * Gibt den Markiertwert vom Knoten zurueck
     * 
     * @return  markiert?
     */
    public boolean isMarkiert() {
        return getBoolean("Markiert");
    }

    /**
     * Setzt das Besuchtattribut vom Knoten
     *
     * @param  markiert  Der neu zu setzende Besuchtwert
     */
    public void setBesucht(boolean besucht) {
        set("Besucht",besucht);
    }

    /**
     * Gibt den Besuchtwert vom Knoten zurueck
     * 
     * @return  besucht?
     */
    public boolean isBesucht() {
        return getBoolean("Besucht");
    }

    /**
     * Gibt den Index der Farbe des Knoten zurück.
     * Standardmäßig hängt die Farbe von den Attributen markiert und besucht ab.
     * Durch Setzen der Farbe kann die Farbe gezielt gesetzt werden.
     * @return Farbe des Knotens
     */
    public int getFarbe() {
        if (getInt("Farbe") == -1) {
            int f = 0;
            if(isMarkiert()) {
                f += 1;
            }
            if(isBesucht()) {
                f += 2;
            }
            return f;
        }
        return getInt("Farbe");
    }

    /**
     * Setzt den Index der Farbe des Knoten.
     * Standardmäßig hängt die Farbe von den Attributen markiert, besucht und beendet ab.
     * Durch Setzen der Farbe kann die Farbe gezielt gesetzt werden.
     * @param farbe Index der Farbe (0-19)
     */

    public void setFarbe(int farbe) {
        set("Farbe",farbe);
    }

    /** Gibt zurück, ob die Knotenfarbe automatisch aus den Attributen ermittelt wird.
     * @return true=Farbe wird automatisch bestimmt, false=Farbe wurde explizit gesetzt.

     */
    public boolean isFarbeAutomatisch() {
        return getInt("Farbe") == -1;
    }

    /** Legt fest, ob die Knotenfarbe automatisch aus den Attributen ermittelt wird.
     * @param auto true=Farbe wird automatisch bestimmt,
     *             false=Farbe wird explizit gesetzt.
     */
    public void setFarbeAutomatisch(boolean auto) {
        if(auto) {
            set("Farbe", -1);
        } else {
            if(isFarbeAutomatisch()) set("Farbe", 0);
        }
    }

    /** Liefert die x-Position des Knotens
     * @return x-Postion
     */
    public int getX() {
        return x;
    }

    /** Liefert die y-Position des Knotens
     * @return y-Postion
     */
    public int getY() {
        return y;
    }

    /** Setzt die x-Position des Knotens
     * @param x x-Postion
     */
    public void setX(int x) {
        this.x = x;
    }

    /** Setzt die y-Position des Knotens
     * @param y y-Postion
     */   
    public void setY(int y) {
        this.y = y;
    }

    /**
     * Die Methode ueberschreibt die Methode toString() und gibt die String-Raepraesentation eines Knotens zurueck
     * 
     * @return      String-Raepraesentation des Knotens
     */
    @Override
    public String toString() {
        
        return getStatus();
    }
}
