//
/* ----------------------------------------------------------------------------------------------
    phone.java			電話								ver. 1.10 (JDK 1.02)
    														ueyama@infonet.co.jp  2000.02.20
---------------------------------------------------------------------------------------------- */

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


class fade extends RGBImageFilter
{
	int tp;
	
	public fade(int tp)
	{
		canFilterIndexColorModel=true;
		this.tp=tp;
	}
	
	public int filterRGB(int x, int y, int rgb)
	{
		int c=rgb & 0x00ffffff;
		int a=(tp<<24) & 0xff000000;
		return (a | c);
	}
}

public class phone extends Applet implements Runnable
{
	int			Pq=0;												// 使用中電話機数
	int			Pn=9;												// 電話機番号
	int			Cn=9;												// 呼出電話番号
	int			Snd=9;												// 送信電話番号
	int			Rcv=9;												// 受信電話番号
	boolean		Busy[]=new boolean[10];								// true:  ネットワーク使用中
	boolean		Call, Talk;
	Image		Img;
	Image		Tel;
	AudioClip	Ac[]=new AudioClip[15];
	int			Code[]={0,0,0,0,0};
	int			Cx[][]={{ 77, 77,337},{217,217,347},{357,357,357},{497,367,367},{637,377,377}};
	int			Cy[][]={{173,216,221},{173,206,211},{173,206,211},{173,206,211},{173,216,221}};
	int			Cw[][]={{  5,265,  5},{  5,135,  5},{  5,  5,  5},{  5,135,  5},{  5,265,  5}};
	int			Ch[][]={{ 43,  5, 18},{ 33,  5, 28},{ 33,  5, 28},{ 33,  5, 28},{ 43,  5, 18}};
	int			Ph=76;
	int			At=999;
	int			Px[]=new int[59*62];
	int			Wait=64;
	int			N=0;
	int			Col;
	String		Bg;
	Thread		th=null;
	Graphics	gr;
	
	public void start()
	{
		if(th==null)
		{
			th=new Thread(this);
			th.start();
		}
	}
	
