//
/* ----------------------------------------------------------------------------------------------
    latch.java	ラッチ回路									ver. 1.10 (JDK 1.02)
    														ueyama@infonet.co.jp  1999.02.08
    														update: 2007.08.12
---------------------------------------------------------------------------------------------- */

import java.applet.Applet;
import java.awt.*;


public class latch extends Applet implements Runnable
{
	int			Aa=1,Ab=1,Ax=0, Ba=0,Bb=1,Bx=1;							// 入出力値
	int			Ga=3, Gb=1;												// gate の状態(真理値表の対応行数)
	int			Tt[][]={{0,0,1},{0,1,1},{1,0,1},{1,1,0}};				// NAND 回路の真理値表
	int			Mx=0;													// ドット(マーカー)の表示座標
	int			Wait=128;												// 遅延表示用タイマ
	int			Clk=0;													// 遅延表示用クロック
	boolean		Sdn=false, Sup=false, Rdn=false, Rup=false;				// マウスのクリック状態
	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){};
	}
	
	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_b(int x, int y, int m, int n, int c)				// 0 or 1 の表示
	{
		int w=0, h=0, ox=0, oy=0;
		switch(c)
		{
			case 0: w=15; h=21; ox=434; oy= 0; break;					// 0,1(大)
			case 1: w=13; h=17; ox=434; oy=21; break;					// 0,1(小)
			case 2: w=26; h=23; ox=434; oy=72; break;					// <<, >> ボタン
			case 3: w= 4; h= 4; ox=464; oy= 0; break;					// ドット
		}
		Graphics gx=getGraphics();
		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 dsp_s()													// データの表示
	{
		int i,j,k;
		dsp_b( 27,  5,Aa,0,0);											// S (=Aa)
		dsp_b( 27,144,Bb,0,0);											// R (=Bb)
		dsp_b(245, 20,Ax,0,0);											// Q (=Ax)
		dsp_b(217,132,Bx,0,1);											// Bx
		dsp_b( 55, 46,Ab,0,1);											// Ab
		dsp_b( 55,106,Ba,0,1);											// Ba
		for(i=0; i<4; i++)												// 真理値表の表示
		{
			k=(i==Ga)? 1:0;
			if(i==Gb)  k=2;
			dsp_b(337,i*26+62,Tt[i][0],k,1);							// A
			dsp_b(367,i*26+62,Tt[i][1],k,1);							// B
			dsp_b(408,i*26+62,Tt[i][2],k,1);							// X
		}
	}
	
	public void paint(Graphics g)
	{
		g.clearRect(0,0,size().width,size().height);
		g.drawImage(Img,0,0,this);
		dsp_s();
		dsp_b(108,187,0,(Wait==1024)?2:0,2);											// << ボタンの表示
		dsp_b(138,187,1,(Wait==16)?2:0,2);								// >> ボタンの表示
		dsp_b(135+Mx*8,181,0,0,3);										// ドットの表示
	}
	
	public void run()
	{
		while(th!=null)
		{
			if(Sdn && Clk==1) Ax=(Aa==1 && Ab==1)? 0:1;					// 初段のゲートの状態を変える
			if(Rdn && Clk==1) Bx=(Ba==1 && Bb==1)? 0:1;
			if(Sdn && Clk==2) Bx=(Ba==1 && Bb==1)? 0:1;					// 次段のゲートの状態を変える
			if(Rdn && Clk==2) Ax=(Aa==1 && Ab==1)? 0:1;
			Ba=Ax; Ab=Bx;
			for(int i=0;i<4;i++)										// 真理値表 表示色設定
			{
				if(Tt[i][0]==Aa && Tt[i][1]!=Ax && Tt[i][2]==Ax) Ga=i;
				if(Tt[i][0]==Ax && Tt[i][1]==Bb && Tt[i][2]!=Ax) Gb=i;
			}
			dsp_s();
			Clk++;
			if(Clk>2)
			{
				if(Sup) Aa=1;
				if(Rup) Bb=1;
				Sdn=Rdn=Sup=Rup=false;
			}
			try
			{
				th.sleep(Wait);
			}
			catch (InterruptedException e){};
		}
	}
	
	public void mouse_click(int x, int y, boolean m)
	{
		Clk=0;
		if(inside(x,0,80))
		{
			if(inside(y,  0, 35))										// 'S' をクリック
			{
				if(Bb==1 && !Sdn) Aa=(Aa==1)? 0:1;
				if(m) Sdn=true;
				else  Sup=true;
			}
			if(inside(y,135,170))										// 'R' をクリック
			{
				if(Aa==1 && !Rdn) Bb=(Bb==1)? 0:1;
				if(m) Rdn=true;
				else  Rup=true;
			}
			dsp_s();
		}
	}
	
	public boolean mouseDown(Event e, int mx, int my)
	{
		if(my>186)
		{
			if(inside(mx,108,134) && Wait<1024)										// << ボタン
			{
				Wait*=2; Mx--;
				dsp_b(108,187,0,1,2);
			}
			if(inside(mx,138,164) && Wait>16)							// >> ボタン
			{
				Wait/=2; Mx++;
				dsp_b(138,187,1,1,2);
			}
			Graphics gx=getGraphics();
			gx.clearRect(0,181,164,5);
			dsp_b(135+Mx*8,181,0,0,3);									// ドットの表示
		}
		else mouse_click(mx,my,true);
		return true;
	}
	
	public boolean mouseUp(Event e, int mx, int my)
	{
		if(my>186)
		{
			if(inside(mx,108,134))										// << ボタン
			{
				dsp_b(108,187,0,(Wait==1024)?2:0,2);											// << ボタンの表示
				dsp_b(138,187,1,0,2);
			}
			if(inside(mx,138,164))								// >> ボタン
			{
				dsp_b(108,187,0,0,2);
				dsp_b(138,187,1,(Wait==16)?2:0,2);								// >> ボタンの表示
			}
		}
		else mouse_click(mx,my,false);
		return true;
	}

	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
}
//
戻る