import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;

/** Analoganzeige fuer das Uhrenprogramm
  **/
public class AnalogAnzeige_2 extends JPanel implements Anzeige {
  
  /** Dieses Uhrwerk wird fuer die Zeitdarstellung verwendet. */
  private Uhrwerk uhrwerk;
  
  /** Die darzustellenden Stunden (0-11) */
  private int stunden;
  
  /** Die darzustellenden Minuten (0-59) */
  private int minuten;
  
  /** Die darzustellenden Sekunden (0-59) */
  private int sekunden;
  
  /** Ist es nachmittags (PM) ? */
  private boolean zeigePM;
  
  /** Konstruktor */
  public AnalogAnzeige_2() {
    // Veraendere das Aussehen 
    setBackground(Color.BLACK);
    setForeground(Color.GREEN);
    // Sorge dafuer, dass die Komponente
    // eine gewisse bevorzugte Groesse hat
    setPreferredSize(new Dimension(200,200));
  }
  
  /** Nennt der Anzeige das Uhrwerk, das verwendet werden
    * soll.
    * @param uhr das zu verwendende Uhrwerk
    **/
  public void setUhrwerk(Uhrwerk uhr) {
    uhrwerk = uhr;
  }
  
  /** Weist die Anzeige an, die aktuelle Uhrzeit aus dem
    * Uhrwerk auszulesen und darzustellen.
    **/
  public void zeigeZeit() {
    // Extrahiere Stunden, Minuten und Sekunden
    Date date = uhrwerk.getZeit();
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(date);
    stunden = calendar.get(Calendar.HOUR);
    minuten = calendar.get(Calendar.MINUTE);
    sekunden = calendar.get(Calendar.SECOND);
    zeigePM = calendar.get(Calendar.AM_PM) == Calendar.PM;
    // Dann rufe die repaint-Methode auf
    repaint();
  }  
  
  /** Hilfsmethode: setzt die Liniendicke in einem
    * Graphics-Objekt auf X Pixel
    **/
  private void setzeBreite(Graphics g,int breite,boolean rundeEnden) {
  }
  
  /** Hilfsmethode: zeichnet eine Linie vom Zentrum
    * des Bildes zum Rand des Kreises. 
    * @param g das zum Zeichnen zu verwendende
    *  Graphics-Objekt
    * @param mitteX die X-Koordinate des Mittelpunktes
    * @param mitteY die Y-Koordinate des Mittelpunktes
    * @param winkel der zu verwendende Winkel
    *  im Bogenmass
    *  (360 Grad = 2*Math.PI)
    * @param radius der Radius des Kreises
    * @param von bei wie viel Prozent der Strecke
    *   Uhrsprung/Kreisbogen fangen wir zu zeichnen an?
    *  (100 Prozent = 1)
    * @param bis bei wie viel Prozent der Strecke
    *   Uhrsprung/Kreisbogen hoeren wir zu zeichnen auf?
    *  (100 Prozent = 1)
    **/
  private void zeichneLinie(Graphics g,int mitteX,
    int mitteY,double winkel,int radius,double von,double bis) {
  }
  
  /** Hilfsmethode: berechne den Winkel des Stundenzeigers 
    * fuer eine gegebene Uhrzeit.
    **/
  private double stundenWinkel(int stunde,int minute,int sekunde) {
    return 2 * Math.PI * (sekunde + minute * 60 + stunde * 3600) 
      / (3600 * 12);
  }
  
  /** Hilfsmethode: berechne den Winkel des Minutenzeigers
    * fuer eine gegebene Uhrzeit.
    **/
  private double minutenWinkel(int minute,int sekunde) {
    return 2 * Math.PI * (sekunde + minute * 60) /3600;
  }
  
  /** Hilfsmethode: berechne den Winkel des Sekundenzeigers
    * fuer eine gegebene Uhrzeit.
    **/
  private double sekundenWinkel(int sekunde) {
    return 2 * Math.PI * sekunde / 60;
  }  
  
  /** Malt die Uhr auf dem Bildschirm */
  public void paint(Graphics graphics) {
    // Zeichne nicht direkt auf dem Bildschirm, sondern
    // verwende ein so genanntes Offscreen-Image
    int width = getWidth();
    int height = getHeight();
    Image bild = createImage(width,height);
    Graphics g = bild.getGraphics();
    // Berechne den Mittelpunkt unseres Uhrenkreises
    int mitteX = width/2;
    int mitteY = height/2;
    int radius = Math.min(width,height) / 2 - 10;
    // Zuerst einmal malen wir den Hintergrund
    g.setColor(getBackground());
    g.fillRect(0,0,width,height);    
    // Nun zum Zifferblatt
    setzeBreite(g,4,false);
    g.setColor(getForeground());
    g.drawOval(mitteX - radius, mitteY - radius,
      2 * radius, 2 * radius);
    for (int i = 0; i < 12; i++)
      zeichneLinie(g,mitteX,mitteY,stundenWinkel(i,0,0),
        radius,0.75,1);
    // Zeichne den Stundenzeiger
    setzeBreite(g,9,true);
    zeichneLinie(g,mitteX,mitteY,
      stundenWinkel(stunden,minuten,sekunden),radius,0,0.5);
    // Zeichne den Minutenzeiger
    zeichneLinie(g,mitteX,mitteY,
      minutenWinkel(minuten,sekunden),radius,0,0.9);
    // Zeichne den Sekundenzeiger
    setzeBreite(g,2,true);
    zeichneLinie(g,mitteX,mitteY,
      sekundenWinkel(sekunden),radius,0,0.9);    
    // Im Falle von "PM", zeige einen kleinen Punkt an
    if (zeigePM)
      g.fillOval(width - 20, height - 20 , 10 , 10);
    // Zu guter Letzt zeichnen wir das Offscreen-Image
    // in der wirklichen Komponente
    graphics.drawImage(bild,0,0,this);
  }
  
}
