/**********************************************************************************
 *                                                                                *
 *                       デジタル時計Javaアプレット                              *
 *                         ( DigitalClock.java )                                  *
 *                                                                                *
 *                                                        Author : Seiichi Inoue  *
 **********************************************************************************/

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

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

/************************ << クラス属性の定義 >> ****************************/
    Dimension    d;                             /* 表示領域            */
    Thread       kicker=null;                   /* スレッド制御(初期値:停止)  */
    Image        offs;                          /* オフスクリーンエリア      */
    Graphics     grf;                           /* 描画領域             */
    Image        img;                           /* 背景イメージ情報        */
    MediaTracker mt;                            /* メディアトラッカー       */
    int          imgsw;                         /* 背景イメージ有無情報      */
    String       param;                         /* 入力パラメータ取込エリア    */
    Font         font;                          /* フォント情報          */
    Color        color;                         /* 色情報             */
    int          h;                             /* 時情報             */
    String       sh,h10,h01;                    /* 時表示文字情報         */
    int          h_fontsize;                    /* 時表示フォント情報       */
    int          h10x,h10y,h01x,h01y;           /* 時表示位置情報         */
    int          m;                             /* 分情報             */
    String       sm,m10,m01;                    /* 分表示文字情報         */
    int          m_fontsize;                    /* 分表示フォント情報       */
    int          m10x,m10y,m01x,m01y;           /* 分表示位置情報         */
    int          s;                             /* 秒情報             */
    String       ss,s10,s01;                    /* 秒表示文字情報         */
    int          s_fontsize;                    /* 秒表示フォント情報       */
    int          s10x,s10y,s01x,s01y;           /* 秒表示位置情報         */
    int          am_pm;                         /* 午前/午後情報         */

/******************** << クラスのメッソード指定(実行手順) >> **************/

/*********** 初期化(init)メッソード **********/
    public void init() {
        d = size();                             /* 表示画面サイズ情報を設定     */
        offs = createImage(d.width,d.height);   /* オフスクリーン用エリア作成   */
        grf  = offs.getGraphics();              /* Graphicsオブジェクト取出     */

        param = getParameter("image");          /* 背景イメージ入力取込      */
        if ( param != null ) {                  /* 入力パラメータ有り?      */
            mt = new MediaTracker(this);        /* メディアトラッカーインスタンス */
            img = getImage(getCodeBase(),param);/* 背景イメージ取込            */
            mt.addImage(img,0);                 /* イメージロード監視登録     */
            imgsw = 1;                          /* 背景イメージ有り情報設定    */
        }
        else                                    /* NO :入力指定無し        */
            imgsw = 0;                          /* 背景イメージ無し情報設定    */

        param = getParameter("h_fontsize");     /* 時間表示フォントサイズ入力取込 */
        h_fontsize = (param != null)?           /* 入力判定(無指定時:20ポイント) */
            Integer.parseInt(param): 20;
        param = getParameter("m_fontsize");     /* 分表示フォントサイズ入力取込  */
        m_fontsize = (param != null)?           /* 入力判定(無指定時:20ポイント) */
            Integer.parseInt(param): 20;
        param = getParameter("s_fontsize");     /* 秒表示フォントサイズ入力取込  */
        s_fontsize = (param != null)?           /* 入力判定(無指定時:20ポイント) */
            Integer.parseInt(param): 20;

        param = getParameter("h10x");           /* 時10位表示位置(横)入力取込 */
        h10x = (param != null)?                 /* 入力判定(無指定時:0)      */
            Integer.parseInt(param): 0;
        param = getParameter("h10y");           /* 時10位表示位置(縦)入力取込 */
        h10y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;
        param = getParameter("h01x");           /* 時1位表示位置(横)入力取込  */
        h01x = (param != null)?                 /* 入力判定(無指定時:10)     */
            Integer.parseInt(param): 10;
        param = getParameter("h01y");           /* 時1位表示位置(縦)入力取込  */
        h01y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;

        param = getParameter("m10x");           /* 分10位表示位置(横)入力取込 */
        m10x = (param != null)?                 /* 入力判定(無指定時:30)     */
            Integer.parseInt(param): 30;
        param = getParameter("m10y");           /* 分10位表示位置(縦)入力取込 */
        m10y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;
        param = getParameter("m01x");           /* 分1位表示位置(横)入力取込  */
        m01x = (param != null)?                 /* 入力判定(無指定時:40)     */
            Integer.parseInt(param): 40;
        param = getParameter("m01y");           /* 分1位表示位置(縦)入力取込  */
        m01y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;

        param = getParameter("s10x");           /* 秒10位表示位置(横)入力取込 */
        s10x = (param != null)?                 /* 入力判定(無指定時:60)     */
            Integer.parseInt(param): 60;
        param = getParameter("s10y");           /* 秒10位表示位置(縦)入力取込 */
        s10y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;
        param = getParameter("s01x");           /* 秒1位表示位置(横)入力取込  */
        s01x = (param != null)?                 /* 入力判定(無指定時:70)     */
            Integer.parseInt(param): 70;
        param = getParameter("s01y");           /* 秒1位表示位置(縦)入力取込  */
        s01y = (param != null)?                 /* 入力判定(無指定時:20)     */
            Integer.parseInt(param): 20;

    }                                           /* 初期化メソッド終了       */

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

