//
/* ----------------------------------------------------------------------------------------------
    ethernet.java		イーサネット						ver. 1.10 (JDK 1.02)
    														ueyama@infonet.co.jp  2000.10.05
---------------------------------------------------------------------------------------------- */

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


public class ethernet extends Applet implements Runnable
{
	int			Dq=14;
	int			Dx[]=new int[16];									// X座標値
	int			Dy[]=new int[16];									// Y座標値
	int			Snd[]={-1,-1,-1,-1,-1,-1,-1};						// 送信コンピュータ
	int			Rcv[]={-1,-1,-1,-1,-1,-1,-1};						// 受信コンピュータ
	int			Tq=0;												// 通信数
	int			Ms=-1,Mr=-1;
	boolean		Busy=false;											// true:  ネットワーク使用中
	boolean		Run=true;											// false: 停止
	boolean		Col=false;											// true:  衝突発生モード
	int			Cd=0;												// >0:  衝突検出
	boolean		Used[]=new boolean[11];
	int			W0,W1;
	int			Bgc;
	int			Wait=64;
	Thread		th=null;
	Graphics	gr;
	Image		Gif;
	Random		Rnd=new Random();
	
	public void start()
	{
		if(th==null)
		{
			th=new Thread(this);
			th.start();
		}
	}
	
	public void init()
	{
		String bg=getParameter("BgColor");
		Bgc=Integer.valueOf(bg,16).intValue();
		setBackground(new Color(Bgc)); 
		gr=getGraphics();
		MediaTracker mt=new MediaTracker(this);
		Gif=getImage(getCodeBase(),"ethernet.gif");
		mt.addImage(Gif, 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 void dsp_g(int x, int y, int n, int c)					// 画像の表示
	{
		int			w=0,h=0, ox=0,oy=0;
		Graphics	gx=gr.create();
		switch(n)
		{
			case  0: w= 11; h= 11; ox=248; oy=11; break;			// 宛先 ヘッダ
			case  1: w= 11; h= 11; ox=248; oy= 0; break;			// 送り主 ヘッダ
			case  2: w= 11; h= 11; ox=369; oy= 0; break;			// データ
			case  3: w= 11; h= 11; ox=369; oy=11; break;			// データ消去
			case  4: w= 61; h= 60; ox=  0; oy= 0; break;			// コンピュータ
			case  5: w= 17; h= 21; ox= 61; oy= 0; break;			// コンピュータ名 白
			case  6: w= 17; h= 21; ox= 61; oy=21; break;			// コンピュータ名 青
			case  7: w= 17; h= 21; ox= 61; oy=42; break;			// コンピュータ名 赤
			case  8: w= 26; h= 23; ox=352; oy=45; break;			// "<<" ボタン
			case  9: w= 26; h= 23; ox=326; oy=22; break;			// ">>" ボタン
			case 10: w= 26; h= 23; ox=248; oy=45; break;			// "||" ボタン
			case 11: w= 26; h= 23; ox=300; oy=45; break;			// "|>" ボタン
			case 12: w= 26; h= 23; ox=248; oy=22; break;			// "×" ボタン
			case 13: w= 33; h= 33; ox=  0; oy=68; break;			// タイマー
		}
		if(n<4 && y>165) h=176-y;
		if(n<4 && y<99) {h=y-88; y=99; oy+=(11-h);}
		gx.clipRect(x,y,w,h);
		gx.drawImage(Gif,x-(ox+w*c),y-oy,this);
		gx.dispose();
	}
	
	public void dsp_c(int c)										// ネットワークケーブルの表示
	{
		int	i;
		switch(c)
		{
			case 0: gr.setColor(new Color(102,102,102)); break;
			case 1: gr.setColor(new Color(153,102,102)); break;
			case 2: gr.setColor(new Color(204, 51, 51)); break;
		}
		gr.fillRect(0,132,501,11);
		for(i=0;i<5;i++) gr.fillRect(i*88+69, 99, 11, 33);
		for(i=0;i<6;i++) gr.fillRect(i*88+25,143, 11, 33);
	}
	
	public void paint(Graphics g)
	{
		int i;
		for(i=0;i<11;i++)
		{
			dsp_g(i*44,   (i%2==0)?176:39,4,0);						// コンピュータの表示
			dsp_g(i*44+22,(i%2==0)?185:48,5,i);						// 画面の表示
		}
		for(i=0;i<6;i++) if(Snd[i]>=0) dsp_g(Snd[i]*44+22,(Snd[i]%2==0)?185:48,6,Snd[i]);
		for(i=0;i<6;i++) if(Rcv[i]>=0) dsp_g(Rcv[i]*44+22,(Rcv[i]%2==0)?185:48,7,Rcv[i]);
		i=0;
		if(Busy) i=2;
		if(Col)  i=1;
		dsp_c((Busy)?1:0);											// ネットワークケーブルの表示
		dsp_g(192,287,8,0);											// "<<" ボタンの表示
		dsp_g(222,287,(Run)? 10:11,0);								// "||" or "|>" ボタンの表示
		dsp_g(252,287,12,i);										// "×" ボタンの表示
		dsp_g(282,287,9,(Wait>16)? 0:2);							// ">>" ボタンの表示
	}
	
	public boolean dsp_p()											// パケットの表示
	{
		int i,j=0,k=0,x=0,y=0, d=9;
		
		k=(Rcv[0]0)
				{
					dsp_c((Cd%2==0)?2:1);
					Cd--;
					if(Cd==0) dsp_c((Dy[0]==99 || Dy[0]==176)?0:1);
				}
				if(!Busy)
				{
					k=Rnd.nextInt()%128;
					if(k==0 && W0==0 && W1==0)
					{
						for(i=0;i<11;i++) Used[i]=false;
						j=Math.abs(Rnd.nextInt())%11;
						while(j==(k=Math.abs(Rnd.nextInt())%11));
						Used[j]=true; Used[k]=true;
						data_set(k,j);
						if(Col)
						{
							while(Used[(j=Math.abs(Rnd.nextInt())%11)]);
							Used[j]=true;
							while(Used[(k=Math.abs(Rnd.nextInt())%11)]);
							data_set(k,j);
							W0=Math.abs(Rnd.nextInt())%128+32;
							W1=Math.abs(Rnd.nextInt())%64+32;
							Cd=8;
						}
					}
				}
				if(Col && W0>0)
				{
					W0--;
					if(W0%21==0) dsp_g(Snd[0]*44+14,(Snd[0]%2==0)?242:0,13,(W0+20)/21);	// タイマーの表示
					if(W1>0 && (W0+W1)%21==0) dsp_g(Snd[1]*44+14,(Snd[1]%2==0)?242:0,13,(W0+W1+20)/21);
					if(W0==0) dsp_c(1);
				}
				else if(dsp_p())									// 通信の終了
				{
					stop_c();
					if(Tq>0)
					{
						data_pos(Snd[0]);
						dsp_g(Rcv[0]*44+22,(Rcv[0]%2==0)?185:48,7,Rcv[0]);	// 端末赤色表示
						dsp_g(Snd[0]*44+22,(Snd[0]%2==0)?185:48,6,Snd[0]);	// 端末青色表示
					}
					if(W0==0 && W1>0)
					{
						W0=W1; W1=0;
					}
					if(W0==0 && W1==0)
					{
						Col=false;
						dsp_g(252, 287, 12, 0);
					}
				}
			}
			try
			{
				th.sleep((Run)?Wait:128);
			}
			catch (InterruptedException e){}
		}
	}
	
