/* Simple Animation Applet
                  Coded By.KeN    Jul.12,1996

   <param name=... value=...>で使えるパラメータ
    src:画像ファイル名(image1.gif〜image4.gifというアニメだったら "image")
    start:スタートフレーム
    end:エンドフレーム
    interval:ポーズ時間(ms) 500が限度？
*/

import java.awt.*;
import java.lang.Integer; // <param>タグから数値を読み出すのに使います

public class SimpleAnim extends java.applet.Applet implements Runnable {
  
  Thread anim; // スレッド型のスレッドを作ります
  
  int interval; // ポーズ時間
  int startframe; // スタートフレーム
  int endframe; // エンドフレーム
  int frame; // 総フレーム数
  String filename; // 画像ファイル名
  boolean pause = false; // 現在一時停止中かどうか
  Image src[]; // アニメ画像データを格納する配列
  int count = 0; // カウンタ

  public void init() { // アプレットが呼ばれた時最初に実行するメソッド
    String s = null;
    s = getParameter("start") ; // <param>タグからstartパラメータの値を
                                // 読み、sに入れます
    /* もし s がnullでなければその数値(intValue()メソッドが文字列sを
       数値に直します)をstartframeに入れます。nullだったらデフォルト
       として1にします */
    startframe =  ( s != null ) ? Integer.valueOf(s).intValue() : 1;
    s = getParameter("end"); // endframeの読み込み(デフォルト:1)
    endframe =  ( s != null ) ? Integer.valueOf(s).intValue() : 1;
    frame = endframe-startframe+1 ; // 総フレーム数の計算
    src = new Image[frame]; // 配列srcを総フレーム数分だけ用意します
    s = getParameter("interval"); // intervalの読み込み(デフォルト：1000)
    interval =  ( s != null ) ? Integer.valueOf(s).intValue() : 1000;
    filename = getParameter("src"); // filenameの読み込み
  }

  public void start() { // init()後に実行するメソッド
    if ( anim == null ) { // もしまだ設定していないなら
      anim = new Thread( this ); // このクラスと同じrun()を使います
                                 // スレッド anim を作成
      anim.start();              // animスレッドの開始
    }
  }

  public void run() { // animスレッドで使うメソッド
    int i;
    int j = 0;
    for ( i = startframe ; i <= endframe ; i++ ) { // スタートフレームから
                                                   // エンドフレームまで
                                                   // 以下の行を繰り返します
      // Image型 getImage(getDocumentBase(), ファイル名); はファイル名の
      // ファイルからImage型の画像(gifファイル)を読み出します。
      src[j] = getImage(getDocumentBase(), filename + i + ".gif");
      j++; // jを一つ増加
    } // for命令の終わり

    while ( true ) { // 無限ループ
      try { Thread.currentThread().sleep(interval);} // intervalで設定し
                                                     // ただけ間を置きます
             catch (InterruptedException e) {};
      repaint(); // 再描画
    }
  }

  public void paint(Graphics scr) { // 画面描画メソッド
    if (src[count] != null) { // src配列のうち現在表示しようとしている
                              // 画像がnullでないならば
      /* drawImage( Image型 img, int型 x, int型 y, ImageObserver型 observer);
         は、imgの左上をx,yに合わせて描きます。observerはimgがcomplete
	 したかどうかを知らせるインタフェースです。
      */
      scr.drawImage(src[count], 0, 0, this);
    }
    count++; // カウンタを1つ増加します
    if ( count == frame ) count=0; // カウンタとフレーム総数が同じになっ
				   // たら0に戻します
  }
  public void update(Graphics scr) { // repaint()から実行するメソッド
    paint( scr );                    // 同じ位置、同じ大きさで上書きし
				     // ていくので消去せずに直接paint
				     // メソッドを実行します。これでち
				     // らつきがなくなります
  }

  public boolean mouseDown(Event e,int x,int y) { // マウスをクリック
						  // した時のイベント
    if ( pause == true ) { // すでに中断していたのなら
      anim.resume(); // resume()メソッドはsuspend()で記憶しておいた状
		     // 態から再生します
    } else {
      anim.suspend(); // suspend()メソッドは現在の状態を記憶し、実行を
		      // 中断します
    }
    pause = ! pause; // pauseがtrueだったらfalse、falseだったらtrueに
		     // します
    return( true ); // boolean型メソッドなので返り値trueを返しておきます
  }

  public void stop() { // スレッドの停止
    if ( anim != null ) {
      anim.stop();
      anim = null;
    }
  }
}

