import java.awt.*;
import java.applet.*;
import java.awt.event.*;


public class Jouko2 extends Applet implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener
{
  double x = 284;
  double y = 150;
  double xoff = 0;
  double yoff = 0;
  int m,n,o,p,s,t,u,v;
  double a;
  double kreis_a, kreis_b;
  double joukreis_a, joukreis_b;
  double joukreisalt_a, joukreisalt_b;
  double xcross, alfa0, ca, Z;
  int hilfslinien = 0;
  private Image dbImage;
  private Graphics dbg;


  public void init()
  {
    addMouseListener(this);
    addMouseMotionListener(this);
    addMouseWheelListener(this);
    addKeyListener(this);
    setBackground(new java.awt.Color(220,220,220));
    setSize(568,300);
    a = 65.37; xoff = -14; yoff = 10;
    repaint();
  }

  // DoubleBuffering
  public void update (Graphics g)
  {
      if (dbImage == null)
      {
      dbImage = createImage (this.getSize().width, this.getSize().height);
      dbg = dbImage.getGraphics ();
      }
      dbg.setColor (getBackground ());
      dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
      dbg.setColor (getForeground());
      paint (dbg);
      g.drawImage (dbImage, 0, 0, this);
  }

  public void Rechnen ()
  {
    Z = 2*Math.PI*yoff;
    if (xoff<0)
     {xcross = Math.sqrt(6400-Math.pow(yoff,2))+xoff;}
    else
     {xcross = -1*Math.sqrt(6400-Math.pow(yoff,2))+xoff;};
    alfa0 = -1*Math.atan(yoff/(Math.abs(xoff)+Math.abs(xcross)));
    ca = -1*alfa0*2*Math.PI;
    repaint();
  }

  public void Mlinks ()
  {
    xoff = (x-284)/10; yoff = (150-y)/10;
    a = Math.abs(Math.abs(xoff)-Math.sqrt(Math.abs(6400-Math.pow(yoff,2))));
    Rechnen();
  }

  public void Mrechts ()
  {
    xoff = (x-284)/10; yoff = (150-y)/10;
    Rechnen();
  }
  
  public void MMitte ()
  {
    if (a<0) {a=0;};
    Rechnen();
  }
  
  public void Spacetaste ()
  {
    a = Math.abs(Math.abs(xoff)-Math.sqrt(Math.abs(6400-Math.pow(yoff,2))));
    Rechnen();
  }

