/*
 * JVirus is a PacMan clone, written in Java.
 *
 * Please read "http://jvirus.sourceforge.net/jvirus_licence.txt" for copyrights.
 * 
 * The sourcecode is designed and created with
 * Sun J2SDK 1.3 and Microsoft Visual J++ 6.0
 *
 * JVirus homepage: http://jvirus.sourceforge.net
 *
 * autor: Slawa Weis
 * email: slawaweis@animatronik.net
 *
 */

package org.game.JVirus;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;

import javax.swing.*;

/**
 * the display for the level array. It has a static size and a buffer.
 */
public class Display extends JPanel implements IFields
{
 /**
  * tile width 64 pixel
  */
 public static final int TILE_WIDTH  = 64;
 /**
  * tile height 64 pixel
  */
 public static final int TILE_HEIGHT = 64;
 /**
  * display width in tiles = 12
  */
 public static final int DISPLAY_TILES_WIDTH  = 12;
 /**
  * display height in tiles = 8
  */
 public static final int DISPLAY_TILES_HEIGHT = 8;

 /**
  * half of DISPLAY_TILES_WIDTH
  */
 public static final int DISPLAY_TILES_WIDTH2  = DISPLAY_TILES_WIDTH/2;
 /**
  * half of DISPLAY_TILES_HEIGHT
  */
 public static final int DISPLAY_TILES_HEIGHT2 = DISPLAY_TILES_HEIGHT/2;

 /**
  * display offscreen buffer
  */
 protected BufferedImage bufferImage = null;
 /**
  * reference to the level
  */
 protected Matrix level = null;
 /**
  * current display point of the level, if the level is bigger that the display size
  */
 public Point mapOnScreen = new Point(0, 0);

 /**
  * simply constructor
  */
 public Display()
  {
  super(null);

  setDoubleBuffered(false);
  setBackground(Color.black);

  Dimension bufferSize = new Dimension(DISPLAY_TILES_WIDTH  * TILE_WIDTH,
                                       DISPLAY_TILES_HEIGHT * TILE_HEIGHT);

  bufferImage = new BufferedImage(bufferSize.width, bufferSize.height, BufferedImage.TYPE_INT_RGB);

  setSize(bufferSize);
  setPreferredSize(bufferSize);
  setMaximumSize(bufferSize);
  setMinimumSize(bufferSize);
  }

 /**
  * set the new level and repaint the back buffer
  */
 public void reset(Matrix level)
  {
  this.level = level;
  mapOnScreen.setLocation(level.displayPoint);
  repaintMatrix();
  }

 /**
  * paintComponent overwritten to paint the back buffer
  */
 public void paintComponent(Graphics g)
  {
  super.paintComponent(g);
  g.drawImage(bufferImage, 0, 0, null);
  }

 /**
  * repaints the whole back buffer
  */
 protected void repaintMatrix()
  {
  repaintMatrix(null);
  }

 /**
  * repaints the whole back buffer and the avatar
  */
 protected void repaintMatrix(Avatar avatar)
  {
  int i, j, a, b;
  Graphics2D g2 = bufferImage.createGraphics();

  for(i = mapOnScreen.y, a = 0; i < level.matrix.length; i++, a++)
     for(j = mapOnScreen.x, b = 0; j < level.matrix[i].length; j++, b++)
        {
        g2.drawImage(Images.imageArray[level.matrix[i][j]].nextImage(), b*64, a*64, null);
        }

  if(avatar != null)
    {
    drawAvatar(g2, avatar);
    }
  }

 /**
  * repaints only the animated tiles in the back buffer
  */
 protected void repaintAnimTiles(Avatar avatar)
  {
  int i, j, a, b;
  Graphics2D g2 = bufferImage.createGraphics();

  for(i = mapOnScreen.y, a = 0; (a < DISPLAY_TILES_HEIGHT || i < level.matrix.length); i++, a++)
     for(j = mapOnScreen.x, b = 0; (b < DISPLAY_TILES_WIDTH || j < level.matrix[i].length); j++, b++)
        {
        if((Matrix.actionTyp[level.matrix[i][j]] & AT_ANIM) == AT_ANIM && (avatar.x != j || avatar.y != i))
          g2.drawImage(Images.imageArray[level.matrix[i][j]].nextImage(), b*64, a*64, null);
        }
  }

 /**
  * repaint the avatar only in the back buffer
  */
 public void moveAvatar(Avatar avatar)
  {
  Graphics2D g2 = bufferImage.createGraphics();
  g2.drawImage(Images.imageArray[level.matrix[avatar.ly][avatar.lx]].nextImage(), (avatar.lx-mapOnScreen.x)*64, (avatar.ly-mapOnScreen.y)*64, null);
  drawAvatar(g2, avatar);
  }

 /**
  * paints the avatar
  */
 public void drawAvatar(Graphics2D g2, Avatar avatar)
  {
  g2.drawImage((avatar.move_direction ? 
                 (avatar.eat_sequence ? Images.avatar3 : Images.avatar4) :
                 (avatar.eat_sequence ? Images.avatar1 : Images.avatar2)),
               (avatar.x-mapOnScreen.x)*TILE_WIDTH,
               (avatar.y-mapOnScreen.y)*TILE_HEIGHT, null);
  }
}