/*
    Ein kleineres Beispiel in der Sprache Java
    Das folgende stellt ein sogenanntes Applet dar, ein Programm, das
    ueber das world wide web (www) verteilt werden kann und mit
    html-Browsern wie z.B. netscape oder appletviewer geladen/gestartet 
    werden kann.
    Applets funktionieren wie andere GUI-programmiertools mit der sogenannten 
    Callback-methode.
    Das heisst, dass fuer ein bestimmtes Ereignis (Event z.B. Tastatur, 
    Fensterneuzeichnen noetig, Mausklick usw.) eine damit verbundene Funktion
    aufgerufen wird. Die Verbindung mit diesen Funktionen funktioniert 
    bei Java-Applets ueber Vererbung.
    Ausserdem benutzt dieses Applet die Java Multitasking-Features, damit
    die Callbacks nicht das Abarbeiten von Events (Eventloop) behindert.

    Das Programm rechnet in der Initialisierung Daten aus,
    die dann spaeter fuer das Zeichnen auf eine Flaeche benutzt werden
    Ausserdem benutzt sie noch ein paar andere interessante Zeichenfunktionen
 */

// Import von fertigen Java-Klassen/Unterprogrammen

// Grundlegende Appletklasse fuer die Eventloop
import java.applet.Applet;    

// Alle Klassen des "applet window toolkit"
import java.awt.*; 

// Mathematische Funktionen
import java.lang.Math;
 

// Die eigene Klasse erbt mit der Applet-Klasse die Funktion
// "paint", der Callback fuer das Neuzeichnen des Fensters
// (ausserdem noch "init" und "start" fuer einen Neustart des Programms)  
// Die Klasse "runnable" stellt die Funktion "run" fuer Threads zur Verfuegung
// die unabhaengig von der Applet-eventloop benutzt wird

