//
/* ----------------------------------------------------------------------------------------------
    caesar.java		シーザー暗号							ver. 1.00 (JDK 1.02)
    														ueyama@infonet.co.jp  1999.12.28
---------------------------------------------------------------------------------------------- */

import java.applet.*;
import java.awt.*;
import java.util.*;


public class caesar extends Applet
{
	int			X0=120, Y0=240;
	int			Ax=34, Ay= 0;										// アルファベット表示座標
	int			Kx=34, Ky=53;										// キー文字列表示座標
	int			Hx0=0, Hy0=130, Hx,Hy;								// 平文表示座標
	int			Cx0=0, Cy0=180, Cx,Cy;								// 暗号文表示座標
	int			R,G,B;
	int			Qwer[]={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			Htxt[]=new int[128];
	int			Ktxt[]=new int[28];
	int			Ex[]  =new int[28];
	int			Hq=0;
	int			Kn=0;												// シーザー暗号キー
	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[]={139,157,169,185,201,212,223,239,254,257,265,279,291,309,324,
					  342,354,374,389,401,418,432,449,472,488,505,519,519};
	boolean		Fc=true;											// true:シーザー暗号  false:換字暗号
	AudioClip	Ac1, Ac2;											// 効果音
	Graphics	gr;
	Image		Img;
	Random		Rnd=new Random();
	
	public void init()
	{
		R=Integer.parseInt(getParameter("bg_red"));
		G=Integer.parseInt(getParameter("bg_green"));
		B=Integer.parseInt(getParameter("bg_blue"));
		setBackground(new Color(R,G,B));
		MediaTracker mt=new MediaTracker(this);
		Img=getImage(getCodeBase(), getParameter("figure"));
		mt.addImage(Img, 0);
		try
		{
			mt.waitForID(0);
		}
		catch(InterruptedException e){};
		gr=getGraphics();
		Ac1=getAudioClip(getCodeBase(), getParameter("audio_clip_1"));
		Ac2=getAudioClip(getCodeBase(), getParameter("audio_clip_2"));
		Kn=Math.abs(Rnd.nextInt())%25+1;
		caesar_key();
		Hx=Hx0; Hy=Hy0; Cx=Cx0; Cy=Cy0;
	}
	
	public void update(Graphics g)
	{
		paint(g);
	}
	
	public boolean inside(int x, int a, int b)
	{
		return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
	}
	
	public void caesar_key()
	{
		int i,j;
		for(i=Kn,j=0; i<26; i++,j++) Ktxt[j]=i;
		for(i=0; id) {d=Ex[j]; k=j;}}
			Ex[k]=0; Ktxt[i]=k;
		}
	}
	
	public void shift_key(int n)
	{
		int i,j;
		if(n>0)
		{
			j=Ktxt[25];
			for(i=24; i>=0; i--) Ktxt[i+1]=Ktxt[i];
			Ktxt[0]=j;
		}
		else
		{
			j=Ktxt[0];
			for(i=0; i<26; i++) Ktxt[i]=Ktxt[i+1];
			Ktxt[25]=j;
		}
	}
	
	public void dsp_g(int x, int y, int n, int c, int m)
	{
		Graphics	gx=gr.create();
		int			w=0, h=0, ox=0, oy=0;
		switch(c)
		{
			case	 0:	w= 30; h=30; ox=  0; oy= 0; x+=X0; y+=Y0;	break;	// キー
			case	 1:	w=109; h=30; ox= 30; oy= 0; x+=X0; y+=Y0;	break;	// SPACE キー
			case	 2:	w= 16; h=16; ox=139; oy= 0; x+=X0; y+=Y0;	break;	// キー文字
			case	 3:	w=  7; h=13; ox=106; oy=89;					break;	// 矢印
			case	 4:	w= 26; h=23; ox=  0; oy=60;					break;	// 右矢印ボタン
			case	 5:	w= 26; h=23; ox=  0; oy=83;					break;	// 左矢印ボタン
			case	 6:	w= 14; h=14; ox= 78; oy=89;					break;	// チェックボックス
			case	 7:	w= 56; h=14; ox= 78; oy=60;					break;	// "シーザー"
			case	 8:	w= 31; h=15; ox= 78; oy=74;					break;	// "換字"
			case	 9:	w= 26; h=23; ox=520; oy=16;					break;	// クリアボタン
		}
		gx.clipRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+n*w),y-(oy+m*h),this);
		gx.dispose();
	}
	
	public void dsp_k(int i, int m)
	{
		dsp_g(Bx[i],By[i],0,(i<27)?0:1,m);							// キートップの表示
		if(i<27) dsp_g(Bx[i]+7,By[i]+7,Qwer[i],2,0);				// 文字の表示
	}
	
	public void dsp_t(int x, int y, int n, int m)
	{
		Graphics	gx=gr.create();
		int			w=0, h=0, ox=0, oy=0;
		h=24; oy=16;
		w=Cw[n]; ox=Co[n];
		gx.clipRect(x,y,w,h);
		gx.drawImage(Img,x-(ox),y-(oy+m*h),this);
		gx.dispose();
	}
	
	public void dsp_c()												// 平文・暗号文の表示
	{
		int i,j;
		for(i=0;i336)
		{
			if(inside(x, 397, 423))
			{
				dsp_g(397,337,1,5,0);								// 左矢印ボタンの表示
				Kn++; Kn%=26;
				if(Fc) caesar_key();
				else shift_key(-1);
				dsp_a();
				gr.clearRect(0,Cy0,size().width,24);
				Hx=Hx0; Cx=Cx0;
				dsp_c();
			}
			if(inside(x, 427, 453))
			{
				dsp_g(427,337,1,9,0);								// クリアボタンの表示
				Hq=0;
				gr.clearRect(0,Hy0,size().width,24);
				gr.clearRect(0,Cy0,size().width,24);
				Hx=Hx0; Cx=Cx0;
				dsp_c();
			}
			if(inside(x, 457, 483))
			{
				dsp_g(457,337,1,4,0);								// 右矢印ボタンの表示
				Kn+=25; Kn%=26;
				if(Fc) caesar_key();
				else shift_key(1);
				dsp_a();
				gr.clearRect(0,Cy0,size().width,24);
				Hx=Hx0; Cx=Cx0;
				dsp_c();
			}
			if(inside(x, 500, 640))
			{
				if(inside(x, 500, 582))
				{
					Fc=true;
					caesar_key();
				}
				if(inside(x, 583, 640))
				{
					Fc=false;
					exchange_key();
				}
				dsp_a();
				gr.clearRect(0,Cy0,size().width,24);
				Hx=Hx0; Cx=Cx0;
				dsp_c();
				dsp_g(397,337,0,5,0);								// 左矢印の表示
				dsp_g(427,337,0,9,0);								// 左矢印の表示
				dsp_g(457,337,0,4,0);								// 右矢印の表示
				dsp_g(500,343,(Fc)?0:1,6,0);						// チェックボックスの表示
				dsp_g(590,343,(Fc)?1:0,6,0);						// チェックボックスの表示
			}
		}
		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_k(i, 0);
				j=Qwer[i];
				if(j<26)
				{
					dsp_t(Hx,Hy,j,2);								// 平文の表示
					dsp_t(Cx,Cy,Ktxt[j],(Fc && Kn==0)?2:3);			// 暗号文の表示
					gr.setColor(new Color(255,255,255));
					gr.fillRect(j*24+Ax+4,Ay+1,24,31);
					gr.fillRect(j*24+Kx+4,Ky+1,24,31);
					dsp_t(j*24+(24-Cw[j])/2+Ax+4,Ay+5,j,0);			// アルファベットの表示
					dsp_t(j*24+(24-Cw[Ktxt[j]])/2+Kx+4,Ky+5,Ktxt[j],1);		// 暗号キーの表示
					dsp_g(j*24+Ax+12,36,1,3,0);						// 矢印の表示
				}
				if(j==26)
				{
					Hq--;
					gr.clearRect(0,Hy0,size().width,24);
					gr.clearRect(0,Cy0,size().width,24);
					Hx=Hx0; Cx=Cx0;
					dsp_c();
				}
				else
				{
					Hx+=Cw[j]+3;
					Cx+=(j<26)?Cw[Ktxt[j]]+3:Cw[j]+3;
					Htxt[Hq]=j;
					Hq++;
				}
				Ac2.play();
			}
		}
		if(inside(x, 397, 640) && y>336)
		{
			if(inside(x, 397, 423)) dsp_g(397,337,0,5,0);			// 左矢印ボタンの表示
			if(inside(x, 427, 453)) dsp_g(427,337,0,9,0);			// クリアボタンの表示
			if(inside(x, 457, 483)) dsp_g(457,337,0,4,0);			// 右矢印ボタンの表示
		}
		return true;
	}
}
//
戻る