/* Eyes Applet
   JDK1.1対応版
                  Coded By.KeN    Mar.19,1997

   appletタグの width、heightの値に応じて目玉の大きさが変わります。
*/

import java.awt.*;     // このクラスは沢山使うので*を使います
import java.lang.Math; // 数式クラス
import java.awt.event.*; // イベント処理パッケージ

public class Eye extends java.applet.Applet implements MouseMotionListener {
  int mx, my; // マウスの位置用変数
  int blx, bly, brx, bry; // 前の目玉の位置保存用変数

  public void init() {
    addMouseMotionListener( this ); // マウス移動のイベントを受け取ります
  }

  public void paint( Graphics scr ) { // アプレットが最初に呼ばれた時
                                      // 描くべきものを描きます
    int sw = getSize().width;         // アプレットウィンドウの横幅
    int sh = getSize().height;        // アプレットウィンドウの縦幅
    blx = (int)( getSize().width/4 );   // 直前の左目のX座標の初期設定
    bly = (int)( getSize().height/2 );  //             Y
    brx = (int)( getSize().width*3/4 ); //       右目のX
    bry = bly;                          //             Y

    scr.setColor( Color.black );     // 描画色を黒にします
    scr.fillOval( 0, 0, (int)(sw/2), sh );           // 左目の枠を描きます
    scr.fillOval( (int)(sw/2), 0, (int)(sw/2), sh ); // 右目

    scr.setColor( Color.white );     // 描画色を白にします
    scr.fillOval( (int)(sw/2*0.05), (int)(sh*0.05 ), // 左の白目を描きます
                  (int)(sw/2*0.9), (int)(sh*0.9) ); 
    scr.fillOval( (int)(sw/2*1.05), (int)(sh*0.05), // 右
                  (int)(sw/2*0.9), (int)(sh*0.9) );
  }

  public void mouseMoved( MouseEvent event ) { // マウス操作イベント
    mx = event.getX(); // マウスポインタのX座標
    my = event.getY(); // マウスポインタのY座標
    repaint(); // 黒目の描画メソッドを実行
  }

  public void mouseDragged( MouseEvent event ) {
  }

  public void update( Graphics scr ) { // repaint()メソッドから呼び出されます
    int sw = getSize().width;  // アプレットウィンドウの横幅
    int sh = getSize().height; // アプレットウィンドウの縦幅
    int lx, ly, rx, ry; // 左右の目玉の座標
    int a, b; // a:楕円の長軸 b:楕円の短軸
    int px, py; // 楕円上での仮想座標

    a = (int)(sw/2*0.35);
    b = (int)(sh*0.35);

    /* 左目を描きます */
    px = mx - (int)(sw/4);
    py = (int)(sh/2) - my;

    scr.setColor( Color.white ); // 描画色を白にします
    scr.fillOval( (int)(blx-(sw/2*0.1)), (int)(bly-(sh*0.1)),
                  (int)(sw/2*0.2), (int)(sh*0.2) ); // 左の黒目をまず消す

    scr.setColor( Color.black ); // 描画色を黒にします
    if ( px == 0 ) { // マウスのX座標が楕円のX軸と同じか確認
      lx = 0;
    }
    else
      {
      // 楕円の原点からマウスの座標に向けた直線と
      // 楕円との交点のX座標を求めます
	lx = (int)( a * b * Math.sqrt (
             1 / ( Math.pow( b, 2 ) + ( Math.pow( py, 2 ) *
             Math.pow( a, 2 ) / Math.pow( px, 2 ) ) ) ) ); 

	if ( px < 0 ) lx *= -1; // マウスのX座標がX軸より左にあるならば
                                // lxを反転します
      }
      // 楕円の原点からマウスの座標に向けた直線と
      // 楕円との交点のY座標を求めます
    ly = (int)( Math.sqrt( Math.pow( b, 2 ) - ( Math.pow( b, 2 )*
         Math.pow( lx, 2 ) / Math.pow( a, 2 ) ) ) );
    if (  py < 0 ) ly *= -1; // マウスのY座標がY軸より下にあるならば
                             // lyを反転します
    if ( Math.pow( (double)px / (double)a, 2 ) + 
         Math.pow( (double)py / (double)b, 2 ) < 1 ) {
      // もし楕円内にマウスポインタがあった時
      lx = px;
      ly = py;
    }
    lx += (int)( sw / 4 ); // 相対座標から絶対座標に直します
    ly = (int)( sh / 2 ) - ly;
    // 左の黒目を描きます
    scr.fillOval( (int)( lx - ( sw / 2 * 0.1 ) ), (int)(ly - ( sh * 0.1 ) ),
                  (int)( sw / 2 * 0.2 ), (int)( sh * 0.2 ) );
    blx = lx; // 黒目のX座標を保存します
    bly = ly; //       Y

    /* 右目を描きます 内容は左目と同じです */
    px = mx - (int)( sw * 3 / 4 );
    py = (int)( sh / 2 ) - my;

    scr.setColor( Color.white );
    scr.fillOval( (int)( brx - ( sw / 2 * 0.1 ) ), (int)( bry - ( sh * 0.1 ) ),
                 (int)( sw / 2 * 0.2 ), (int)( sh * 0.2 ) ); // 左目を消します

    scr.setColor( Color.black );
    if ( px == 0 ) {
      rx = 0;
    }
    else
      {
	rx = (int)( a * b * Math.sqrt( 1 / ( Math.pow( b, 2 )+
             ( Math.pow( py, 2 ) * Math.pow( a, 2 ) / Math.pow( px, 2 ) )
             ) ) );
	if ( px < 0 ) rx *= -1;
      }
    ry = (int)( Math.sqrt( Math.pow( b, 2 ) - ( Math.pow( b, 2 ) *
         Math.pow( rx, 2 ) / Math.pow( a, 2 ) ) ) );
    if (  py < 0 ) ry *= -1;
    if ( Math.pow( (double)px / (double)a, 2 ) +
         Math.pow( (double)py / (double)b, 2 ) < 1 ) {
      rx = px;
      ry = py;
    }
    rx += (int)( sw * 3 / 4 );
    ry = (int)( sh / 2 ) - ry;
    scr.fillOval( (int)( rx - ( sw / 2 * 0.1 ) ), (int)( ry - ( sh * 0.1 ) ),
                  (int)( sw / 2 * 0.2 ), (int)( sh * 0.2 ) ); // 右目
    brx = rx;
    bry = ry;
  }
}