  public void paint (Graphics g)
  {
    if (hilfslinien == 1)
    {
    // Raster im Hintergrund
    g.setColor(new java.awt.Color(210,210,220));
    for(int i=0; i<29; i++) {g.drawLine(4+i*20,0,4+i*20,300);};
    for(int i=0; i<18; i++) {g.drawLine(0,10+i*20,568,10+i*20);};
    };

    // Gitter - Kreise
    g.setColor(Color.white);
    for(int i=1; i<16; i++)
    {
     for(int j=1; j<50; j++)
     {
     kreis_a = xoff+((80+i*20)*Math.cos(0.131*j));
     kreis_b = yoff+((80+i*20)*Math.sin(0.131*j));
     joukreis_a = kreis_a*(1+(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     joukreis_b = -1*kreis_b*(1-(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     m = (int)Math.round(joukreis_a);
     n = (int)Math.round(joukreis_b);
     if (j==1) {o = m; p = n;};
     g.drawLine(o+284, p+150, m+284, n+150);
     o = m; p = n;
     }
   }

    // Gitter - Strahlen
    for(int i=1; i<89; i++)
    {
     for(int j=1; j<17; j++)
     {
     kreis_a = xoff+((60+j*20)*Math.cos(0.0715*i));
     kreis_b = yoff+((60+j*20)*Math.sin(0.0715*i));
     joukreis_a = kreis_a*(1+(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     joukreis_b = -1*kreis_b*(1-(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     m = (int)Math.round(joukreis_a);
     n = (int)Math.round(joukreis_b);
     if (j==1) {o = m; p = n;};
     g.drawLine(o+284, p+150, m+284, n+150);
     o = m; p = n;
     }
   }

    // Joukowski-Profil
    g.setColor(Color.black);
    for(int i=0; i<90; i++)
    {
     kreis_a = xoff+(80*Math.cos(0.0705*i));
     kreis_b = yoff+(80*Math.sin(0.0705*i));
     joukreis_a = kreis_a*(1+(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     joukreis_b = -1*kreis_b*(1-(Math.pow(a,2)/(Math.pow(kreis_a,2)+Math.pow(kreis_b,2))));
     m = (int)Math.round(joukreis_a);
     n = (int)Math.round(joukreis_b);
     if (i==0) {o = m; p = n;};
     g.drawLine(o+284, p+150, m+284, n+150);
     o = m; p = n;
    }

    if (hilfslinien == 1)
    {
    // Linien zum Offset und zum Cursor
    g.setColor(new java.awt.Color(230,180,180));
    u = (int)Math.round(x);
    v = (int)Math.round(y);
    g.drawLine(284,150,u,v);
    g.setColor(Color.red);
    s = (int)Math.round(xoff);
    t = (int)Math.round(yoff);
    g.drawLine(284,150,284+s,150-t);
    // kleines rotes Kreuz
    g.drawLine(u,v-5,u,v+5);
    g.drawLine(u-5,v,u+5,v);
    // Original- und Bildkreis
    g.setColor(Color.blue);
    g.drawOval(284-80,150-80,160,160);
    g.setColor(Color.red);
    g.drawOval(s+284-80,-1*t+150-80,160,160);
    g.drawOval(s+284-1,-1*t+150-1,2,2);
    // Koordinatensystem
    g.setColor(Color.darkGray);
    g.drawLine(0,150,568,150);
    g.drawLine(284,0,284,300);
    }

    g.setColor(Color.darkGray);
    g.drawString("X-Offset  =  "+xoff,15,25);
    g.drawString("Y-Offset  =  "+(Math.round(yoff*10.))/10.,15,40);
    g.drawString("Transformations-",15,55);
    g.drawString("konstante  a = "+(Math.round(a*10.))/10.,15,70);

    if ((Math.sqrt((Math.pow(xoff,2)+Math.pow(yoff,2))) > 80) || (a > Math.abs(Math.abs(xoff)-Math.sqrt(Math.abs(6400-Math.pow(yoff,2))))))
    {
      g.drawString("Keine sinnvolle Rechnung möglich!",15,285);
    }
    else
    {
      g.drawString("Zirkulationsstärke  =  "+(Math.round(Z*100.))/100.,15,255);
      g.drawString("Auftriebsbeiwert    =  "+(Math.round(ca*100.))/100.,15,270);
      g.drawString("Nullanstellwinkel  =  "+(Math.round((alfa0*180/Math.PI)*100.))/100.+"°",15,285);
    }

  }

  public void mouseDragged(MouseEvent e)
  {
    hilfslinien = 1;
    if (!e.isMetaDown())
    {x=e.getX(); y=e.getY(); Mlinks();}
    if (e.getModifiers() == e.BUTTON3_MASK)
    {x=e.getX(); y=e.getY(); Mrechts();}
  }

  public void mousePressed(MouseEvent e)
  {
    hilfslinien = 1;
    if (!e.isMetaDown())
    {x=e.getX(); y=e.getY(); Mlinks();}
    if (e.getModifiers() == e.BUTTON3_MASK)
    {x=e.getX(); y=e.getY(); Mrechts();}
  }

  public void mouseReleased(MouseEvent e)
  {
    hilfslinien = 0;
    if (!e.isMetaDown())
    {x=e.getX(); y=e.getY(); Mlinks();}
    if (e.getModifiers() == e.BUTTON3_MASK)
    {x=e.getX(); y=e.getY(); Mrechts();}
  }

  public void mouseWheelMoved(MouseWheelEvent e)
  {
    hilfslinien = 0;
    if (e.getWheelRotation() < 0) {a=a+1;}
    if (e.getWheelRotation() > 0) {a=a-1;}
    MMitte();
  }
  
  public void keyPressed(KeyEvent e)
  {
    if (e.getKeyCode() == KeyEvent.VK_SPACE)
    {
     hilfslinien = 0;
     Spacetaste();
    }
    if (e.getKeyCode() == KeyEvent.VK_UP)
    {
     hilfslinien = 0;
     a=a+1;
     MMitte();
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN)
    {
     hilfslinien = 0;
     a=a-1;
     MMitte();
    }
  }

  // nicht benutzt, wird aber von Java der Form halber verlangt
  public void mouseExited(MouseEvent e) {;}
  public void mouseEntered(MouseEvent e) {;}
  public void mouseClicked(MouseEvent e) {;}
  public void mouseMoved(MouseEvent e) {;}
  public void keyReleased(KeyEvent e) {;}
  public void keyTyped(KeyEvent e) {;}

}


