//
/* ----------------------------------------------------------------------------------------------
    entropy.java	エントロピー								ver. 1.20 (JDK 1.02)
    															ueyama@infonet.co.jp  2004.02.09
    															update: 2007.08.10
---------------------------------------------------------------------------------------------- */

import java.applet.Applet;
import java.awt.*;
import java.lang.Math;
import java.util.*;


public class entropy extends Applet implements Runnable
{
	int			Kox=15, Koy=218, Dox=15, Doy=15;						// キー・液晶 表示座標
	int			Dgt=0;													// 平均情報量 整数部桁数
	double		Etp=0.0, Rt=0.0;										// Etp: 平均情報量   Rt: 確率の和
	String		Txt="", Ks;												// Txt: キー入力値
	boolean		Err=false, Dsp=false;									// WP1: 確率の和が1のとき true
	TextArea	Dtxt = new TextArea(10,32);
	Image		Img;
	Thread		th=null;
	
	public void init()
	{
		String	bg=getParameter("bgcolor");								// 背景色の読み込み
		int bgc=Integer.valueOf(bg,16).intValue();
		setBackground(new Color(bgc)); 
		MediaTracker mt=new MediaTracker(this);
		Img=getImage(getCodeBase(), getParameter("figure"));			// gif ファイルの読み込み
		mt.addImage(Img, 0);
		try
		{
			mt.waitForID(0);
		}
		catch(InterruptedException e){};
		setLayout(null);
		add(Dtxt);
		Dtxt.reshape(10,60,140,150);
	}
	
	public void start()
	{
		if(th==null)
		{
			th=new Thread(this);
			th.start();
		}
	}
	
	public boolean inside(int x, int a, int b)
	{
		return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
	}
	
	public void dsp_p(int x, int y, int m, int n, int c)				// 図や文字を描く
	{
		int w=0, h=0, ox=0, oy=0;
		switch(c)
		{
			case	 0:	w=13; h=21; ox=  0; oy= 0;	break;				// 液晶数字
			case	 1:	w=38; h=31; ox=  0; oy=42;	break;				// キー "C", "="
			case	 2:	w=38; h=21; ox= 76; oy=42;	break;				// "Err."
			case	 3:	w=20; h=12; ox=114; oy=42;	break;				// "bit"
		} 
		Graphics gx=getGraphics();
		gx.clipRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+m*w),y-(oy+n*h),this);
		gx.dispose();
	}
	
	public void dsp_lcd()												// 液晶表示
	{
		int	i=0,l=0, dp;
		double	in=0.0, dn=0.0, prv=0.0, dec;
		Etp=0.0; Rt=0.0;
		Err=false;
		for(i=0; i0)
				{
					if((dp=Ks.indexOf("/"))>0)							// 分数形式データ
					{
						in=Integer.parseInt(Ks.substring(0,dp));		// 入力値 分子
						dn=Integer.parseInt(Ks.substring(dp+1));		// 入力値 分母
						prv=in/dn;										// 入力値 実数値
					}
					else												// 小数点形式データ
					{
						dp=Ks.indexOf(".");
						if(dp<0) {Ks+=".0"; dp=1;}
						String ds=Ks.substring(dp+1);					// "." 以降の文字列
						if(dp>0) in=Integer.parseInt(Ks.substring(0,dp));	// 入力値 整数部
						dn=Integer.parseInt(ds);						// 入力値 小数部
						prv=in+dn/Math.pow(10, ds.length());			// 入力値 実数値
					}
					if(prv>1.0) Err=true;
					Etp-=prv * Math.log(prv)/Math.log(2.0);				// 平均情報量の計算
					Rt+=prv;
				}
			}
			Ks=""+(int)Etp;												// 平均情報量 整数部(文字列)
			Dgt=Ks.length();											// 平均情報量 整数部桁数(情報量の表示のため)
			dec=Etp-(int)Etp;											// 平均情報量 小数部
			for(i=0; i<8; i++)											// 平均情報量 小数部を1桁ずつ Ks に加える
			{															//                    (表示桁数確保のため)
				dec*=10.0;    
				Ks+=(int)dec;
				dec-=(int)dec;
			}
			l=Ks.length();
			while(Ks.endsWith("0") && l>Dgt)							// 下位桁 '0' の削除
			{
				Ks=Ks.substring(0,l-1);
				l--;
			}
			if(Ks.startsWith("-")  || Etp<0.0) Err=true;
			Dsp=(Rt==1.0)? true:false;									// 確率の総和が1のとき表示する
		}
		dsp_etp();
	}
	
	public void dsp_etp()												// 平均情報量の表示
	{
		int i,l,m;
		Graphics gr=getGraphics();
		gr.setColor(new Color(181,181,156));
		gr.fillRect(Dox-4,Doy-4,138,40);								// 液晶部のクリア
		if(Err) dsp_p(13*7+Dox,Doy,0,0,2);								// Error
		else if(Dsp && Rt>0.0)
		{
			l=10-Ks.length();
			if(l<10)
			{
				for(i=0; i<10; i++)
				{
					m=(i>=l)? Integer.parseInt(Ks.substring(i-l, i-l+1)): 10;
					dsp_p(13*i+Dox, Doy, m, (i-l+1==Dgt && Dgt>=0)? 1:0, 0);
				}
			}
			dsp_p(108+Dox,23+Doy,0,0,3);								// "bit" の表示
		}
	}

	public void paint(Graphics g)
	{
		int i,j;
		g.clearRect(0,0,size().width,size().height);
		g.setColor(new Color(181,181,156));
		g.fillRect(Dox-5,Doy-5,140,42);									// 液晶部
		g.drawRoundRect(0, 0, size().width-1, size().height-1,10,10);	// 外枠
		g.setColor(new Color(120,120,100));
		g.drawRect(Dox-5,Doy-5,140,42);									// 液晶部枠
		dsp_lcd();														// 液晶の表示
		dsp_p(Kox+46, Koy, 0, 0, 1);									// キー "C" の表示
		dsp_p(Kox+92, Koy, 1, 0, 1);									// キー "=" の表示
	}
	
	public void run()
	{
		while(th!=null)
		{
			dsp_etp();
			if(Rt!=1.0) Dsp=!Dsp;										// 確率の総和が1でないときは点滅
			try
			{
				th.sleep(500);
			}
			catch (InterruptedException e){};
		}
	}
	
	public boolean mouseDown(Event e, int mx, int my)
	{
		if(inside(my, Koy, Koy+31))
		{
			Txt=Dtxt.getText();
			if(inside(mx, Kox+92, Kox+130)) dsp_lcd();								// '=' をクリック
			if(inside(mx, Kox+46, Kox+ 84)) Dtxt.replaceText("", 0, Txt.length());	// "C" をクリック
		}
		return true;
	}
	
	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
}
//
戻る