//
/* ----------------------------------------------------------------------------------------------
    caesar.java  シーザー暗号								ver. 1.00 (JDK 1.02)
    														ueyama@infonet.co.jp  1999.12.28
    														update: 2009.12.23
---------------------------------------------------------------------------------------------- */
import java.applet.*;
import java.awt.*;
import java.util.*;


public class caesar extends Applet
{
	int			X0=98, Y0=234;											// キーボード表示位置
	int			Ax=34, Ay= 0;											// アルファベット表示座標
	int			Kx=34, Ky=53;											// 暗号鍵文字列表示座標
	int			Px=0, Py=130;											// 平文表示座標
	int			Cx=0, Cy=180;											// 暗号文表示座標
	int			Qw[]={16, 22,  4, 17, 19, 24, 20,  8, 14, 15, 26,		// キー配列  26:BS, 27:Space
					   0,  18,  3,  5,  6,  7,  9,  10,  11,
						25, 23,  2, 21,  1, 13, 12,			 27};
	int			Bx[]={0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300,	// キー表示 X 座標
					   7, 37, 67, 97, 127, 157, 187, 217, 247,
						22, 52, 82, 112, 142, 172, 202,		112};
	int			By[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,					// キー表示 Y 座標
					   30, 30, 30, 30, 30, 30, 30, 30, 30,
					    60, 60, 60, 60, 60, 60, 60,			 90};
	int			Ptxt[]=new int[128];									// 平文テキストデータ
	int			Key[]=new int[28];										// 暗号鍵データ
	int			Pq=0;													// 平文文字数
	int			Kn=3;													// シーザー暗号 暗号鍵
	int			Cw[]={18,12,16,16,11,11,16,15,3,8,14,12,18,15,18,12,20,15,12,17,14,17,23,16,17,14,0,8};	// 文字幅
	int			Co[]={0,18,30,46,62,73,84,100,115,118,126,140,152,170,185,
					  203,215,235,250,262,279,293,310,333,349,366,550,550};	// gif 画像の文字位置 (X座標)
	boolean		Fc=true;												// true:シーザー暗号  false:換字暗号
	AudioClip	Ac1, Ac2;												// 効果音
	Image		Img;
	Random		Rnd=new Random();
	Graphics	gr;
	
	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"));
		mt.addImage(Img, 0);
		try
		{
			mt.waitForID(0);
		}
		catch(InterruptedException e){};
		Ac1=getAudioClip(getCodeBase(), getParameter("audio_clip_1"));	// 効果音の読み込み
		Ac2=getAudioClip(getCodeBase(), getParameter("audio_clip_2"));
		gr=getGraphics();
		new_key();
	}
	
	public boolean inside(int x, int a, int b)
	{
		return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
	}
	
	public void new_key()												// 暗号鍵生成
	{
		int i,m;
		if(Fc) for(i=0; i<26; i++) Key[i]=(i+Kn)%26;					// シーザー暗号
		else															// 換字暗号
		{
			for(i=0; i<26; i++) Key[i]=-1;								// 暗号鍵をクリア
			for(i=0; i<26; i++)											// ランダムな鍵を生成
			{
				while(true)
				{
					m=Math.abs(Rnd.nextInt())%26;						// 0〜25 の乱数を発生
					if(Key[m]<0) {Key[m]=i; break;}						// 未定であれば鍵の数値を代入
				}
			}
		}
	}
	
	public void dsp_key()												// アルファベット・暗号鍵の表示
	{
		int i;
		gr.setColor(new Color(0x999999));
		gr.drawRect(Ax,Ay,632,32);
		gr.setColor(new Color(0xcc9999));
		gr.drawRect(Kx,Ky,632,32);
		gr.setColor(new Color(0xffffff));
		gr.fillRect(Ax+1,Ay+1,630,30);
		gr.fillRect(Kx+1,Ky+1,630,30);
		for(i=0;i<26;i++)
		{
			dsp_g(i*24+(24-Cw[i])/2+Ax+4,Ay+5,i,0,7);					// アルファベットの表示
			dsp_g(i*24+(24-Cw[Key[i]])/2+Kx+4,Ky+5,Key[i],1,7);			// 暗号キーの表示
		}
	}
	
	public void dsp_g(int x, int y, int m, int n, int c)
	{
		Graphics gx=getGraphics();
		int  w=0, h=0, ox=0, oy=0;
		switch(c)
		{
			case 0:	w= 16; h=16; ox=  0; oy= 0; x+=X0; y+=Y0; break;	// キー文字
			case 1:	w= 30; h=30; ox=458; oy= 0; x+=X0; y+=Y0; break;	// キー
			case 2:	w=109; h=30; ox=488; oy= 0; x+=X0; y+=Y0; break;	// SPACE キー
			case 3:	w=  7; h=13; ox=486; oy=89;				  break;	// 矢印
			case 4:	w= 26; h=23; ox=380; oy=16;				  break;	// ボタン
			case 5:	w= 14; h=14; ox=458; oy=89;				  break;	// チェックボックス
			case 6:	w= 56; h=14; ox=458; oy=60;				  break;	// "シーザー", "換字"
			case 7: w=Cw[m]; h=24; ox=Co[m]; oy=16; m=0;	  break;	// 平文・暗号文用文字
		}
		gx.clipRect(x,y,w,h);
		if(c>0) gx.clearRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+m*w),y-(oy+n*h),this);
		gx.dispose();
	}
	
	public void dsp_ktp(int i, int m)									// キーの表示  i: 文字  m: キー色
	{
		dsp_g(Bx[i],By[i],0,m,(i<27)?1:2);								// キートップの表示
		if(i<27) dsp_g(Bx[i]+7,By[i]+7,Qw[i],0,0);						// 文字の表示
	}
	
	public void dsp_txt()												// 平文・暗号文の表示
	{
		int i,j;
		Px=0; Cx=0;
		for(i=0;i343)								// シーザー/換字 をクリック
		{
			if(inside(x, 458, 547)) Fc=true;							// シーザー暗号
			if(inside(x, 548, 598)) Fc=false;							// 換字暗号
			new_key();													// 暗号鍵生成
			dsp_key();													// 暗号鍵の表示
			gr.clearRect(0,Cy,size().width,24);							// 暗号文表示領域のクリア
			dsp_txt();													// 平文・暗号文の表示
			dsp_g(458,343,(Fc)?0:1,0,5);								// チェックボックスの表示
			dsp_g(548,343,(Fc)?1:0,0,5);								// チェックボックスの表示
		}
		return true;
	}
	
	public boolean mouseUp(Event e, int x, int y)
	{
		int	i,j;
		if(inside(x, X0, X0+330) && inside(y, Y0, Y0+120))
		{
			for(i=0;i<28;i++) if(inside(x,Bx[i]+X0,Bx[i]+X0+((i<27)?30:109)) && inside(y,By[i]+Y0,By[i]+Y0+30)) break;
			if(i<28)
			{
				dsp_ktp(i, 0);											// キー表示を元に戻す
				j=Qw[i];
				if(j<26)
				{
					dsp_g(Px,Py,j,2,7);									// 平文の表示
					dsp_g(Cx,Cy,Key[j],(Fc && Kn==0)?2:3,7);			// 暗号文の表示
					dsp_g(j*24+(24-Cw[j])/2+Ax+4,Ay+5,j,0,7);			// アルファベットの表示
					dsp_g(j*24+(24-Cw[Key[j]])/2+Kx+4,Ky+5,Key[j],1,7);	// 暗号キーの表示
					dsp_g(j*24+Ax+12,36,1,0,3);							// 矢印の表示
				}
				if(j==26)												// BS キー
				{
					Pq--;												// 平文文字数
					gr.clearRect(0,Py,size().width,24);
					gr.clearRect(0,Cy,size().width,24);
					dsp_txt();											// 平文・暗号文の表示
				}
				else
				{
					Px+=Cw[j]+3;										// 平文表示座標の更新
					Cx+=(j<26)?Cw[Key[j]]+3:Cw[j]+3;					// 暗号文表示座標の更新
					Ptxt[Pq]=j;											// 平文テキストデータ
					Pq++;												// 平文文字数
				}
				Ac2.play();
			}
		}
		if(inside(x, 484, 570) && inside(y,308,331))
		{
			if(inside(x, 484, 510)) dsp_g(484,308,0,1,4);				// 左矢印ボタンの表示
			if(inside(x, 514, 540)) dsp_g(514,308,0,2,4);				// クリアボタンの表示
			if(inside(x, 544, 570)) dsp_g(544,308,0,0,4);				// 右矢印ボタンの表示
		}
		return true;
	}
}
//
戻る