import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.util.Vector;
import java.net.*;

// ******************************************************

abstract class Sprite 
{
        SpriteApplet myApplet;                                                                 
        int x, y, w, h;                                                                                

        Sprite(SpriteApplet applet) { myApplet = applet; }  
        
        void move() {}                                                                                         
        void draw(Graphics g) {}                                                               
        boolean handleEvent(Event e) { return false; }  
}


// ******************************************************

public class SpriteApplet extends Applet implements Runnable
{       
        
        int frameRate = 20;                                                                             
        int frameDelay = 1000/frameRate;                                

        boolean stop  = false;                                                                  
        
        
        Image backBuffer;                                                                               
        Graphics backGraphics;                                                                  
        int w, h;                                                                                                      

        Vector sprites = new Vector();                                                                          
        void addSprite(Sprite s) { sprites.addElement(s); }
        void setSpriteAt(Sprite s, int index) { sprites.setElementAt(s, index); }
        void insertSpriteAt(Sprite s, int index) { sprites.insertElementAt(s,index); }
        void removeSprite(Sprite s) { sprites.removeElement(s); }
        void removeSpriteAt(int index) { sprites.removeElementAt(index); }
        void removeAllSprites() { sprites.removeAllElements(); }
        
                
        public void init()                                                                                                     
        {
                
               
                w = this.size().width;
                h = this.size().height; 
                backBuffer   = createImage(w,h);                               
                backGraphics = backBuffer.getGraphics();              
                                                                                                                                                
        }
        
        public void start() { (new Thread(this)).start();}                              
                                                                                                                                                              
        
        public void stop()                                                                                    
        {                                                                                                               
                sprites.removeAllElements();                                           
                sprites = null;                                                                                 
                this.stop = true;
                                                                              
        }       
        
        public void destroy()                                                                        
        { 
                backBuffer = null;                                                                              
                backGraphics.dispose();                                                        
        }

        
        void paintBackdrop(Graphics g) { g.clearRect(0,0,w,h); }        

        public void paint(Graphics g) { update(g); }    
                                                                                                                                      
        
        public void update(Graphics g)                                                                         
        { 
                if (w!=this.size().width || h!=this.size().height)                    
                {                                                                                                                                                              
                        backGraphics.dispose();
                        w = this.size().width;
                        h = this.size().height;         
                        backBuffer   = createImage(w,h);
                        backGraphics = backBuffer.getGraphics();                        
                }
                
                paintBackdrop(backGraphics);                                                                            
                
                for (int i=0; i<sprites.size(); i++)                                                   
                        (( Sprite) sprites.elementAt(i)).draw(backGraphics);    
                
                g.drawImage(backBuffer, 0, 0, null);                                      
        }


        public void run()
        {
                while (!this.stop)                                                                                                                      // test flag
                {
                        for (int i=0; i< sprites.size(); i++)  
                                ( (Sprite) sprites.elementAt(i)).move();                                        
                        repaint();
                        try {Thread.sleep(frameDelay);} catch (Exception e) {} 
                
                }
                
        }
        

        public boolean handleEvent(Event e)
                                                                        
        {
                for (int i = sprites.size() - 1; i>=0; i--)                                     
                  if (((Sprite) sprites.elementAt(i)).handleEvent(e))  
                  { return true;}
                return false;
                
        }

}
// ***********************************************************



// *******************************************************************

class Banner extends Sprite
{
        String label;
        int labelWidth;
        int rate = 6;
        Font f = new Font("Helvetica", Font.BOLD, 36);
        FontMetrics fm = myApplet.getFontMetrics(f);
        int textAscent = fm.getAscent();

        Banner(SpriteApplet applet, String label) 
        { 
                super(applet);
                this.label = label;
                labelWidth = fm.stringWidth(label);
                y = (myApplet.h + textAscent)/2;
                x =  myApplet.w;
        }

        public void move()
        {
                y = (myApplet.h + textAscent)/2;
                x = x - rate;
                if (x < - labelWidth) x = myApplet.w;           
        }
        
