import java.awt.Color;

/**
 * Repräsentiert einen Punkt im RGB-Raum
 * 
 * @author Alexander Kimmig 
 * @version 1.0
 */
public class RGB
{
    /**
     * Rot-Anteil 0-255
     */
    public int r;
    
    /**
     * Grün-Anteil 0-255
     */
    public int g;
    
    /**
     * Blau-Anteil 0-255
     */
    public int b;
    
    /**
     * Wie weit ist der Punkt in der letzten Epoche gelaufen
     */
    public int walk;
    
    /**
     * Wie oft ist der Punkt in der letzten Epoche gelaufen
     */
    public int count;
    
    /**
     * Konstruktor
     * 
     * @param random Punkt zufällig setzen
     */
    public RGB(boolean random) {
        this(0, 0, 0);
        
        if (random) this.setRandom();
    }
    
    /**
     * Konstruktor
     * 
     * @param c ein awt.Color-Wert
     */
    public RGB(Color c) {
        this(c.getRed(), c.getGreen(), c.getBlue());
    }
    
    /**
     * Konstruktor
     * 
     * @param c ein int-Wert 0xRRGGBB
     */
    public RGB(int c) {
        this(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF);
    }

    /**
     * Konstruktor
     * 
     * @param r Rot-Anteil 0-255
     * @param g Grün-Anteil 0-255
     * @param b Blau-Anteil 0-255
     */
    public RGB(int r, int g, int b) {
        this.r = Math.min(255, Math.max(0, r));
        this.g = Math.min(255, Math.max(0, g));
        this.b = Math.min(255, Math.max(0, b));
        
        this.walk = 0;
        this.count = 0;
    }
    
    /**
     * Kopier-Konstruktor
     */
    public RGB(RGB copy) {
        this(copy.r, copy.g, copy.b);
    }
    
    /**
     * Ausgabe als String
     * 
     * @return String: "R, G, B"
     */
    public String toString() {
        return this.r + "," + this.g + "," + this.b;
    }
    
    /**
     * Ausgabe als awt.Color
     * 
     * @return awt.Color
     */
    public Color toColor() {
        return new Color(this.r, this.g, this.b);
    }
    
    /**
     * Ausgabe als int
     */
    public int toInt() {
        return (this.r << 16) + (this.g << 8) + (this.b);
    }
    
    /**
     * Setze zufällige Koordinaten
     */
    public void setRandom() {
        this.r = (int)(Math.random() * 256);
        this.g = (int)(Math.random() * 256);
        this.b = (int)(Math.random() * 256);
    }
    
    /**
     * Setze Koordinaten
     */
    public void setTo(RGB p) {
        this.r = p.r;
        this.g = p.g;
        this.b = p.b;
    }
    
    /**
     * Variiere Koordinaten ±max
     * 
     * @param max maximale verschiebung pro Achse
     */
    public void jitter(int max) {
        this.r = Math.min(255, Math.max(0, this.r + ((int)(Math.random() * max * 2 - max))));
        this.g = Math.min(255, Math.max(0, this.g + ((int)(Math.random() * max * 2 - max))));
        this.b = Math.min(255, Math.max(0, this.b + ((int)(Math.random() * max * 2 - max))));
    }
    
    /**
     * Berechne den quadratischen Abstand zweier Punkte
     * 
     * @param a erster Punkt
     * @param b zweiter Punkt
     */
    public static int diff2(RGB a, RGB b) {
        int dr = a.r - b.r;
        int dg = a.g - b.g;
        int db = a.b - b.b;
        return dr*dr + dg*dg + db*db;
    }
    
    /**
     * Berechne den quadratischen Abstand zu einem anderen Punkt
     */
    public int diff2(RGB b) {
        return RGB.diff2(this, b);
    }
}
