//package PrintGame;

import java.awt.*;
import java.applet.*;
import PrintGame.*;
import PrintGame.Robot;

//----------------------------------------------------------------------
/**
 * class to display the labyrinth
 */

public class PrintGame extends Applet
implements Runnable
{
  protected final static boolean create_labyrinth_ = false;  // Switch, nur derzeit nötig

 // protected final static String directory_ = "F:\\work\\PrintLabyrinth\\";

  //number of cells in a row and a col
  protected final static int ROWS = 20;
  protected final static int COLS = 20;

  //size of the labyrinth
//  protected final static int LABYRINTH_HEIGHT = ROWS * CELL_HEIGHT;
//  protected final static int LABYRINTH_WHITH = COLS * CELL_WHITH;

  Image way, wall, robot, diamond;
  protected static LabyrinthField labyrinth_field_;
  protected static Labyrinth  labyrinth_;
  protected static LevelHandler level_handler_;
  protected static Robot robot_;
  protected static WriteLabToXML write_lab_;

  protected InstructionList instruct_list_;
  protected TuringMachine turing_machine_;
  protected PrintLabyrinth print_labyrinth_;

  public static void main(String[] args)
  {
    int cols_counter, rows_counter;

    cols_counter=0;
    rows_counter=0;

    try
    {
      labyrinth_ = new Labyrinth();
      if (create_labyrinth_)
      {
        labyrinth_.createLabyrinth(ROWS, COLS, 150, 10, true, true, false, false);
      }
      else
      {
        labyrinth_.loadLabyrinth("level1.xml");
      }
      labyrinth_field_=labyrinth_.getLabyrinthField();
      robot_ = new Robot();
      robot_.setPos(labyrinth_.getStartpointRow(), labyrinth_.getStartpointCol());
      robot_.setStartDirection(labyrinth_.getStartDirection());
      write_lab_ = new WriteLabToXML(labyrinth_field_, robot_);

      while(rows_counter<labyrinth_field_.getNumRows())
      {
        while(cols_counter<labyrinth_field_.getNumCols())
        {
          if(labyrinth_field_.isWall(rows_counter,cols_counter)==true)
            System.out.print(LabSymbols.WALLSYMBOL);
          else if(labyrinth_field_.isEmpty(rows_counter, cols_counter))
          {
            System.out.print(LabSymbols.EMPTYSYMBOL);
          }
          else if(labyrinth_field_.isWay(rows_counter,cols_counter)==true)
          {
            if(labyrinth_field_.isStartpoint(rows_counter,cols_counter)==true)
              System.out.print(LabSymbols.STARTSYMBOL);
            else
            {
              if(labyrinth_field_.containsDiamond(rows_counter,cols_counter)==true)
                System.out.print(LabSymbols.DIAMONDSYMBOL);
              else
              {
                System.out.print(LabSymbols.WAYSYMBOL);
              }
            }
          }
          if(cols_counter==labyrinth_field_.getNumCols()-1)
            System.out.print("\n");

         cols_counter=cols_counter+1;
        }
        rows_counter=rows_counter+1;
        cols_counter=0;
      }
    }
    catch(IllegalDirectionException ex)
    {
      System.err.println(ex.getMessage());
    }
    write_lab_.writeXMLFile("Labyrinthaufbau2.xml", 9);

  }

//-----------------------------------------------------------------------------
  public void createInstructList()
  {

    instruct_list_ = new InstructionList();
    //1 - Condition(N oder B, Markierung, Links Wand, Rechts Wand, Vorne Wand)
    Instruction instruction = new Instruction(new Condition(true, 0, true, true, false),
                                              new Action(true, 0, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //2
    instruction = new Instruction(new Condition(true, 0, false, true, true),
                                  new Action(true, 0, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //3
    instruction = new Instruction(new Condition(true, 0, true, false, true),
                                  new Action(true, 0, Action.MOVE_RIGHT));
    instruct_list_.addInstruction(instruction);

    //4
    instruction = new Instruction(new Condition(true, 0, false, false, true),
                                  new Action(true, 1, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //5
    instruction = new Instruction(new Condition(true, 0, true, false, false),
                                  new Action(true, 1, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //6
    instruction = new Instruction(new Condition(true, 0, false, true, false),
                                  new Action(true, 1, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //7
    instruction = new Instruction(new Condition(true, 0, true, true, true),
                                  new Action(false, 0, Action.MOVE_BACK));
    instruct_list_.addInstruction(instruction);


 // B in condition or/and action
    //8
    instruction = new Instruction(new Condition(false, 0, true, true, false),
                                  new Action(false, 0, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //9
    instruction = new Instruction(new Condition(false, 0, false, true, true),
                                  new Action(false, 0, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //10
    instruction = new Instruction(new Condition(false, 0, true, false, true),
                                  new Action(false, 0, Action.MOVE_RIGHT));
    instruct_list_.addInstruction(instruction);

    //11
    instruction = new Instruction(new Condition(false, 1, false, false, true),
                                  new Action(true, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //12
    instruction = new Instruction(new Condition(false, 1, true, false, false),
                                  new Action(true, 2, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //13
    instruction = new Instruction(new Condition(false, 1, false, true, false),
                                  new Action(true, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //14
    instruction = new Instruction(new Condition(false, 2, false, false, true),
                                  new Action(false, 0, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //15
    instruction = new Instruction(new Condition(false, 2, true, false, false),
                                  new Action(false, 0, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //16
    instruction = new Instruction(new Condition(false, 2, false, true, false),
                                  new Action(false, 0, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //Vier Weg Kreuzung
    //1
    instruction = new Instruction(new Condition(true, 0, false, false, false),
                                  new Action(true, 1, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //2
    instruction = new Instruction(new Condition(false, 1, false, false, false),
                                  new Action(true, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //3
    instruction = new Instruction(new Condition(false, 2, false, false, false),
                                  new Action(true, 3, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    //4
    instruction = new Instruction(new Condition(false, 3, false, false, false),
                                  new Action(false, 0, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);


    //Loops bei 3 Weg Kreuzungen
    instruction = new Instruction(new Condition(true, 1, false, false, true),
                                  new Action(false, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    instruction = new Instruction(new Condition(true, 1, false, true, false),
                                  new Action(false, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    instruction = new Instruction(new Condition(true, 1, true, false, false),
                                  new Action(false, 2, Action.MOVE_AHEAD));
    instruct_list_.addInstruction(instruction);

    //Loops bei 4 Weg Kreuzungen
    instruction = new Instruction(new Condition(true, 1, false, false, false),
                                  new Action(true, 2, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

    instruction = new Instruction(new Condition(true, 2, false, false, false),
                                  new Action(false, 3, Action.MOVE_LEFT));
    instruct_list_.addInstruction(instruction);

  }

//-----------------------------------------------------------------------------
  public void init()
  {
   // setSize(LABYRINTH_HEIGHT,LABYRINTH_WHITH);
    String abs_filename = getParameter("abs_filename");
    //String abs_filename ="level1.xml";
    /*try
    {
      labyrinth_ = new Labyrinth();
      if (create_labyrinth_)
      {
        labyrinth_.createLabyrinth(ROWS, COLS, 150, 10, true, true, false, false);
      }
      else
      {
        labyrinth_.loadLabyrinth(abs_filename);
        //labyrinth_.loadLabyrinth(file);
      }
      labyrinth_field_=labyrinth_.getLabyrinthField();
      robot_ = new Robot();
      robot_.setPos(labyrinth_.getStartpointRow(), labyrinth_.getStartpointCol());
      robot_.setStartDirection(labyrinth_.getStartDirection());
      */

      level_handler_= new LevelHandler();
      level_handler_.loadGameXmlFile(abs_filename);

      Thread th = new Thread(this);
      th.start();
    /*}
    catch(IllegalDirectionException ex)
    {
      System.err.println(ex.getMessage());
    }
    // Testprogramm:
    turing_machine_ = new TuringMachine();
    turing_machine_.setLabyrinthField(labyrinth_field_);
    turing_machine_.setRobot(robot_);
    createInstructList();
    turing_machine_.setInstructionList(instruct_list_);
    turing_machine_.setSpeed(TuringMachine.FASTFORWARD);

    // Zeichnen des Labyrinths
    print_labyrinth_ = new PrintLabyrinth(this, robot_, labyrinth_field_);

    Thread th = new Thread(this);
    th.start();*/
  }

//-----------------------------------------------------------------------------
  public void paint(Graphics g)
  {
    update(g);
  }

//-----------------------------------------------------------------------------
  public void update(Graphics g)
  {
    print_labyrinth_.paintFrame(g);
  }

//-----------------------------------------------------------------------------
  public void run()
  {
    try
    {
      int levels=level_handler_.getNumLevels();
      for(int level=1;level<=levels;level++)
      {
        level_handler_.loadLevel(level);
        labyrinth_field_=level_handler_.getLabyrinthField();
        robot_ = new Robot();
        robot_.setPos(level_handler_.getStartpointRow(), level_handler_.getStartpointCol());
        robot_.setStartDirection(level_handler_.getStartDirection());
        // Testprogramm:
        turing_machine_ = new TuringMachine();
        turing_machine_.setLabyrinthField(labyrinth_field_);
        turing_machine_.setRobot(robot_);
        createInstructList();
        turing_machine_.setInstructionList(instruct_list_);
        turing_machine_.setSpeed(TuringMachine.FASTFORWARD);
        // Zeichnen des Labyrinths
        print_labyrinth_ = new PrintLabyrinth(this, robot_, labyrinth_field_);

        turing_machine_.run(this);
        System.out.println("Anzahl der Schritte " + turing_machine_.getNumSteps());
        System.out.println("Anzahl der gesammelten Diamanten " + turing_machine_.getNumTakenDiamonds());
      }
    }
    catch(IllegalDirectionException ex)
    {
      System.err.println(ex.getMessage());
    }
    catch (InterruptedException ex)
    {
      System.err.println(ex.getMessage());
    }
  }
}
