/*
    Roaches.
    
    This file contains the Roach class for chapter
    APP -- Java 6 -- What do you want to do?  (C)opyright 2009
    SoftWarr, Steven P. Warr
    
    This program is in the public domain and may be copied, modified and 
    distributed so long as this documentation is included and the date,
    name of the person doing the modifications and scope of the modifications 
    are included.  This code MAY NOT be sold. 
*/	
import javax.swing.JOptionPane;					
import java.util.*;
import javax.imageio.*;
import java.awt.*;								
import java.awt.event.*;								
import java.io.*;   //for files						
import java.applet.*;
import java.net.*;
import java.net.URL;
public class Roach extends Applet implements KeyListener, MouseListener
{
//declare instance fields

// direction constants

    final static int N = 0,NE = 1,E = 2,SE = 3, S = 4, SW = 5, W = 6, NW =7,STILL = 8;

    int delay = 100;                 // each cycle is 1/10 second 
    int numImages = 36;              // number of gif images for 360 degrees
    boolean gameNotOver = true;      // end game when false
    boolean poisonOn = false;        // bug spray is used when true
    int  mouseX, mouseY;             // mouse coordinates
    int score = 0;                  
    int loopCount = 0;               // Number of times the loop has executed
    int numBugs = 30;                // Maximum number of roaches
    Bug [] roach = new Bug[numBugs]; // Array of roaches
    int numAlive = numBugs;          // Number of visible roaches
    Image buff;                      // for double Buffer
    int scoreMod = 50;               // for score calculation
    String [] names = new String[10];// names for high score list
    String name = "";                // name os current player
    int scores [] = new int[10];     // List of top ten scores
   
public void init()
{       
   for (int x = 0; x <numBugs;x++)
        {
        	roach[x] = new Bug((int)(Math.random() * 900) +50,  // x coordinate
        	                   (int)(Math.random() * 600) + 50, // y coordinate
        	                   (int)(Math.random() * 50) -25,   // speed x
        	                   (int)(Math.random() * 50) -25,   // speed y
        	                   "bug",                // file name
        	                   numImages,                       // number of images        	                                      
        	                   0);                              // score
        	roach[x].setBugDimensions(80,80);  //width and height of images                 
        }
   roach[0].setBugDimensions(80,80);	// width and height of ball
   addKeyListener(this);    	    	// Enable keyboard input	
   addMouseListener(this);    	        // Enable mouse input
   name = JOptionPane.showInputDialog("Enter your name","Name");
   setVisible(true);
   
   do         //Game loop
     {
	    loopCount++;
	    if (loopCount % 4 == 0 && scoreMod > 1)
	        scoreMod --;
   	    roach[0].upDate();
        for (int x = 1; x <numBugs;x++)
	        {
	    	    roach[x].upDate();
	    	    if (poisonOn)  // bug spray activated
	    	       {
	    	       	   
	    	       	   if (roach[x].x > mouseX-roach[x].width*3/2 &&
						   roach[x].x < mouseX +roach[x].width/3 &&
						   roach[x].y > mouseY-roach[x].height*3/2 &&
						   roach[x].y < mouseY +roach[x].height/3 &&
						   roach[x].visible)
						     {
						         roach[x].visible = false; // kill roach
						         numAlive --;
						         score += scoreMod * scoreMod;// add score
						     }
				  }
				if (roach[x].visible)   // If a roach is alive see if it hit the ball
				   checkCollision(roach[0],roach[x]);  
		    }		  
	    this.repaint();  // Command to execute the paint and doubleBuffer methods
	    pause(delay);    // pause delay/1000 seconds
      }
   while(numAlive >1);  //ends one round
   this.repaint();  // paint end screen
}// end of mainInput
public void paint(Graphics pen)  // Draws the window
 {                        
	    buff =createImage(getSize().width,getSize().height);  // screen
        Graphics o = buff.getGraphics();                      // size it
        doubleBuffer(o);                                    // execute doubleBuffer
        pen.drawImage(buff,0,0,null);                       // draw the entire screen
        if (poisonOn)                  // pause to see the bug spray
            pause(100);
        poisonOn = false;

  }  
public void doubleBuffer(Graphics pen)
{
//        pen.setColor(Color.black);
//        pen.fillRect(0,0,1024,768);
        for (int x = 1;x<numBugs;x++)      // draw live roaches in memory
           {
                if (roach[x].visible)
                	roach[x].drawBug(pen);
           }
        pen.fillOval(roach[0].x,roach[0].y,80,80); // draw ball  
        pen.setFont(new Font("Timesroman",Font.ITALIC,28));
        pen.drawString("Roaches: "+numAlive + "    Score: "+ score + 
              "  Score mod "+ scoreMod,150,100);
        pen.setFont(new Font("Timesroman",0,60));
        if (numAlive <= 1)                        // draw end game screen
            pen.drawString("Game Over  Score  "+ score,50,500);
        if (poisonOn)   // draw bug spray in memory
           {
           	   for (int x = 0;x< 100;x+=5)
           	      {
           	            pen.drawOval(mouseX- x ,mouseY- x,x*2  ,x*2);
           	      }
           	     
           }

}	 
public void keyPressed(KeyEvent e)
{
  //  setTitle(""+ KeyEvent.getKeyText(e.getKeyCode()));  
    switch(e.getKeyCode())
       {
       	  case KeyEvent.VK_DOWN :roach[0].speedY+=3;
       	                        break; // control ball
       	  case KeyEvent.VK_UP :roach[0].speedY-=3;
       	                        break; // control ball
       	  case KeyEvent.VK_RIGHT :roach[0].speedX+=3;
       	                        break; // control ball
       	  case KeyEvent.VK_LEFT :roach[0].speedX-=3;
       	                        break; // control ball bug[0]
       	  case KeyEvent.VK_SPACE :roach[0].speedX =0;  //stop
       	                           roach[0].speedY =0;
       	                           poisonOn = true;
       	                        break;
       	  case KeyEvent.VK_ESCAPE :gameNotOver = false;
       	                        break;
      	  
       }

}
public  void checkCollision(Bug b1,Bug b2)
{
      int left1 = b1.x;
      int right1 = b1.x + b1.width; 	// if the ball hit the bug
      int top1 = b1.y;
      int bottom1 = b1.y+ b1.height ; 	
      int left2 = b2.x;
      int right2 = b2.x + b2.width; 	
      int top2 = b2.y;
      int bottom2 = b2.y + b2.height; 	
 	  System.out.println(mouseX);

      if ( left2 < right1 &&
           left1 < right2 &&
           top1 < bottom2 &&
           top2 < bottom1)
             {
                 b2.speedX = b1.speedX;  // bug goes with the ball
                 b2.speedY = b2.speedY;
                 b1.speedX = b2.speedX;  // bug goes with the ball
                 b1.speedY = b2.speedY;
                 b1.upDate();
                 b2.upDate();
             }
       
}	
public void keyReleased(KeyEvent e)   //abstract methods MUST be overridden
{
}
public void keyTyped(KeyEvent e)     // whether they are used or not
{
}
public void mouseClicked(MouseEvent m)
{
	
	
}	
public void mouseEntered(MouseEvent m)
{
}	
public void mouseExited(MouseEvent m)
{
}	
public void mousePressed(MouseEvent m)  // spray roaches
{
	 mouseX = m.getX();
     mouseY = m.getY();
     poisonOn = true;

}	
public void mouseReleased(MouseEvent m)
{
}
public void update(Graphics G) // override standard update method for
{                              // doubleBuffer
	  paint(G);
}	    
//  Provided by Matt Nicki the Great
//  MILLISECONDS for all computers.   
public static void pause (long r)
{
	Date d = new Date();
	long mil = d.getTime();
	long save = mil;
	while(mil < save + r)
		{
			d = new Date();
			mil = d.getTime();
		}
}
}

