//
/* ----------------------------------------------------------------------------------------------
    wave.java		波の干渉								ver. 1.00 (JDK 1.02)
    														ueyama@infonet.co.jp  2001.03.30
---------------------------------------------------------------------------------------------- */

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

public class wave extends Applet implements Runnable
{
	int			Pl=0;
	int			Mx=0;													// 鏡の位置 max: 23;
	int			Bw=340, Bh=145;											// バッファのサイズ
	int			Mc=0;													// 鏡位置の変更量
	int			Ms=-1;													// クリックされたボタン No.
	int			Wait=32;												// 表示変更待機時間 (msec)
	int			Sin[]={0,1,2,3,4,5,6,7,7,8,9,10,11,11,12,12,13,13,14,14,14,14,14,
					   14,14,14,14,14,13,13,12,12,11,11,10,9,8,7,7,6,5,4,3,2,1,
					   0,-1,-2,-3,-4,-5,-6,-7,-7,-8,-9,-10,-11,-11,-12,-12,-13,-13,-14,-14,-14,-14,-14,
					   -14,-14,-14,-14,-14,-13,-13,-12,-12,-11,-11,-10,-9,-8,-7,-7,-6,-5,-4,-3,-2,-1};
	Color		gray=new Color(204,204,204), red=new Color(204,0,0), orange=new Color(238,136,68);
	boolean		Run=false;
	Image		Img;
	Image		Buf;
	Thread		th;
	
	public void init()
	{
		String	bgc=getParameter("bgcolor");							// html 背景色
		int col=Integer.valueOf(bgc,16).intValue();
		setBackground(new Color(col)); 
		Buf=createImage(Bw,Bh);
		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()
	{
		th=new Thread(this);
		th.start();
	}
	
	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
	
	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 dsp_b(int x, int y, int m, int n, int c)				// 画像の表示
	{
		int ox=0,oy=0,w=0,h=0;
		switch(c)
		{
			case  0: w= 26; h= 23; ox=  0; oy= 0; break;				// ボタン
			case  1: w= 11; h= 37; ox=156; oy= 0; break;				// "反射光", "干渉光"
		}
		Graphics gx=getGraphics();
		gx.clipRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+w*m),y-(oy+h*n),this);
		gx.dispose();
	}

	public void dsp_btn()												// ボタンの表示
	{
		int m0=(Ms==0)?1:0, m1=(Ms==1)?1:0, m2=(Ms==5)?1:0, m4=(Ms==7)?1:0;
		dsp_b(  2,177,0, (Mx== 0)?2:m0, 0);								// ← ボタン
		dsp_b( 32,177,1, (Mx==23)?2:m1, 0);								// → ボタン
		dsp_b(152,177,2, (Wait==512)?2:m2, 0);							// << ボタン
		dsp_b(182,177,(Run)?5:3, (Ms==6 || Ms==8)?1:0, 0);				// |> ボタン
		dsp_b(212,177,4, (Wait==  8)?2:m4, 0);							// >> ボタン
	}

	public void dsp_wave()												// 波 を描く
	{
		int i,j,x;
		Graphics gr=getGraphics();
		Graphics mg=Buf.getGraphics();
		mg.clearRect(0,0,Bw,Bh);										// バッファのクリア
		mg.setColor(gray);
		mg.fillRect(0,33,Mx,50);										// 反射膜(鏡)を描く
		mg.fillRect(0,93,Mx,50);
		
		for(i=Pl,j=700; i*j>0; i--,j--)									// 波を描く
		{
			if(Bw-(Pl-i)>0) mg.setColor(gray);							// ランド反射光
			else mg.setColor(red);
			x=(Bw-(Pl-i)>0)?Bw-(Pl-i): (Pl-i)-Bw;
			mg.fillRect(x,Sin[i%90]/2+7,3,3);
			if(Bw-(Pl-i)>Mx) mg.setColor(gray);							// ピット反射光
			else mg.setColor(red);
			x=(Bw-(Pl-i)>Mx)?Bw-(Pl-i): Mx-(Bw-(Pl-i)-Mx);
			mg.fillRect(x,Sin[i%90]/2+57,3,3);
			if(Bw-(Pl-i)<=Mx)											// 干渉光
			{
				mg.setColor(orange);
				mg.fillRect(x,(Sin[(Mx*2+i)%90]+Sin[i%90])/2+117,3,3);
			}
		}
		gr.drawImage(Buf,30,17,this);									// バッファの表示
		gr.dispose();
		mg.dispose();
	}

	public void paint(Graphics g)
	{
		g.setColor(gray);												// 鏡の表示
		g.fillRect(0,  0,30,100);
		g.fillRect(0,110,30, 50);
		dsp_b(10, 32,0,0,1);											// "反射光" の表示
		dsp_b(10,116,1,0,1);											// "干渉光" の表示
		dsp_btn();														// ボタンの表示
	}

	public void run()
	{
		while(true)
		{
			dsp_wave();
			try
			{
				Thread.sleep((Run && Mc==0)?Wait:64);
			}
			catch (InterruptedException e){};
			if(Run) Pl++;												// 波を動かす
			if(Ms==0 && Mx>0) Mx--;										// 鏡面の移動
			if(Ms==1 && Mx<23) Mx++;
		}
	}

	public boolean mouseDown(Event e, int x, int y)						// マウスがクリックされたときの処理
	{
		if(y>177 && (x<58 || inside(x,152,238)))
		{
			Ms=(x-2)/30;												// クリックされたボタン No.
			if(Ms==0 && Mx>0) Mc=-1;									// ← ボタン
			if(Ms==1 && Mx<23) Mc=1;									// → ボタン
			if(Ms==5 && Wait<512) Wait*=2;								// << ボタン
			if(Ms==6) Run=!Run;											// |> ボタン
			if(Ms==7 && Wait>8) Wait/=2;								// >> ボタン
			dsp_btn();													// ボタンの表示
		}
		return true;
	}
	
	public boolean mouseUp(Event e, int x, int y)						// クリックが終わったときの処理
	{
		if(Ms>=0)
		{
			Ms=-1; Mc=0;
			dsp_btn();
		}
		return true;
	}
}
//
戻る