        public void draw(Graphics g)
        {
                
                if( myApplet.sprites.size()<=2)
                {
                g.setFont(f);
        
                g.setXORMode(Color.magenta);
                g.drawString(label, x , y );
                g.setPaintMode();
                }
        }
}

// **********************************************


class ButtonMakesBubbles extends Sprite 

{
        boolean isOut = true;

        ButtonMakesBubbles(SpriteApplet applet) { super(applet);}
        
        public void draw(Graphics g)

        {

                g.setColor(new Color(0,200,0));
        
                if (isOut) {g.fill3DRect(450,450,193,50,true);}
        		else   g.fill3DRect(450,450,193,50,false);
                
        
                        g.setColor(Color.black);
                        g.drawString("mo'pandas",450,480);
        }       
        
        public boolean handleEvent(Event e)
        {
                
                if (e.id==Event.MOUSE_DOWN)
                {
                        if (new Rectangle(450, 450, 193 ,50).inside(e.x, e.y))
                        
                        {
                                myApplet.showStatus("clicked");
                                isOut = false;
                                myApplet.addSprite(new Panda(myApplet));
                                
                                
                                return true;
                        
                        }
                        
                }
                

                
                if (e.id==Event.MOUSE_UP)
                
                {
                          myApplet.showStatus("released");
                        isOut = true;
                        return true;                    
                }
                
        
                return false;
        }
        
}


// ********************************************



public class PandaApplet extends SpriteApplet
{       
        Image bamboo, panda, burger;
        
        AudioClip rattler, sheep;

        public void init()      
        {
        	super.init();                                                                
        	bamboo = getImage(getCodeBase(),"bamboo3.jpg");
        	rattler = getAudioClip(getCodeBase(),"Rattler.au");
        	burger= getImage(getCodeBase(),"burger.gif");
        	panda=getImage(getCodeBase(),"panda56.gif");
            sheep = getAudioClip(getCodeBase(),"Sealion.au");
            addSprite(new Banner(this, "PANDAS ? ...AIN'T NO PANDAS HERE, BOY.....PANDAS ? ...AIN'T NO PANDAS HERE, BOY"));
            addSprite(new ButtonMakesBubbles(this));
            rattler.loop();
          		}
			public void stop()
			{
			rattler.stop();              
       	 
       	 }
        
       
        
        void paintBackdrop(Graphics g)
        {
        	g.drawImage(bamboo,0,0,650,650,this);
        
        }
        
        
        int random(int r) {return (int) Math.floor(Math.random()*r);}
}

class Panda extends Sprite
{
	int movement_rate;
	boolean isburger;
	boolean isMoving = true;
	Panda(SpriteApplet a)
	{
		super(a);
		x=((PandaApplet)myApplet).random(500);
		y=((PandaApplet)myApplet).random(500);
		isburger=false;
		
		  movement_rate  = (int) Math.floor(Math.random()*6) + 1 ;

	}
	void draw(Graphics g)
	{
		if (isburger) { g.drawImage(((PandaApplet)myApplet).burger,x,y,null);}
		
		else { g.drawImage(((PandaApplet)myApplet).panda,x,y,null);}
		}	
	public void move()							
	{
		if (isMoving)
		{
			x = x - movement_rate;
			if (x<-this.w)
			{
				x= myApplet.w + this.w;
				x = (int) Math.floor(Math.random()*(myApplet.w + this.w));
			}
		}
	}
	

	
	public boolean handleEvent(Event e)
    {
    	if (e.id==Event.MOUSE_DOWN)
        {
            if (new Rectangle(x, y, 100 ,100).inside(e.x, e.y))
           	{
                ((PandaApplet)myApplet).sheep.play();
                if (isburger) { myApplet.removeSprite(this);}
                else {isburger=true;}
                return true;
           	}
            
         }
        return false;
     }
     
            
}

public class TrivialApplet extends PandaApplet
{
	public void init()
	{
		super.init();
	}
	
	
}