/**********************************************************************************
 *                                                                                *
 *                  文字をスクロール表示するJavaアプレット                       *
 *                             ( Scroller.java )                                  *
 *                                                         Author : Seiichi Inoue *
 **********************************************************************************/

/****************** << インポートパッケージクラス定義 >> ********************/
import java.applet.*;                /* Appletパッケージの全て                    */
import java.awt.*;                   /* Abstract Windowing Toolkitパッケージの全て*/

/************************ << 自分のクラス定義 >> ****************************/
//  クラス名称 : Scroller
//  アクセス制御: public(どのクラスからもアクセス可能)
//  継承クラス : Applet
//  引継クラス : Runnable
public  class  Scroller  extends Applet implements Runnable {

/************************ << クラス属性の定義 >> ****************************/
    Dimension d;                                    /* 表示領域          */
    String    s[];                                  /* 文字配列領域    (文字)*/
    Thread    kicker = null;                        /* キッカー    (スレッド)*/
    int       xScroll;                              /* スクロール位置   (正数)*/
    int       y_Point;                              /* 文字の縦位置    (正数)*/
    Font      font;                                 /* フォント    (フォント)*/
    int       strHeight,strWidth;                   /* 文字列高さ、幅   (正数)*/
    int       maxText;                              /* 文字ブロック数   (正数)*/
    int       curTextCount = 0;                     /* 現在の文字ブロック (正数)*/
    int       red,blue,green;                       /* 文字色       (正数)*/
    Color     color;                                /* 文字色      (カラー)*/
    int       speed;                                /* スクロール速度   (正数)*/
    Image     offs;                                 /* オフスクリーン (イメージ)*/
    Graphics  grf;                                  /* 描画領域  (グラフィック)*/

/******************* << クラスのメソッド(実行手順) >> *********************/
//
/************* 初期化(init)メソッド ***************/
    public void init() {
        d = size();                                  /* 表示画面サイズ情報を設定  */
        xScroll = d.width;                           /* 表示開始位置を設定     */

        offs = createImage(d.width,d.height);        /* オフスクリーン用イメージ
                            エリア作成         */
        grf  = offs.getGraphics();                   /* イメージ表示のための
                            Graphicsオブジェクト取出  */
        String param = getParameter("speed");        /* 入力パラメータ"speed"取込 */
        speed = (param != null)?                     /* 入力判定(無指定時は1)   */
            Integer.parseInt(param): 1;
        if(speed < 1 && speed > 5) {                 /* 入力異常判定( <1? , >5? ) */
            speed = 1;                               /* 異常の時は1を設定    */
        }
        param = getParameter("maxText");             /* テキストブロック数取込  */
        maxText = (param != null)?                   /* 入力判定(無指定時は1)  */
            Integer.parseInt(param): 1;
        s = new String[maxText];                     /* 文字配列の作成      */

        int i=0;                                     /* ループカウント初期化   */
        do {                                         /* DOループ (文字配列作成) */
            param = getParameter("text" + (i+1));    /* i+1番目のテキスト取込   */
            if(param != null) {                      /* テキスト有無判定     */
                s[i] = new String(param);            /* 有(テキストを配列に設定) */
            } else {                                 /* 無            */
                if( i==0 ) {                         /* テキストが1つも無い?  */
                    s[i] = "Text Parameter Erorr";   /* テキスト指定異常を設定  */
                }
                    maxText = i + 1;                 /* テキストブロック数を設定 */
                }
        } while(param != null && ++i != maxText);    /* DOループ終了判定    */

        font = new Font("Dialog",Font.BOLD,20);      /* 表示フォント設定     */
        strHeight  = (getFontMetrics(font)).getLeading(); /* 表示位置(縦)設定  */
        strHeight -= (getFontMetrics(font)).getDescent();
        strHeight += (getFontMetrics(font)).getAscent();
        y_Point    = (d.height + strHeight
                      - (getFontMetrics(font)).getDescent())/2;
    }                                                /* 初期化メソッド終了        */


/************** 実行(run)メソッド *****************/
    public void run() {
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3);
        while (kicker != null) {                     /* kickerがnullになるまで繰返*/
            repaint();                               /* 描画           */
            try {                                    /* 割り込み確認       */
                Thread.sleep( 20 );                  /* 待ち時間を20ミリ秒設定 */
            } catch (InterruptedException e) {}      /* 割り込み処理       */
        }
        kicker = null;
    }                                                /* 実行メソッド終了     */


/************* 更新(update)メソッド ***************/
    public void update(Graphics g)  {
        paint(g);
    }                                                /* 更新メソッド終了     */


/************** 描画(paint)メソッド ***************/
    public void paint(Graphics g) {
        grf.setFont(font);                           /* 表示フォントの設定    */
        grf.setColor(Color.black);                   /* 表示背景色の設定     */
        grf.fillRect(0, 0, d.width, d.height);       /* 表示領域を塗る      */
        if (xScroll == d.width) {                    /* 表示位置が先頭?     */
            String param = getParameter("red");      /* 赤色の指定を取込     */
            red = (param != null)?                   /* 無指定時最大値            */
               Integer.parseInt(param): 255;
            param = getParameter("blue");            /* 青色の指定を取込     */
            blue = (param != null)?                  /* 無指定時最大値            */
               Integer.parseInt(param): 255;
            param = getParameter("green");           /* 緑色の指定を取込     */
            green = (param != null)?                 /* 無指定時最大値            */
               Integer.parseInt(param): 255;
            color = new Color(red,green,blue);       /* 表示色を設定       */
            curTextCount ++ ;
            if (curTextCount > maxText) {            /* 文字ブロックオーバー?    */
                curTextCount = 1;                    /* YES:最初のブロック設定  */
            }
            strWidth = (getFontMetrics(font)).       /* 文字列の幅を取込     */
                        stringWidth(s[curTextCount - 1]);
        }
        grf.setColor(color);                         /* 表示色設定        */
        xScroll -= speed;                            /* スピード指定分位置を減算 */
        grf.drawString(s[curTextCount-1],            /* ずらした文字を表示       */
                               xScroll,y_Point);
        if(xScroll < -strWidth)  {                   /* 表示終了判定       */
           xScroll = d.width;                        /* 終了時に表示位置を初期化 */
        }
        g.drawImage(offs, 0, 0, this);               /* イメージ表示       */
    }                                                /* 描画メソッド終了     */

/************* スタート(start)メソッド ************/
    public void start() {
        if (kicker == null) {                        /* kickerがnull?(停止中?)  */
            kicker = new Thread(this);               /* YES:kickerを動作中に設定 */
            kicker.start();
        }
    }                                                /* スタートメソッド終了   */

/************* ストップ(stop)メソッド *************/
    public void stop() {
        if (kicker != null) {                      /* kickerがnullでない?(動作中?)*/
            kicker.stop();
            kicker = null;                           /* YES:kickerを停止に設定  */
        }
    }                                                /* ストップメソッド終了   */
}                                                    /* クラス設定終了      */

/**********************************************************************************
 *             スクロールアプレット終了                              *
 **********************************************************************************/