/*
 * 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.io.*;
import java.util.*;

/**
 * this class containt the level array. Most variables are public for faster access
 */
public class Matrix implements IFields
{
 /**
  * name of level
  */
 public String name         = "level ???";
 /**
  * start point in the Display
  *
  * @see org.game.JVirus.Display
  */
 public Point  displayPoint = new Point();
 /**
  * level tiles array
  */
 public char   matrix [][]  = null;
 /**
  * buffer array for object fall function
  *
  * @see org.game.JVirus.ActionControl
  */
 public int    bufferMatrix1 [][]  = null;
 /**
  * level number in the level list
  */
 public int    levelNumber = -1;

 /**
  * copy constructor
  */
 public Matrix(Matrix copy)
  {
  this.name = copy.name;
  this.displayPoint.setLocation(copy.displayPoint);

  this.levelNumber = copy.levelNumber;

  this.matrix        = new char[copy.matrix.length][copy.matrix[0].length];
  this.bufferMatrix1 = new int [copy.matrix.length][copy.matrix[0].length];

  int i, j;
  for(i = 0; i < copy.matrix.length; i++)
     for(j = 0; j < copy.matrix[i].length; j++)
        {
        this.matrix[i][j] = copy.matrix[i][j];
        this.bufferMatrix1[i][j] = copy.bufferMatrix1[i][j];
        }
  }

 /**
  * Constructor. load the level from file
  */
 public Matrix(File file) throws FileNotFoundException, IOException
  {
  loadMatrix(file);
  }

 /**
  * Constructor. load the level from InputStream
  */
 public Matrix(InputStream is) throws IOException
  {
  loadMatrix(is);
  }

 /**
  * load the level from file
  */
 protected void loadMatrix(File file) throws FileNotFoundException, IOException
  {
  FileInputStream fis = new FileInputStream(file);
  loadMatrix(fis);
  fis.close();
  }

 /**
  * load the level from InputStream
  */
 protected void loadMatrix(InputStream is) throws IOException
  {
  LineNumberReader lnr = new LineNumberReader(new InputStreamReader(is));

  String line = null;
  boolean parse = false;
  int i, j;
  int matrix_w = 0, matrix_h = 0;
  Vector vecLines = new Vector();

  i = 0;
  while((line = lnr.readLine()) != null)
       {
       // first line: level name
       if(i == 0)
         name = line;

       // second line: display start coordination x
       if(i == 1)
         displayPoint.x = Integer.parseInt(line);

       // third line: display start coordination y
       if(i == 2)
         displayPoint.y = Integer.parseInt(line);

       // level itself
       if(line.equals("LEVEL_BEGIN"))
         {
         parse = true;
         continue;
         }
       if(line.equals("LEVEL_END"))
         {
         parse = false;
         continue;
         }

       if(parse)
         {
         vecLines.add(line);
         }
       i++;
       }
  lnr.close();

  matrix_w = ((String)vecLines.elementAt(0)).length();
  matrix_h = vecLines.size();

  matrix = new char[matrix_h][matrix_w];
  bufferMatrix1 = new int[matrix_h][matrix_w];

  for(i = 0; i < matrix.length; i++)
     for(j = 0; j < matrix[i].length; j++)
        {
        matrix[i][j] = IFields.EMPTY;
        bufferMatrix1[i][j] = 0;
        }

  for(i = 0; i < matrix_h; i++)
     {
     line = (String)vecLines.elementAt(i);
     j = 0;
     while(j < line.length())
          {
          matrix[i][j] = line.charAt(j);
          j++;
          }
     }
  }

 /**
  * convert the matrix to string to print it in the console
  */
 public String matrixToString()
  {
  StringBuffer ret = new StringBuffer((matrix.length * matrix[0].length) + matrix.length);
  int i, j;
  for(i = 0; i < matrix.length; i++)
     {
     for(j = 0; j < matrix[i].length; j++)
        {
        ret.append(matrix[i][j]);
        }
     ret.append('\n');
     }
  return ret.toString();
  }

 /**
  * return the name of this level
  */
 public String toString()
  {
  return name;
  }

///////////////////////////////////////////////////////////////////
// action types

 /**
  * array with action types. See the AT_* constants int the IFields interface. Used in ActionControl
  *
  * @see org.game.JVirus.IFields
  * @see org.game.JVirus.ActionControl
  */
 public static final int actionTyp [] = new int[256];
  {
  for(int i = 0; i < actionTyp.length; i++)
     actionTyp[i] = AT_WALL;

  actionTyp[WALL1] = AT_WALL | AT_HOLD;
  actionTyp[AMD]   = AT_WALL | AT_HOLD;
  actionTyp[INTEL] = AT_WALL | AT_HOLD;

  actionTyp[STONE]    = AT_PUSH | AT_FAll;

  actionTyp[START]    = AT_MOVE;
  actionTyp[END]      = AT_MOVE | AT_END;
  actionTyp[EMPTY]    = AT_MOVE;
  actionTyp[LIFE]     = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;
  actionTyp[NOTHING]  = AT_MOVE | AT_EAT | AT_HOLD;
  actionTyp[DATA1]    = AT_MOVE | AT_EAT | AT_EAT_SOUND1 | AT_FAll;
  actionTyp[DATA2]    = AT_MOVE | AT_EAT | AT_EAT_SOUND1 | AT_FAll;
  actionTyp[DATA3]    = AT_MOVE | AT_EAT | AT_EAT_SOUND1 | AT_FAll;

  actionTyp[REDKEY]   = AT_MOVE | AT_EAT | AT_ACTION | AT_FAll;
  actionTyp[GREENKEY] = AT_MOVE | AT_EAT | AT_ACTION | AT_FAll;
  actionTyp[BLUEKEY]  = AT_MOVE | AT_EAT | AT_ACTION | AT_FAll;

  actionTyp[BEOS]     = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;
  actionTyp[LINUX]    = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;
  actionTyp[MAC]      = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;
  actionTyp[UNIX]     = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;
  actionTyp[WINDOWS]  = AT_MOVE | AT_EAT | AT_EAT_SOUND2 | AT_FAll;

  actionTyp[BEAM0]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM1]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM2]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM3]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM4]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM5]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM6]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM7]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM8]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  actionTyp[BEAM9]    = AT_MOVE | AT_ACTION | AT_ANIM | AT_BEAM;
  }

 /**
  * score for every field. Used in ActionControl
  *
  * @see org.game.JVirus.ActionControl
  */
 public static final int scoreTab [] = new int[256];
  {
  for(int i = 0; i < scoreTab.length; i++)
     scoreTab[i] = 0;

  scoreTab[LIFE]     = 1000;
  scoreTab[NOTHING]  = 1;
  scoreTab[DATA1]    = 10;
  scoreTab[DATA2]    = 100;
  scoreTab[DATA3]    = 1000;

  scoreTab[REDKEY]   = 100;
  scoreTab[GREENKEY] = 100;
  scoreTab[BLUEKEY]  = 100;

  scoreTab[BEOS]     = 1000;
  scoreTab[LINUX]    = 1000;
  scoreTab[MAC]      = 1000;
  scoreTab[UNIX]     = 1000;
  scoreTab[WINDOWS]  = 1000;
  }

// action types
///////////////////////////////////////////////////////////////////
}