//
/* ----------------------------------------------------------------------------------------------
    counter2.java	カウンタの原理								ver. 2.00 (JDK 1.02)
    															ueyama@infonet.co.jp  2000.03.20
    															update: 2009.11.26
---------------------------------------------------------------------------------------------- */
import java.applet.*;
import java.awt.*;


public class counter2 extends Applet
{
	int			Clk=0;													// 入力信号(クロック)
	int			X0=1,X1=1,X2=1,X3=1;									// ゲート出力
	int			Q=0,_Q=1;												// ラッチ出力
	int			Dx[]={34,34, 34, 34,129,129,146,146,247,247,  4,298};	// データ表示 X座標
	int			Dy[]={ 4,53,107,154, 15,145, 60,100, 26,134,107, 27};	// データ表示 Y座標	
	int			Gx[]={64,64,183,183};									// NAND ゲート表示 X座標
	int			Gy[]={13,117,25,105};									// NAND ゲート表示 Y座標
	int			Bd[]=new int[12];										// 各所データの値 (0 or 1)
	int			Dc[]={2,2,2,2,2,2,2,2,2,2,0,0};							// データの表示色 0,1:黒 2,3:灰 4,5:青 6,7:赤
	int			Gc[]={0,0,0,0};											// ゲートの表示色 0:淡 1:濃
	int			Step=5;
	Image		Img;
	
	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){};
	}
	
	public boolean inside(int x, int a, int b)
	{
		return (x<=Math.max(a,b) && x>=Math.min(a,b)) ? true:false;
	}
	
	public int nand(int a, int b)
	{
		return (a*b==1) ? 0:1;
	}
	
	public int not(int a)
	{
		return (a==1) ? 0:1;
	}
	
	public void dsp_b(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=12; h=16; ox=314; oy=154; break;					// 2進数数字
			case 1: w=62; h=46; ox=314; oy= 46; break;					// NAND gate
			case 2: w=26; h=23; ox=314; oy=  0; break;					// ボタン
			case 3: w=28; h= 7; ox=376; oy= 46; break;					// ボタンの説明文字
			case 4: w=41; h=16; ox=314; oy=138; break;					// "STEP"
			case 5: w=11; h=16; ox=355; oy=138; break;					// STEP 数字 "1"〜"5"
			case 6: w=66; h=16; ox=180; oy=150; break;					// STEP 数のクリア
		}
		gx.clipRect(x,y,w,h);
		gx.clearRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+m*w),y-(oy+n*h),this);
		gx.dispose();
	}
	
	public void signal()
	{
		Bd[0]=_Q; Bd[1]=Clk; Bd[2]=Clk; Bd[3]=Q; Bd[4]=X0; Bd[5]=X1;
		Bd[6]=_Q; Bd[7]=Q; Bd[8]=Q; Bd[9]=_Q; Bd[10]=Clk; Bd[11]=Q;
	}
	
	public void paint(Graphics g)
	{
		int i;
		g.clearRect(0,0,size().width,size().height);
		g.drawImage(Img,0,0,this);
		signal();														// 各データの読みとり
		for(i=0;i<4;i++) dsp_b(Gx[i],Gy[i],0,Gc[i],1);					// ゲートの表示
		for(i=0;i<12;i++) dsp_b(Dx[i],Dy[i],Bd[i]+Dc[i],0,0);			// データの表示
		dsp_b(200,197,0,(Step>4)?0:1,2); dsp_b(199,223,0,(Step>4)?0:1,3);	// Clock ボタンと説明の表示
		if(Step<5)
		{
			dsp_b(88,200,0,0,4);										// "STEP"の表示
			dsp_b(143,200,Step,0,5);									// STEP 数の表示
		}
	}
	
	public void dsp_status()
	{
		int i=0;
		switch(Step)
		{
			case 0:	Clk=not(Clk); Dc[1]=Dc[2]=6;	break;
			case 1: for(i=0;i<4;i++) Dc[i]=4;
					Gc[0]=Gc[1]=1;					break;
			case 2: X0=nand(Clk,_Q); X1=nand(Clk,Q);
					for(i=0;i<4;i++) Dc[i]=2;
					for(i=0;i<2;i++) Dc[i+4]=6;		break;
			case 3: for(i=0;i<4;i++) Dc[i+4]=4;
					Gc[0]=Gc[1]=0; Gc[2]=Gc[3]=1;	break;
			case 4: Q=(X0==0)?1:0; _Q=not(Q);
					Clk=not(Clk);
					X0=nand(Clk,_Q); X1=nand(Clk,Q);
					for(i=0;i<4;i++) Dc[i+4]=2;
					for(i=0;i<2;i++) Dc[i+8]=6;		break;
			case 5: for(i=0;i<2;i++) Dc[i+8]=2;
					Gc[2]=Gc[3]=0;
					dsp_b(88,200,0,0,6);								// STEP 数の表示をクリア
					dsp_b(200,197,0,0,2); dsp_b(199,223,0,0,3);	break;
		}
		signal();														// 各データの読みとり
		for(i=0;i<12;i++) dsp_b(Dx[i],Dy[i],Bd[i]+Dc[i],0,0);			// データの表示
		for(i=0;i<4;i++) dsp_b(Gx[i],Gy[i],0,Gc[i],1);					// ゲートの表示
		if(Step<5)
		{
			dsp_b(88,200,0,0,4); dsp_b(143,200,Step,0,5);				// ステップの表示
		}
	}
	
	public boolean mouseDown(Event e, int mx, int my)
	{
		if(inside(mx,200,226) && my>197)
		{
			Step++; Step%=6;
			dsp_status();
			dsp_b(200,197,1,(Step==0)?0:1,2);							// CLOCK / STEP ボタンの表示
		}
		return true;
	}
	
	public boolean mouseUp(Event e, int mx, int my)
	{
		if(inside(mx,200,226) && my>197)
		{
			if(Step==5) dsp_b(200,197,0,0,2);							// CLOCK / STEP  ボタンの表示
			else		dsp_b(200,197,0,1,2);							// 同上
			dsp_b(199,223,0,(Step>4)?0:1,3);							// CLOCK ボタンの説明の表示
		}
		return true;
	}
}
//
戻る