import java.applet.*;
import java.awt.*;
import java.util.*;

public class flagpole extends Applet implements Runnable
{
	private Thread	 m_flagpole = null;
	int width,height,gy,gh,sy,hy,polex=150,poley=60,poleh,flagx=150,flagy=70,flagw=140,flagh=100;
	int px=500,py=430,n=0,nn=0,nmax=100,pmax,cl,nl=3,l=0,sh=0,nf=0,nw=0,ic=0,lw=0;
	int[] pp=new int[nmax];
	int[] dp=new int[nmax];
	int[] xp=new int[nmax];
	int[] ppmax=new int[nmax];
	Color grassclr=new Color(128,240,160),bgclr=new Color(64,92,240),
		skyclr=new Color(160,196,255),flagclr=new Color(224,64,64),
		poleclr=new Color(192,192,192),cloudclr=new Color(240,240,240),
		sunclr=new Color(240,228,100),skinclr=new Color(255,198,185),
		bodyclr=new Color(64,128,192),mudclr=new Color(128,80,40),
		fontclr=new Color(255,255,0);
	Graphics bg;
	Image buf,grass;
	Font font=new Font("Helvetica",Font.BOLD,18);
	Font flagfont=new Font("Helvetica",Font.BOLD,15);
	FontMetrics fm;
	int[] k,flagkey;
	boolean flagmore=true,first=true,wordflag=false,mouseflag=true;
	String wordstr = "",word="";
	String[] words=new String[500];


	public flagpole()
	{
	}

	public String getAppletInfo()
	{
		return "Name: flagpole\r\n" +
		       "Author: Anthony Michael Affer\r\n";
	}


	public void init()
	{
		wordstr = getParameter("wordstr");
		StringTokenizer st=new StringTokenizer(wordstr,",");
		n=0;
		while(st.hasMoreTokens())words[nw++]=st.nextToken().toUpperCase();
		width=Integer.parseInt(getParameter("width"));
		height=Integer.parseInt(getParameter("height"));
		buf=createImage(width,height);
		bg=buf.getGraphics();
		bg.setFont(font);
		fm=bg.getFontMetrics();
		k=new int[nmax];
		flagkey=new int[500];
		gy=height-70;
		sy=200;
		hy=sy-20;
		pmax=px-polex+py-poley;
		poleh=height-110;
		buf=createImage(width,height);
		bg=buf.getGraphics();
		// construct grass image
		int h=height-hy;
		grass=createImage(width,h);
		Graphics g=grass.getGraphics();
		drawgrass(width,h,g);
		resize(width,height);
	}

	public void drawgrass(int gw, int gh, Graphics gg){
		Color mudclr=new Color(128,80,40);
		Color[] grassclrs={new Color(64,160,120),new Color(160,192,64),
		new Color(64,192,192),new Color(80,192,192),new Color(96,192,96),
		new Color(64,192,80),new Color(80,192,64)};
		gg.setColor(mudclr);
		gg.fillRect(0,0,gw,gh);
		int x,y,yy,xx,p,z,i,j,yo=50,h=gh+yo;
		for(z=4000;z>=0;z--){
			p=(1000*h)/(h+z);
			if(z==200){
				// draw flagpole stub
				gg.setColor(poleclr);
				gg.fillRect(polex,0,12,p*h/1000+yo);
				gg.setColor(Color.white);
				gg.drawLine(polex+7,0,polex+7,p*h/1000+yo);
				gg.drawLine(polex+8,0,polex+8,p*h/1000+yo);
				gg.drawLine(polex+9,0,polex+9,p*h/1000+yo);}
			for(i=0;i<30;i++){
				x=(int)((double)gw*Math.random());
				y=(int)((double)7*Math.random())+3;
				yy=(int)((double)10*Math.random())+5;
				xx=(int)((double)15*Math.random())-8;
				j=(int)((double)grassclrs.length*Math.random());
				gg.setColor(grassclrs[j]);
				gg.drawLine(x,p*h/1000-yo,x,p*(h-y)/1000-yo);
				gg.drawLine(x,p*(h-y)/1000-yo,x+p*xx/1000,p*(h-y-yy)/1000-yo);}}
	}

	public void destroy()
	{
	}

	public void update(Graphics g){
		paint(g);
	}

