// Clock.java -- Matt Mahoney, mmahoney@cs.fit.edu

// Ten aplet wyświetla zegar analogowy wskazujący bieżącą godzinę.
// Jest to ilustracja użycia apletów, wątków i animacji oraz obsługi zdarzeń.

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;

// Wątek Timer wymusza odświeżanie ekranu co jedną sekundę
class Timer extends Thread {
  private Applet applet;

  public Timer(Applet applet) {
    this.applet=applet;
  }

  // Odświeżanie ekranu przez aplet co jedną sekundę
  public void run() {
    while (true) {
      try {
        sleep(1000);
      }
      catch (InterruptedException x) {}
      applet.repaint();
    }
  }
}

// Aplet Clock wyświetla bieżącą godzinę
public class Clock extends Applet {
  private Timer timer;  // Wątek odświeżający ekran co jedną sekundę
  private Image image;  // Rysunek pozwalający usunąć drgania
  private Graphics g2;  // Grafika dla tego rysunku

  // Inicjalizacja
  public void init() {
    setBackground(Color.white);
    timer=new Timer(this);
    timer.start();
    image=createImage(getSize().width, getSize().height);
    g2=image.getGraphics();

    // Aplet Catch do obsługi zdarzeń (zwykle tylko w appletviewer)
    addComponentListener(new ComponentAdapter() {

      // Aktualizacja wielkości obiektu graficznego g2
      public void componentResized(ComponentEvent e) {
        g2.dispose();
        image=createImage(e.getComponent().getSize().width,
          e.getComponent().getSize().height);
        g2=image.getGraphics();
      }
    });
  }

  public synchronized void update(Graphics g) {
    g2.setColor(getBackground());
    g2.fillRect(0, 0, getSize().width, getSize().height);
    g2.setColor(getForeground());
    paint(g);
  }

  // Rysowanie zegara
  public void paint(Graphics g) {

    // Rysowanie tarczy zegara poza ekranem
    g2.setColor(Color.blue);
    g2.drawOval(1, 1, image.getWidth(this)-2, image.getHeight(this)-2);
    for (int i=0; i<360; i+=30)
      drawRadius(0.9, 1.0, i);  // takty

    // Uzyskanie czasu i rysowanie wskazówek poza ekranem
    Calendar rightNow = Calendar.getInstance();;
    g2.setColor(Color.black);
    drawRadius(0, 0.7, rightNow.get(Calendar.SECOND)*6);  // Druga wskazów
    drawRadius(0, 0.8, rightNow.get(Calendar.MINUTE)*6+rightNow.get(Calendar.SECOND)/10);  // Minuty
    for (int i=-2; i<=2; ++i)  // Wskazówka godzin (5 razy grubsza od innych)
      drawRadius(0, 0.5, rightNow.get(Calendar.HOUR_OF_DAY)*30+rightNow.get(Calendar.MINUTE)/2+i);

    // Zastąpienie obrazu na ekranie
    g.drawImage(image, 0, 0, this);
  }

  // Narysowanie linii od środka rysunku począwszy od promienia r1
  private void drawRadius(double r1, double r2, int degrees) {
    int x0=image.getWidth(this)/2;  // środek
    int y0=image.getHeight(this)/2;
    double radians=(degrees-90)*2*Math.PI/360;  // 0 deg = 12:00
    double xr=Math.cos(radians);
    double yr=Math.sin(radians);
    int xr1=(int)(x0*xr*r1);  // punkty końcowe linii są relatywne do środka
    int yr1=(int)(y0*yr*r1);
    int xr2=(int)(x0*xr*r2);
    int yr2=(int)(y0*yr*r2);
    g2.drawLine(x0+xr1, y0+yr1, x0+xr2, y0+yr2);
  }

  // Usunięcie g2
  public void destroy() {
    g2.dispose();
  }
}
