//
/* ---------------------------------------------------------------------------------------------------
	opt_mouse.java	光学式マウス										ver. 3.00 (JDK 1.02)
																		ueyama@infonet.co.jp  2004.05.23
																		update: 2007.09.21
--------------------------------------------------------------------------------------------------- */
import java.applet.*;
import java.awt.*;

public class opt_mouse extends Applet
{
	int			Mx =63,My =63;											// マウスセンサの初期位置
	int			Mbx=63,Mby=63;											// 同上バックアップ
	int			Mcx=63,Mcy=63;											// クリックされたときの座標
	int			Mdx=63,Mdy=63;											// ドラッグ中のマウスセンサの位置
	int			Tx=468, Ty=113;											// テキストデータ基準表示座標
	int			Dx=144, Dy=144;											// マウス移動量
	Image		Img, Buf;
	Graphics	gr;
	
	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){};
		gr=getGraphics();
		Buf=createImage(144,144);
	}

	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_view(int x, int y, int c, Graphics g)				// マウスセンサの視野 (枠) の表示
	{
		if(c==0) g.setColor(new Color(255,255, 51));					// 新・視野色
		if(c==1) g.setColor(new Color(255,255,204));					// 旧・視野色
		g.drawRect(x-1, y-1,145,145);
		g.drawRect(x, y,143,143);
	}

	public void del_view(int x, int y)									// センサ枠の消去
	{
		dsp_bg(x, y, 146, 2, x, y);
		dsp_bg(x, y, 2, 146, x, y);
		dsp_bg(x, y+144, 146, 2, x, y+144);
		dsp_bg(x+144, y, 2, 146, x+144, y);
	}
	
	public void dsp_bg(int x, int y, int w, int h, int ox, int oy)		// 画像の部分表示
	{
		Graphics gx=getGraphics();
		gx.clipRect(x, y, w, h);
		gx.drawImage(Img, x-ox, y-oy, this);
		gx.dispose();
	}

	public void dsp_g(int x, int y, int m, int n, int c)				// 数字・文字の表示
	{
		int w=0, h=0, ox=0, oy=0;
		switch(c)
		{
			case  0: w= 26; h= 16; ox=  0; oy=270; break;				// 数字
			case  1: w= 13; h= 16; ox= 78; oy=318; break;				// 符号
			case  2: w= 16; h= 16; ox=104; oy=318; break;				// "縦"・"横"
			case  3: w= 27; h= 11; ox=139; oy=318; break;				// "ドット"
			case  4: w= 45; h= 13; ox=168; oy=318; break;				// "移動量"
			case  5: w= 56; h= 11; ox=214; oy=318; 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_mouse()												// マウス位置の表示
	{
		int mx=0, my=0, dx=Mdx-Mx, dy=Mdy-My;
		Graphics gx=getGraphics();
		gx.clipRect(0, 0, 270, 270);
		dsp_view(Mx, My, 1, gx);										// 移動前のマウス視野(枠)の表示
		dsp_view(Mdx, Mdy, 0, gx);										// 移動後
		gx.setColor(new Color(255,187,0)); 								// 新旧共通部分の表示
		gx.drawRect(Math.max(Mdx,Mx)-1, Math.max(Mdy,My)-1, Dx+1,Dy+1);	// 長方形を描く
		gx.drawRect(Math.max(Mdx,Mx), Math.max(Mdy,My), Dx-1,Dy-1);
		gx.dispose();
		dsp_g(342,216,0,0,5);											// "センサ画像" の表示
		Graphics gs=Buf.getGraphics();									// バッファを準備する
		gs.clearRect(0, 0, 144, 144);
		gs.clipRect(0, 0, 144, 144-(Mdy-126));
		gs.drawImage(Img, -Mdx, -Mdy, this);							// バッファにセンサ画像を描く
		gs.setColor(new Color(255,204,0)); 								// 共通部分の枠を作成
		gs.drawRect( ((dx>0)?0:144-Dx),((dy>0)?0:144-Dy), Dx, Dy);		// 枠をバッファに描く
		gs.drawRect( ((dx>0)?1:143-Dx),((dy>0)?1:143-Dy), Dx, Dy);
		gs.dispose();
		gr.drawImage(Buf,297, 63,this);									// バッファの表示
		gr.setColor(new Color(99,99,99)); 								// センサ画像部の枠の表示
		gr.drawRect(296,62,145,145);
		if(Dx>0 && Dy>0)												// マウス移動量データの表示
		{
			mx=(144-Dx)/9; my=(144-Dy)/9;
			dsp_g(Tx+14,Ty+20,(Mx>Mdx)?0:1,0,1);						// 横方向符号
			dsp_g(Tx+26,Ty+20,mx%10,mx/10,0);							//   〃  数字
			dsp_g(Tx+14,Ty+70,(My>=Mdy)?1:0,0,1);						// 縦方向符号
			dsp_g(Tx+26,Ty+70,my%10,my/10,0);							//   〃  数字
		}
		else gr.clearRect(485,132,35,67);
	}

	public void paint(Graphics g)
	{
		Mx=Mbx; My=Mby;
		g.clearRect(0, 0, size().width, size().height);
		g.drawImage(Img,0,0,this);
		dsp_g(490, 70,0,0,4);											// "移動量"
		dsp_g(Tx,   Ty,   1,0,2);										// "横"
		dsp_g(Tx+58,Ty+25,0,0,3);										// "ドット"
		dsp_g(Tx   ,Ty+50,0,0,2);										// "縦"
		dsp_g(Tx+58,Ty+75,0,0,3);										// "ドット"
		dsp_mouse();													// マウス位置の表示
	}

	public boolean mouseDown(Event e, int x, int y)						// マウスがクリックされたときの処理
	{
		if(inside(x,Mx,Mx+144) && inside(y,My,My+144))					// 視野内であれば (144=16×9)
		{
			Mcx=x; Mcy=y;
			del_view(Mbx-1, Mby-1);										// 旧センサ枠の消去
		}
		return true;
	}

	public boolean mouseDrag(Event e, int x, int y)						// マウスがドラッグされたときの処理
	{
		if(inside(x,Mdx,Mdx+144) && inside(y,Mdy,Mdy+144))				// 視野内であれば
		{
			del_view(Mdx-1, Mdy-1);										// センサ枠の消去
			Mdx=(Mx+x-Mcx)/9*9; Mdy=(My+y-Mcy)/9*9;						// センサ位置 (9 の整数倍化する)
			Dx=144-Math.abs(Mx-Mdx); Dy=144-Math.abs(My-Mdy);			// マウスの移動量
			dsp_mouse();												// マウス位置の表示
		}
		return true;
	}

	public boolean mouseUp(Event e, int x, int y)						// マウスが離されたときの処理
	{
		if(inside(x,Mdx,Mdx+144) && inside(y,Mdy,Mdy+144))
		{
			Mbx=Mx; Mby=My; Mx=Mdx; My=Mdy;
		}
		return true;
	}
}
//
戻る