	public void paint(Graphics g)
	{
		bg.setColor(bgclr);
		bg.fillRect(0,0,width,height);
// draw grass
		bg.drawImage(grass,0,hy,this);
// draw sky	with clouds and sun
		bg.setColor(skyclr);
		bg.fillRect(0,0,width,sy);
		bg.setColor(sunclr);
		bg.fillOval(440,4,50,50);
		bg.setColor(cloudclr);
		drawcloud(80,10,120);
		drawcloud(360,20,100);
		// draw flagpole
		bg.setColor(poleclr);
		bg.fillRect(polex,poley,12,poleh-20);
		bg.setColor(Color.white);
		bg.drawLine(polex+7,poley,polex+7,poley+poleh-20);
		bg.drawLine(polex+8,poley,polex+8,poley+poleh-20);
		bg.drawLine(polex+9,poley,polex+9,poley+poleh-20);
		// draw flag
		bg.setColor(flagclr);
		bg.fillRect(flagx-flagw,flagy,flagw,flagh);
		// draw People
		int x,y;
		for(int i=0;i<n;i++){
			y=py;
			x=px-pp[i];
			if(x<xp[i]){
				x=xp[i];
				y=py-(pp[i]-(px-x));}
			people(x,y,i);}
		// draw flag message
		bg.setFont(flagfont);
		FontMetrics ffm=bg.getFontMetrics();
		sh=ffm.getHeight();
		bg.setColor(fontclr);
		x=flagx-flagw+5;
		y=flagy+sh;
		int cw=5;
		for(int i=0;i<nf;i++){
			String ci=(new String(""+(char)flagkey[i])).toUpperCase();
			cw=ffm.stringWidth(ci);
			if(x+cw>flagx||flagkey[i]==10){
				x=flagx-flagw+5;
				y+=sh;}
			if(flagkey[i]!=10){
				bg.drawString(ci,x,y);
				x+=cw;}}
		flagmore=(y<=flagy+flagh&&(y+sh<=flagy+flagh||x+cw<=flagx));
		g.drawImage(buf,0,0,this);
	}

	public void drawcloud(int x,int y, int w){
		int d=3*w/5;
		bg.fillOval(x,y,d,d/2);
		bg.fillOval(x+2*w/5,y,d,d/2);
	}

	public void people(int x,int y,int i){
		bg.setFont(font);
		fm=bg.getFontMetrics();
		bg.setColor(skinclr);
		bg.fillOval(x-6,y-8,12,16);
		bg.setColor(bodyclr);
		bg.fillRect(x-12,y+8,24,20);
		bg.fillRect(x-8,y+28,4,16);
		bg.fillRect(x+4,y+28,4,16);
		if(k[i]!=10&&k[i]!=0){
			String ci=(new String(""+(char)k[i])).toUpperCase();
			bg.setColor(fontclr);
			bg.drawString(ci,x-fm.stringWidth(ci)/2,y+14+fm.getHeight()/2);}
	}

	public void start()
	{
		if (m_flagpole == null)
		{
			m_flagpole = new Thread(this);
			m_flagpole.start();
		}
	}
	
	public void stop()
	{
		if (m_flagpole != null)
		{
			m_flagpole.stop();
			m_flagpole = null;
		}
	}

	public void run()
	{
		while (true)
		{
			try
			{
				repaint();
				for(int i=0;i<n;i++){
					if(pp[i]>ppmax[i]){
						dp[i]=0;
						if(k[i]!=0){
							if(mouseflag&&!flagmore){
								nf=0;
								flagmore=true;}
							if(flagmore)flagkey[nf++]=k[i];
							k[i]=0;}}
					if(pp[i]<0)dp[i]=1;
					pp[i]+=dp[i];}
				Thread.sleep(10);
			}
			catch (InterruptedException e)
			{
				stop();
			}
		}
	}

	public boolean mouseDown(Event evt, int x, int y)
	{
		if(flagx-flagw<x&&x<flagx&&flagy<y&&y<flagy+flagh){
			nf=0;
			first=false;
			return true;}
		if(first){
			first=false;
			return true;}
		mouseflag=true;
		if(!wordflag){
			int i=(int)((double)nw*Math.random());
			word=words[i];
			ic=0;
			lw=word.length();
			wordflag=true;}

		if(ic<lw)k[nn]=(int)word.charAt(ic);
		else k[nn]=10;
		ic++;
		if(ic>lw)wordflag=false;
		dp[nn]=1;
		pp[nn]=0;
		ppmax[nn]=(int)((double)18*Math.random())-18/2+pmax;
		xp[nn++]=(int)((double)18*Math.random())+polex;
		if(n<nmax-1)n++;
		if(nn>=nmax)nn=0;


		return true;
	}

	public boolean mouseUp(Event evt, int x, int y)
	{
		return true;
	}

	public boolean mouseDrag(Event evt, int x, int y)
	{
		return true;
	}

	public boolean mouseMove(Event evt, int x, int y)
	{
		return true;
	}

		public boolean keyDown(Event evt,int key)
	{
		mouseflag=false;
		k[nn]=key;
		dp[nn]=1;
		pp[nn]=0;
		ppmax[nn]=(int)((double)18*Math.random())-18/2+pmax;
		xp[nn++]=(int)((double)18*Math.random())+polex;
		if(n<nmax-1)n++;
		if(nn>=nmax)nn=0;
		return true;
	}

}
