import java.applet.*;
import java.awt.*;
import java.util.*;

public class GameArea extends Canvas {
  Applet applet;

    long numFrames = 0;
    long numDrawnFrames = 0;
    long start_time = 0;
    
  static int WIDTH = 320;
  static int HEIGHT = 400;
  /* Speed: */
  
  static int MAX_COLORS =512;


/* Objects: */
  
  static int OBJ_0 =0;        /* objects 0-9 are digits 0-9 */
  static int OBJ_TITLE =10;
  static int OBJ_BULLET =11;
  static int OBJ_ALIENBULLET =12;
  static int OBJ_SHIP_0 =13;  /* objects 13-20 are ship0 */
  static int OBJ_SHIP_1 =21;  /* objects 21-28 are ship1 */
  static int OBJ_ALIEN_0 =29; /* objects 29-37 are alien0 */
  static int OBJ_ALIEN_1 =38; /* objects 38-46 are alien1 */
  static int OBJ_ALIEN_2 =47; /* objects 47-55 are alien2 */
  static int OBJ_ALIEN_3 =56; /* objects 56-64 are alien3 */
  static int OBJ_ALIEN_4 =65; /* objects 65-73 are alien4 */
  static int OBJ_ALIEN_5 =74; /* objects 74-82 are alien5 */
  static int OBJ_GIANT_0 =83;
  static int OBJ_GIANT_1 =84;
  static int OBJ_TRACTORBEAM =85;
  static int OBJ_CREDITS =86;
  static int OBJ_ASTEROID_A =87; /* objects 87-91 are asteroid-a */
  static int OBJ_ASTEROID_B =92; /* objects 92-96 are asteroid-b */
  static int OBJ_EXPLODE =97;    /* objects 97-101 are explosion */
  static int OBJ_PLANET_0 =102;  /* objects 102-105 are planets */
  static int NUM_OBJECTS =106;

  static int NUM_EXPLODE_SHAPES =OBJ_PLANET_0 - OBJ_EXPLODE;
  static int NUM_PLANET_SHAPES =NUM_OBJECTS - OBJ_PLANET_0;

  static String[] object_names  =
  {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
   "jalaxa", "bullet", "alienbullet",
   "ship_0_0", "ship_0_1", "ship_0_2", "ship_0_3",
   "ship_0_4", "ship_0_5", "ship_0_6", "ship_0_7",
   "ship_1_0", "ship_1_1", "ship_1_2", "ship_1_3",
   "ship_1_4", "ship_1_5", "ship_1_6", "ship_1_7",
   "alien_0_0", "alien_0_1", "alien_0_2", "alien_0_3",
   "alien_0_4", "alien_0_5", "alien_0_6", "alien_0_7", "alien_0_0b",
   "alien_1_0", "alien_1_1", "alien_1_2", "alien_1_3",
   "alien_1_4", "alien_1_5", "alien_1_6", "alien_1_7", "alien_1_0b",
   "alien_2_0", "alien_2_1", "alien_2_2", "alien_2_3",
   "alien_2_4", "alien_2_5", "alien_2_6", "alien_2_7", "alien_2_0b",
   "alien_3_0", "alien_3_1", "alien_3_2", "alien_3_3",
   "alien_3_4", "alien_3_5", "alien_3_6", "alien_3_7", "alien_3_0b",
   "alien_4_0", "alien_4_1", "alien_4_2", "alien_4_3",
   "alien_4_4", "alien_4_5", "alien_4_6", "alien_4_7", "alien_4_0b",
   "alien_5_0", "alien_5_1", "alien_5_2", "alien_5_3",
   "alien_5_4", "alien_5_5", "alien_5_6", "alien_5_7", "alien_5_0b",
   "giant0", "giant1",
   "tractorbeam",
   "credits",
   "asteroid_a0", "asteroid_a1", "asteroid_a2", "asteroid_a3", "asteroid_a4",
   "asteroid_b0", "asteroid_b1", "asteroid_b2", "asteroid_b3", "asteroid_b4",
   "explode0", "explode1", "explode2", "explode3", "explode4",
   "planet0", "planet1", "planet2", "planet3"
  };


  static int SND_INTRO =0;
  static int SND_TRACTORBEAM =1;
  static int SND_CAPTURE =2;
  static int SND_SHOT =3;
  static int SND_KILL =4;
  static int SND_BUZZ =5;
  static int SND_FLASH =6;
  static int SND_NEXTLEVEL =7;
  static int SND_HURT =8;
  static int SND_FIREWORKS =9;
  static int SND_WELCOME =10;
  static int NUM_SOUNDS =11;

  static String[] sounds = {
    "sounds/intro.au", "sounds/tractorbeam.au", "sounds/capture.au",
    "sounds/shot.au", "sounds/kill.au", "sounds/buzz.au",
    "sounds/flash.au", "sounds/nextlevel.au", "sounds/hurt.au",
    "sounds/fireworks.au", "sounds/welcome.au"
  };
  
  static int NUM_EXPLOSION_COLORS =3;

  static Color[] explosioncolors = {Color.red, Color.orange, Color.yellow};

    private boolean drawing=true;

  /* X-Window Globals: */

  FontMetrics fm;
  Font font;
  int fh;


  /* Globals: */