/*********** 繰り返し(run)メソッド ***********/
    public void run() {
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3);
        if ( imgsw != 0 ) {                     /* イメージ指定あり?       */
            try {                               /* 割り込み確認          */
                mt.waitForID(0);                /* イメージロード待ち合わせ    */
            } catch( InterruptedException e ) { /* 割り込み処理          */
                System.out.println("Wait Error");
                return;
            }
        }

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


/************ 更新(update)メソッド ***********/
    public void update(Graphics g) {            /* 画面のちらつきを無くす     */
        paint(g);                               /* 描画              */
    }                                           /* 更新メソッド終了        */


/************ 描画(paint)メソッド ************/
    public void paint(Graphics g) {
        if ( imgsw != 0 ) {                     /* 背景イメージ情報有り?     */
            if ( mt.isErrorID(0)) {             /* ロードエラー?         */
                g.drawString("Image Load Error....",50,20); /* エラー表示     */
                return;
            }
            if( ! mt.checkID(0)) {              /* ロード中?           */
                g.drawString("Loading....",d.width/2-30,20); /* ロード中表示   */
                return;
            }
            grf.drawImage(img,0,0,this);        /* イメージ情報設定        */
        }
        else {                                  /* NO :                           */
            grf.setColor(Color.black);          /*   背景色(黒)を設定     */
            grf.fillRect(0,0,d.width,d.height); /*   背景色塗りつぶし      */
        }

        Date d = new Date();                    /* 時計情報を取込         */

        h = d.getHours();                       /* 時情報を取込          */
        if ( h < 12 )                           /* 午前?             */
            am_pm = 0;                          /* YES:午前情報設定        */
        else {                                  /* NO :午後            */
            h -= 12;                            /*     時情報から12時間減算   */
            am_pm = 1;                          /*     午後情報設定        */
        }

        if ( h < 10 )                           /* 1桁( 0 - 9 )?        */
            sh = " " + h + " ";                 /* 2桁(  0 -  9 ) + 空白     */
        else
            sh = h + " ";                       /* 数字 + 空白(抽出処理のため)  */
        h10 = sh.substring(0,1);                /* 時10位数字抽出        */
        h01 = sh.substring(1,2);                /* 時1位数字抽出         */
        if ( am_pm == 0 )                       /* 午前?             */
            grf.setColor(Color.red);            /* 午前文字色(赤)設定      */
        else
            grf.setColor(Color.green);          /* 午後文字色(緑)設定      */
        grf.setFont(new Font("Dialog",Font.BOLD,h_fontsize)); /* フォント情報設定 */
        grf.drawString( h10, h10x, h10y );      /* 時10位表示情報設定      */
        grf.drawString( h01, h01x, h01y );      /* 時1位表示情報設定       */

        m = d.getMinutes();                     /* 分情報を取込          */
        if ( m < 10 )                           /* 1桁( 0 - 9 )?        */
            sm = "0" + m + " ";                 /* 2桁( 00 - 09 ) + 空白     */
        else
            sm = m + " ";                       /* 数字 + 空白(抽出処理のため)  */
        m10 = sm.substring(0,1);                /* 分10位数字抽出        */
        m01 = sm.substring(1,2);                /* 分1位数字抽出         */
        if ( am_pm == 0 )                       /* 午前?             */
            grf.setColor(Color.red);            /* 午前文字色(赤)設定      */
        else
            grf.setColor(Color.green);          /* 午後文字色(緑)設定      */
        grf.setFont(new Font("Dialog",Font.BOLD,m_fontsize)); /* フォント情報設定 */
        grf.drawString( m10, m10x, m10y );      /* 分10位表示情報設定      */
        grf.drawString( m01, m01x, m01y );      /* 分1位表示情報設定       */

        s = d.getSeconds();                     /* 秒情報を取込          */
        if ( s < 10 )                           /* 1桁( 0 - 9 )?        */
            ss = "0" + s + " ";                 /* 2桁( 00 - 09 ) + 空白     */
        else
            ss = s + " ";                       /* 数字 + 空白(抽出処理のため)  */
        s10 = ss.substring(0,1);                /* 秒10位数字抽出        */
        s01 = ss.substring(1,2);                /* 秒1位数字抽出         */
        grf.setColor(Color.red);                /* 文字色設定           */
        grf.setFont(new Font("Dialog",Font.BOLD,s_fontsize)); /* フォント情報設定 */
        grf.drawString( s10, s10x, s10y );      /* 秒10位表示情報設定      */
        grf.drawString( s01, s01x, s01y );      /* 秒1位表示情報設定       */

        g.drawImage(offs,0,0,this);             /* 描画設定            */

    }                                           /* 描画メソッド終了        */


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

}                                               /* クラス設定終了         */

/**********************************************************************************
 *            デジタル時計アプレット終了                              *
 **********************************************************************************/