class Bug    //Each roach is a bug  -- not truly object-oriented
{
	int x, y, speedX, speedY,width,height;
	String fileName;
	int direction;
	int score;
	Image [] picture; 
    int numImages;
    boolean visible = true;
    
	public Bug(int xx,int yy, int sX, int sY, String fn,int nI,int sc)
	{
		x = xx;
		y = yy;
		speedX = sX;
		speedY = sY;
		fileName = fn;
		numImages = nI;
		Applet app;
		picture = new Image[numImages];
		//direction = d;
		score = sc;
		String tempName = "";
		for (int x = 0;x<numImages;x++)	
          {		
			try 
			    {
			     if (x<10)
			         tempName = fileName +"0" + x + "0.gif";
			     else
			         tempName = fileName + x + "0.gif";
//		         picture[x] = getImage(tempName);
		         picture[x] = ImageIO.read(new File(tempName));
		   	    }
		   catch (Exception e)
		        {
		              JOptionPane.showMessageDialog(null,
		             "    Click ok to continue"+ e + " " + tempName);
		       }	
		   }   
	}
	public void setBugDimensions(int h,int w)
	  {
	  	  width = w;
	  	  height = h;
	  }	      
   public void upDate()
     {
     	 x += speedX;
     	 y += speedY;
     	 if (x > 950 || x <0)
     	    speedX *= -1;
     	 if (y > 700 || y <0)
     	    speedY *= -1;
     	  
     }
   public void getDirection()  	
      {
      	  double slope = 100;
      	  if (speedX != 0)
	      	   slope =speedY/(double)speedX;
		  slope *= -1;   //y values are reversed
      	  if (speedX>=0 && speedY <=0)
      	      {
      	      	  if (slope > 10)
      	      	     direction = 0;
      	      	  else if (slope > 5)
      	      	     direction = 10;
      	      	  else if (slope > 4)
      	      	     direction = 20;
      	      	  else if (slope > 3)
      	      	     direction = 30;
      	      	  else if (slope > 1)
      	      	     direction = 40;
      	      	  else if (slope > .8)
      	      	     direction = 50;
      	      	  else if (slope > .5)
      	      	     direction = 60;
      	      	  else if (slope > .2)
      	      	     direction = 70;
      	      	  else if (slope > .1)
      	      	     direction = 80;
      	      	  else 
      	      	     direction = 90;
     	      	}     
      	  if (speedX>=0 && speedY >=0)
      	      {
      	      	  if (slope < -10)
      	      	     direction = 180;
      	      	  else if (slope < -5)
      	      	     direction = 170;
      	      	  else if (slope < -4)
      	      	     direction = 160;
      	      	  else if (slope < -3)
      	      	     direction = 150;
      	      	  else if (slope < -1)
      	      	     direction = 140;
      	      	  else if (slope < -.8)
      	      	     direction = 130;
      	      	  else if (slope < -.5)
      	      	     direction = 120;
      	      	  else if (slope < -.2)
      	      	     direction = 110;
      	      	  else if (slope < -.1)
      	      	     direction = 100;
      	      	  else 
      	      	     direction = 90;
     	      	}     
      	  if (speedX<=0 && speedY >=0)
      	      {
      	      	  if (slope > 10)
      	      	     direction = 190;
      	      	  else if (slope > 5)
      	      	     direction = 200;
      	      	  else if (slope > 4)
      	      	     direction = 210;
      	      	  else if (slope > 3)
      	      	     direction = 220;
      	      	  else if (slope > 1)
      	      	     direction = 230;
      	      	  else if (slope > .8)
      	      	     direction = 240;
      	      	  else if (slope > .5)
      	      	     direction = 250;
      	      	  else if (slope > .2)
      	      	     direction = 260;
      	      	  else //if (slope > .1)
      	      	     direction = 270;
     	      	}     
      	  if (speedX<=0 && speedY <=0)
      	      {
      	      	  if (slope < -10)
      	      	     direction = 350;
      	      	  else if (slope < -5)
      	      	     direction = 340;
      	      	  else if (slope < -4)
      	      	     direction = 330;
      	      	  else if (slope < -3)
      	      	     direction = 320;
      	      	  else if (slope < -1)
      	      	     direction = 310;
      	      	  else if (slope < -.8)
      	      	     direction = 300;
      	      	  else if (slope < -.5)
      	      	     direction = 290;
      	      	  else if (slope < -.2)
      	      	     direction = 280;
      	      	  else if (slope < -.1)
      	      	     direction = 270;
     	      	}     
      	  
      }
   public void drawBug(Graphics g)
     {
     	
     	if (visible)
     	   {
     			getDirection();
     			g.drawImage(picture[direction/10],x,y,null);
     		}	
   
     }	    
}		