	public void init()
	{
		int i,j;
		for(i=0;i<10;i++) Busy[i]=false;
		Call= Talk=false;
		Bg=getParameter("BgColor");
		Col=Integer.valueOf(Bg,16).intValue();
		setBackground(new Color(Col)); 
		gr=getGraphics();
		String ph=getParameter("path");
		
		for(i=0,j=1;i<12;i++,j++)
		{
			Ac[i]=getAudioClip(getCodeBase(), ph+"p"+j+".au");
			Ac[i].play(); Ac[i].stop();
		}
		Ac[12]=getAudioClip(getCodeBase(), ph+"wait.au");
		Ac[12].play(); Ac[12].stop();
		Ac[13]=getAudioClip(getCodeBase(), ph+"call.au");
		Ac[13].play(); Ac[13].stop();
		Ac[14]=getAudioClip(getCodeBase(), ph+"busy.au");
		Ac[14].play(); Ac[14].stop();

		MediaTracker mt=new MediaTracker(this);
		Img=getImage(getCodeBase(), getParameter("figure"));
		mt.addImage(Img, 0);
		try
		{
			mt.waitForID(0);
		}
		catch(InterruptedException e){};
		get_img(0);
	}

	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= 79; h= 97; ox=  0; oy=  0; break;			// 電話機
			case  1: w= 33; h= 75; ox=395; oy=  0; break;			// 受話器
			case  2: w= 22; h= 75; ox=415; oy= 75; break;			// 受話器台
			case  3: w= 17; h= 24; ox=525; oy= 75; break;			// コード
			case  4: w=  9; h= 10; ox=436; oy=150; break;			// ボタン
			case  5: w=  9; h= 10; ox=328; oy=150; break;			// ボタン
			case  6: w= 59; h= 62; ox=  0; oy= 97; break;			// ひと
			case  7: w= 24; h= 24; ox=295; oy=121; break;			// 電話番号
			case  8: w= 24; h= 24; ox=295; oy= 97; break;			// 電話番号
			case  9: w= 33; h= 11; ox=295; oy=149; break;			// "交換機"
			case 10: w= 35; h= 50; ox=525; oy= 99; break;			// 音マーク
		}
		gx.clipRect(x,y,w,h);
		if(n==7) gx.clearRect(x,y,w,h);
		gx.drawImage(Img,x-(ox+w*c),y-oy,this);
		gx.dispose();
	}
	
	public void dsp_p(int i)										// 電話機の表示
	{
		dsp_g(i*140+40,Ph,0,i);
		dsp_g(i*140+45,Ph+102,(i==Snd)?8:7,i);
		if(Busy[i])
		{
			dsp_g(i*140,Ph+12,1,i); dsp_g(i*140+45,Ph+11,2,i);
			dsp_g(i*140+23,Ph+86,3,Code[i]);
		}
		else
		{
			gr.setColor(new Color(Col));
			gr.fillRect(i*140,Ph+12,40,98);
		}
	}
	
	public int dsp_b(int mx, int my, int c)
	{
		int k=0, m=0, p=0, q=0;
		my-=Ph;
		if(inside(mx%140,70,83) || inside(mx%140,85,98) || inside(mx%140,100,113))
		{
			p=(mx%140-70)/15;
			m+=p; k++;
		}
		if(inside(my,27,40) || inside(my,42,55) || inside(my,57,70) || inside(my,72,85))
		{
			q=(my-27)/15;
			m+=q*3; k++;
		}
		if(k>0) dsp_g((mx/140)*140+p*15+72, q*15+30+Ph, c, m);
		return m;
	}

	public void dsp_line(boolean c)									// 通信回線の表示
	{
		int i,j;
		gr.setColor(new Color(214,214,214));
		gr.fillRect(332,229,55,25);
		for(i=0;i<5;i++)
		{
			if(i==Snd || i==Rcv) gr.setColor(new Color(((c)?N%2:1)*153,0,0));
			else	 			 gr.setColor(new Color((Busy[i])?153:0,0,0));
			for(j=0;j<3;j++)	 gr.fillRect(Cx[i][j],Cy[i][j],Cw[i][j],Ch[i][j]);
		}
	}
	
	public void dsp_x(int c)										// 交換機の接続の表示
	{
		int i=(SndCn)?Snd:Cn;
		if(i<5 && j<5)
		{
			if(c>0)	gr.setColor(new Color(153,0,0));
			else	gr.setColor(new Color(0,0,0));
			gr.fillRect(Cx[i][2],239,5,5);
			gr.fillRect(Cx[j][2],239,5,5);
			gr.fillRect(Cx[i][2],244,Cx[j][2]-Cx[i][2]+5,5);
		}
	}
	
	public void get_img(int i)
	{
		PixelGrabber pg=new PixelGrabber(Img, i*59, 97, 59,62, Px, 0, 59);
		try
		{
			pg.grabPixels();
		}
		catch (InterruptedException ie) {}
		Tel=createImage(new MemoryImageSource(59,62,Px,0,59));
	}
	
	public void paint(Graphics g)
	{
		int i;
		for(i=0;i<5;i++)
		{
			dsp_p(i);												// 電話機の表示
			if(Busy[i]) dsp_g(i*140+40,0,6,i);						// ひとの表示
		}
		dsp_g(398,236,9,0);											// "交換機" の表示
		dsp_line(false);											// 電話回線の表示
	}
	
	public void run()
	{
		int k;
		boolean f=false;
		while(th!=null)
		{
			if(inside(At,0,255))
			{
				ImageFilter imgf=new fade(At);
				ImageProducer pr=new FilteredImageSource(Tel.getSource(), imgf);
				Image fi=createImage(pr);
				MediaTracker mt=new MediaTracker(this);
				mt.addImage(fi, 1);
				try
				{
					mt.waitForID(1);
				}
				catch(InterruptedException e){};
				gr.setColor(new Color(Col));
				gr.fillRect(Pn*140+40,0,59,62);
				gr.drawImage(fi,Pn*140+40,0,this);
				
				At+=(Busy[Pn])?31:-31;
				if(inside(At, 10,  0)) At=0;
				if(inside(At,245,255)) At=255;
			}
			if(Call)
			{
				if(N%30==0) Ac[13].play();
				if(N%30<=10)
				{
					gr.setColor(new Color(Col));
					if(N%2==0)	gr.fillRect(Cn*140+62,12,35,50);
					else		dsp_g(Cn*140+62,12,10,0);
				}
			}
			dsp_line((Talk)?true:false);
			if(Call || Talk) dsp_x((Talk)?N%2:1);
			try
			{
				th.sleep(100);
			}
			catch (InterruptedException e){}
			N++;
		}
	}
	
	
	public boolean mouseDown(Event e, int mx, int my)
	{
		Random rnd=new Random();
		int i=mx/140, k=0, x=(mx-((Busy[i])?0:45))%140;
		if(inside(my-Ph, 11, 88) && inside(x, 0, ((Busy[i])?33:22)))	// 受話器をクリック
		{
			get_img(i);
			Busy[i]=!Busy[i];
			if(Busy[i]) Pq++; else Pq--;
			Code[i]=Math.abs(rnd.nextInt())%2;
			At=(Busy[i]?93:255);
			if(Pq==0)
			{
				Snd=9; Rcv=9; Call=false; Cn=9;
				Ac[14].stop(); Ac[12].stop();
			}
			else if(Pq==1)
			{
				if(Rcv>5 && Busy[i]) Snd=i;
				if(Cn>5) Ac[12].loop();
			}
			else if(Pq>1 && Cn==i && i!=Snd)
			{
				Rcv=i; Talk=true; Call=false;
			}
			if(i==Cn && !Busy[i]) Cn=9;
			if((i==Rcv || i==Snd) && !Busy[i])
			{
				Talk=false;
				if(i==Rcv) Rcv=9;
				else
				{
					Snd=9; Call=false;
				}
			}
			dsp_p(i);
			Pn=i;
		}
		x=mx%140;
		if(inside(my-Ph, 28, 86) && inside(x, 70, 113) && Busy[i])	// ボタンをクリック
		{
			k=dsp_b(mx, my, 4);										// k: ボタンの番号
			Ac[k].play();
			if(i==Snd && k<5 && !Talk && !Call)
			{
				if(k!=Snd && !Busy[k])
				{
					Cn=k;
					Call=true;
					Ac[14].stop();
					Ac[12].stop();
				}
				else Ac[14].loop(); 
			}
		}
		return true;
	}
	
	public boolean mouseUp(Event e, int mx, int my)
	{
		int i=mx/140, m=-1, x=mx%140, p=0, q=0;
		if(inside(my-Ph, 11, 88) && inside(x, 0, ((Busy[i])?33:22)))	// 受話器をクリック
		{
			gr.setColor(new Color(Col));
			gr.fillRect(i*140+40,0,59,62);
		}
		if(inside(my-Ph, 28, 86) && inside(x, 70, 113) && Busy[i]) dsp_b(mx, my, 5);
		return true;
	}
	
	public void stop()
	{
		if(th!=null)
		{
			th.stop();
			th=null;
		}
	}
}
//
戻る