	public void stop_c()											// 通信終了処理
	{
		int i;
		for(i=0;i<11;i++) dsp_g(i*44+22,(i%2==0)?185:48,5,i);		// 画面の白色表示
		gr.setColor(new Color(Bgc)); 
		gr.fillRect(Snd[0]*44+14,(Snd[0]%2==0)?242:0,33,33);		// タイマーの消去
		for(i=0;i<6;i++) {Snd[i]=Snd[i+1]; Rcv[i]=Rcv[i+1];}
		Snd[6]=-1; Rcv[6]=-1; Ms=-1; Mr=-1;
		dsp_c(0);
		Busy=false;
		dsp_g(252,287,12,(Col)?1:0);								// "×" ボタンの表示
		Tq--;
	}
	
	public boolean mouseDown(Event e, int mx, int my)
	{
		int i,j, n=mx/88;
		boolean c=false;
		if(inside(my,39,99) && (mx-44)%88<61)						// 端末をクリック
		{
			n=(mx-44)/88*2+1;
			c=true;
		}
		if(inside(my,176,237) && mx%88<61)							// 端末をクリック
		{
			n=mx/88*2;
			c=true;
		}
		if(c)
		{
			if(Ms<0)
			{
				if(Mr<0)
				{
					Ms=n;
					dsp_g(n*44+22, (n%2==0)?185:48, 6, n);			// 端末青色表示
				}
			}
			else if(Mr<0)
			{
				if(Ms>=0)
				{
					Mr=n;
					if(Busy)
					{
						Cd=8; Col=true;
						W1=Math.abs(Rnd.nextInt())%32+32;
						dsp_g(252, 287, 12, 1);
					}
					data_set(Ms, Mr);
				}
			}
		}
		
		if(inside(my,287,310))
		{
			if(inside(mx,192,218))									// "<<" ボタン
			{
				Wait*=2;
				dsp_g(192, 287, 8, 1);
				dsp_g(282, 287, 9, 0);
			}
			if(inside(mx,222,248))									// "||" or "|>" ボタン
			{
				Run=!Run;
				dsp_g(222, 287, (Run)? 11:10, 1);
			}
			if(inside(mx,252,278) && !Busy)							// "×" ボタン
			{
				Col=!Col;
				dsp_g(252, 287, 12, (Col)?1:0);
				if(!Col) W0=W1=0;
			}
			if(inside(mx,282,308) && Wait>16)						// ">>" ボタン
			{
				Wait/=2;
				dsp_g(282, 287, 9, 1);
			}
		}
		return true;
	}
	
	public boolean mouseUp(Event e, int mx, int my)
	{
		if(inside(my,287,310))
		{
			if(inside(mx,192,218)) dsp_g(192, 287, 8, 0);				// "<<" ボタン
			if(inside(mx,222,248)) dsp_g(222, 287, (Run)? 10:11, 0);	// "||" or "|>" ボタン
			if(inside(mx,282,308)) dsp_g(282, 287, 9, (Wait>16)? 0:2);	// ">>" ボタン
		}
		return true;
	}
	
	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
}
//
戻る