public class aimBeispiel extends Applet implements Runnable 
  {
// eigene Daten

// Daten fuer ein gif-bild
  Image gifpicture;
// Fenstergroesse
  int AppletWidth, AppletHeight;
// eigene Daten fuer das Zeichnen auf die Flaeche
  int NUM_POINTS = 100;
  int xPoints[][] = new int[NUM_POINTS][2];
  int yPoints[][] = new int[NUM_POINTS][2];
  int xPolygon[] = new int[4];
  int yPolygon[] = new int[4];
  int NUM_ARCS=60;
  int arc=0;
// Farben fuer das Zeichnen auf die Flaeche
  Color mycolors[] = new Color[NUM_POINTS];
// Daten fuer die Position des letzten Mausklicks
  int mousex=-1;
  int mousey=-1;
// Datentyp fuer das Starten/Stopen eines zweiten Programmtasks
  Thread mytask=null;

// Initialierung
  public void init() 
    {
    double Width1,Height1;
    double Width2,Height2;
    double ElipseWidth,ElipseHeight;
    int i;
    double degree;
    float x,y;

// Daten fuers gifbild einlesen 
    gifpicture=null;
    // getImage ist asynchron, Bild ist erst da vorhanden, wenn gifpicture!=null
    gifpicture = getImage(getDocumentBase(),"maschine.gif");
// Fenstergroesse und Elipsengroesse festlegen
    AppletWidth = size().width;
    if (AppletWidth>300)
       ElipseWidth=300; 
    else
       ElipseWidth=AppletWidth; 
    AppletHeight = size().height;
    if (AppletHeight>=100)
       ElipseHeight=100;
    else
       ElipseHeight=AppletHeight;
// Daten fuer das Zeichnen in "paint" aufbereiten
    // auessere Elipse
    Width1=ElipseWidth-30;
    Height1=ElipseHeight-30;
    // innere Elipse
    Width2=ElipseWidth-40;
    Height2=ElipseHeight-40;
// Punkte fuer Elipsen innerhalb x=-Width1|2...Width1|2 y=-Height1|2...Height1|2
    for (i=0;i<NUM_POINTS;i++)
       {
       // auessere Elipse
       xPoints[i][0] = (int)((Math.sin((i*2*Math.PI)/NUM_POINTS))*Width1/2.0);
       yPoints[i][0] = (int)((Math.cos((i*2*Math.PI)/NUM_POINTS))*Height1/2.0);
       // innere Elipse
       xPoints[i][1] = (int)((Math.sin((i*2*Math.PI)/NUM_POINTS))*Width2/2.0);
       yPoints[i][1] = (int)((Math.cos((i*2*Math.PI)/NUM_POINTS))*Height2/2.0);
       }
// Elipsen kippen
    for (i=0;i<NUM_POINTS;i++)
       {
       degree=7.0/360.0*2*Math.PI;
       x=xPoints[i][0];
       y=yPoints[i][0];
       xPoints[i][0] = (int)( x*Math.cos(degree)+y*Math.sin(degree));
       yPoints[i][0] = (int)(-x*Math.sin(degree)+y*Math.cos(degree));
       x=xPoints[i][1];
       y=yPoints[i][1];
       xPoints[i][1] = (int)( x*Math.cos(degree)+y*Math.sin(degree));
       yPoints[i][1] = (int)(-x*Math.sin(degree)+y*Math.cos(degree));
       }      
// Elipsen in das Fenster verschieben
    for (i=0;i<NUM_POINTS;i++)
       {
       xPoints[i][0] = (int)(xPoints[i][0]+ElipseWidth/2.0);
       yPoints[i][0] = (int)(yPoints[i][0]+ElipseHeight/2.0);
       xPoints[i][1] = (int)(xPoints[i][1]+ElipseWidth/2.0);
       yPoints[i][1] = (int)(yPoints[i][1]+ElipseHeight/2.0);
       }
// Farben definieren 
    for (i=0;i<NUM_POINTS;i++)
       {
       // RGB-Werte
       mycolors[i]=new Color(255,255,(int)((i*255.0)/(2.0*NUM_POINTS)));
       // Ausgabe der Punkte auf stdout (funktioniert nicht mit netscape)
       // System.out.println("start "+i+" "+xPoints[i][0]+" "+yPoints[i][0]
       //                              +" "+xPoints[i][1]+" "+yPoints[i][1]);
       }
    }

// Start des Applets
  public void start() 
    {
// Neuen Task starten
    mytask = new Thread(this);
    mytask.start();
// Fenster neu malen
    repaint();
    }

// Stop des Applets
  public void stop() 
    {
    // diese Zuweisung f"uhrt dazu, da\3 der java-Garbagecollector 
    // den bei start() angeforderten Thread automatisch entsorgt
    mytask = null;
    }

// Starten der Anwendung
 public void run () 
    {
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
// immer wieder Flaeche neuzeichnen, dann warten
    while (true) 
      {
      repaint();
      try 
        {
        Thread.currentThread().sleep(100);
        }
      catch (Exception e) 
        {      
        System.out.println("da war was !");
        }
      }  
    }

// Callback fuer Flaeche neu malen 
  public void paint(Graphics graph) 
    {
    Color mycolor;

// gif-bild malen
   if (gifpicture!=null)
      graph.drawImage(gifpicture,0,60,this); 
// schwarze Farbe setzen
    graph.setColor(Color.black);
// line ziehen
   graph.drawLine(arc,arc,arc+22,arc);
// Text schreiben
    graph.drawString("Java Beispiel",arc,arc);
// rote Farbe setzen
    graph.setColor(Color.red);
// Mausklickposition schreiben
    if (mousex>0)
       graph.drawString("Mausklick bei "+mousex+" "+mousey,AppletWidth/2,10);
// Elipse malen
    for (int i=arc; i < arc+NUM_ARCS; i++) 
      {
      if (i<NUM_POINTS-1)
         {
         // Farbe setzen
         graph.setColor(mycolors[i]);
         // polygonzug besetzen
         xPolygon[0]=xPoints[i][0];
         xPolygon[1]=xPoints[i][1];
         xPolygon[2]=xPoints[i+1][1];
         xPolygon[3]=xPoints[i+1][0];
         yPolygon[0]=yPoints[i][0];
         yPolygon[1]=yPoints[i][1];
         yPolygon[2]=yPoints[i+1][1];
         yPolygon[3]=yPoints[i+1][0];
         }
      else if (i==NUM_POINTS-1)
         {
         // Farbe setzen
         graph.setColor(mycolors[i]);
         // polygonzug besetzen
         xPolygon[0]=xPoints[i][0];
         xPolygon[1]=xPoints[i][1];
         xPolygon[2]=xPoints[0][1];
         xPolygon[3]=xPoints[0][0];
         yPolygon[0]=yPoints[i][0];
         yPolygon[1]=yPoints[i][1];
         yPolygon[2]=yPoints[0][1];
         yPolygon[3]=yPoints[0][0];
         }
      else
         {
         // Farbe setzen
         graph.setColor(mycolors[i-NUM_POINTS]);
         // polygonzug besetzen
         xPolygon[0]=xPoints[i-NUM_POINTS+1][0];
         xPolygon[1]=xPoints[i-NUM_POINTS+1][1];
         xPolygon[2]=xPoints[i-NUM_POINTS][1];
         xPolygon[3]=xPoints[i-NUM_POINTS][0];
         yPolygon[0]=yPoints[i-NUM_POINTS+1][0];
         yPolygon[1]=yPoints[i-NUM_POINTS+1][1];
         yPolygon[2]=yPoints[i-NUM_POINTS][1];
         yPolygon[3]=yPoints[i-NUM_POINTS][0];
         }
      // Gefuelltes Polygon malen
      graph.fillPolygon(xPolygon,yPolygon,4);
      }
    if (arc<NUM_POINTS)
       arc++;
    else
       arc=0;
    }

// callback fuer das Druecken einer Maustaste

  public boolean mouseDown(Event e, int x, int y) 
     {
     mousex=x;
     mousey=y;
     return true;
     }

  } 
