import java.awt.Shape;
import java.awt.geom.AffineTransform;


/**
 * Abstrakte Klasse sichtbaresTeil

 */

public abstract class SichtbaresTeil  
{
  protected int xPosition;
  protected int yPosition;
  protected int orientierung;
  protected String farbe;
  protected boolean istSichtbar;
  protected int breite;
  protected int tiefe;


  /**
   * Bewege dieses Objekt horizontal um 'entfernung' Bildschirmpunkte.
   */
  public void bewegeHorizontal(int entfernung)
  {
    // Bitte programmieren
  }

  /**
   * Bewege dieses objekt vertikal um 'entfernung' Bildschirmpunkte.
   */
  public void bewegeVertikal(int entfernung)
  {
    // Bitte programmieren
  }

 
  
  
  /**
   * Berechnet das zu zeichnende Shape anhand der gegebenen Daten
   * Achtung: Da gibAktuelleFigur() abstrakt definiert ist, muss in
   * jeder Unterklasse eine Methode gibAktuelleFigur() definiert sein!
   * In dieser Methode wird das Aussehen der Figur definiert.
   */
  protected abstract Shape gibAktuelleFigur();
  
  
  
  /**
   * Transformiert das Shape, so dass es die richtige Position
   * und Orientierung einnimmt.
   */
  protected Shape transformiere(Shape shape)
  {
      AffineTransform t1 = new AffineTransform();
      AffineTransform t2 = new AffineTransform();
      t1.translate(xPosition, yPosition);
      t2.rotate(Math.toRadians(orientierung),gibMitteX(),gibMitteY());
      t2.concatenate(t1);
      return  t2.createTransformedShape(shape);
  }
  
  /**
   * Hole die X-Koordinate des Mittelpunktes
   * [ Hilfsfunktion für das Drehen. ]
   */
  protected int gibMitteX()
  {
    return xPosition+breite/2;
  }

  /**
   * Hole die Y-Koordinate des Mittelpunktes
   * [ Hilfsfunktion für das Drehen. ]
   */
  protected int gibMitteY()
  {
    return yPosition+tiefe/2;
  }

  /**
   * Mache dieses Objekt sichtbar. Wenn es bereits sichtbar ist, tue
   * nichts.
   */
  public void zeige()
  {
    istSichtbar = true;
    zeichne();
  }

  /**
   * Mache dieses Objekt unsichtbar. Wenn es bereits unsichtbar ist, tue
   * nichts.
   */
  public void verberge()
  {
    loesche();
    istSichtbar = false;
  }

  /**
   * Drehe auf den angegebenen Winkel
   */
  public void dreheAuf(int neuerWinkel)
  {
     loesche();
     orientierung = neuerWinkel;
     zeichne();
  }

  /**
   * Zeichne dieses Objekt mit seinen aktuellen Werten auf den Bildschirm.
   */
  protected void zeichne()
  {
    if (istSichtbar)
    {
      Shape figur = gibAktuelleFigur();
      Leinwand leinwand = Leinwand.gibLeinwand();
      leinwand.zeichne (
        this,
        farbe,
        figur);
      leinwand.warte(10);
    }
  }

  /**
   * Lösche dieses Objekt vom Bildschirm.
   */
  protected void loesche()
  {
    if (istSichtbar)
    {
      Leinwand leinwand = Leinwand.gibLeinwand();
      leinwand.entferne(this);
    }
  }
}