  Image[] object_pixmap = new Image[NUM_OBJECTS];
  Graphics g_backbuffer;
  Image backbuffer;
  Graphics g_backbuffer2;
  Image backbuffer2;
  Image background;
  int greymode;
  int[] object_width = new int[NUM_OBJECTS];
  int[] object_height = new int[NUM_OBJECTS];
  int[] xms = new int[8];
  int[] yms = new int[8];

    public void enableDrawing() {
	drawing=true;
    }
    public void disableDrawing() {
	drawing=false;
    }
    
  public Dimension preferredSize() {
    return new Dimension(WIDTH,HEIGHT);
  }
  
  public GameArea(Applet app) {
    applet = app;
    
    xms[0] = 0;
    yms[0] = -2;
    
    xms[1] = 1;
    yms[1] = -1;

    xms[2] = 2;
    yms[2] = 0;
    
    xms[3] = 1;
    yms[3] = 1;

    xms[4] = 0;
    yms[4] = 2;

    xms[5] = -1;
    yms[5] = 1;

    xms[6] = -2;
    yms[6] = 0;

    xms[7] = -1;
    yms[7] = -1;
  
  }


  public void update(Graphics g) {
      paint(g);
  }
  public void paint(Graphics g) {
    if (g_backbuffer2 != null) {
      g.drawImage(backbuffer2,0,0,this);
    }
  }

    public void frame() {
	numFrames++;
      if (!drawing)
	  return;
      numDrawnFrames++;
      // Uncomment if you want frame rate info.
      /*      if (start_time == 0) {
	      start_time = new Date().getTime();
	      numFrames = 0;
	      numDrawnFrames = 0;
	      }
	      else {
	      long ttime = new Date().getTime() - start_time;
	      long fr1 = numFrames*1000/ttime;
	      long fr2 = numDrawnFrames*1000/ttime;
	      drawcenteredtext(0,WIDTH,HEIGHT/2,"Total: "+fr1+"FPS  Synced: "+fr2+"FPS");
	      }*/
	Image i;
	Graphics g;
	i = backbuffer;
	g = g_backbuffer;
	backbuffer=backbuffer2;
	g_backbuffer=g_backbuffer2;
	backbuffer2 = i;
	g_backbuffer2 = g;

	/*	if (g2==null) {
	    g2 = getGraphics();
	}
	paint(g2);*/
	repaint();
    }

    Graphics g2;
    
  /* -- Xsetup -- */
  void drawtext(int x, int y, String s) {
      if (!drawing)
	  return;
    g_backbuffer.drawString(s, x, y);
  }

  void drawcenteredtext(int x1, int x2,
			int y, String s) {
      if (!drawing)
	  return;
    int x;
    
    x = ((x2 - x1) / 2) + x1;
    x = x - (fm.stringWidth(s) / 2);
    
    drawtext(x, y, s);
  }
    void drawrighttext(int x, int y, String s) {
    
      if (!drawing)
	  return;
    x -= fm.stringWidth(s);
    
    drawtext(x, y, s);
    }

  void init() {
    font = new Font("Courier",Font.PLAIN,12);
    fm = getFontMetrics(font);
    fh = fm.getAscent()+fm.getDescent();
    
    backbuffer = createImage(WIDTH,HEIGHT);
    backbuffer2 = createImage(WIDTH,HEIGHT);
    background = createImage(WIDTH,HEIGHT);
    g_backbuffer = backbuffer.getGraphics();
    g_backbuffer2 = backbuffer2.getGraphics();
    
    /* Create object pixmaps: */

    clearbackbuffer();
    drawcenteredtext(0, WIDTH,(HEIGHT + fh) / 2, "ONE MOMENT");
    
    frame();
  
    for (int i = 0; i < NUM_OBJECTS; i++) {
      loadobject(i);
      clearbackbuffer();
      
      drawcenteredtext(0, WIDTH,(HEIGHT + fh) / 2,
		       "Loading Image "+(i+1)+" of "+NUM_OBJECTS);
      
      frame();
    }
  }


/* Draws a shape (using mask): */

  void clearbackbuffer() {
      if (!drawing)
	  return;
    g_backbuffer.setColor(Color.black);
    g_backbuffer.fillRect(0, 0, WIDTH, HEIGHT);
    g_backbuffer.setFont(font);
    g_backbuffer.setColor(Color.white);

  }
  void clearbackbufferinvert() {
      if (!drawing)
	  return;
    g_backbuffer.setColor(Color.white);
    g_backbuffer.fillRect(0, 0, WIDTH, HEIGHT);
    g_backbuffer.setFont(font);
    g_backbuffer.setColor(Color.black);

  }

  void setColor(Color c) {
      if (!drawing)
	  return;
    g_backbuffer.setColor(c);
  }
  
  void drawshape(int x, int y, int shape) {
      if (!drawing)
	  return;
    g_backbuffer.drawImage(object_pixmap[shape], x, y,this);
  }

  void loadobject(int i) {

    Image img = applet.getImage(applet.getCodeBase(),object_names[i]+".gif");
    
    MediaTracker mt = new MediaTracker(applet);
    mt.addImage(img,0);
    applet.getToolkit().prepareImage(img,50,50,applet);
    try {
      mt.waitForAll();
    }
    catch (Exception e) {
    }
    
    
    object_pixmap[i] = img;
    object_width[i] = img.getWidth(this);
    object_height[i] = img.getHeight(this);  
  
  }


  
}
