package TUGLaby;
import java.awt.Dimension;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JScrollPane;

import PrintGame.*;

/*
 * JApplet.java
 *
 * Created on 16. August 2004, 22:30
 */

/**
 * 
 * @author user
 */
public class TUGLabyrinth extends javax.swing.JApplet implements Runnable {
    private static final long serialVersionUID = 7538087491086535801L;

    private static final int height = 700;
    private static final int width = 950;
    private RuleTreePanel rule_tree_panel_;
    private RulesBrickPanel rules_brick_panel_;
    private JScrollPane rule_tree_scrollpane_;
    private HashMap brick_images_;
    private JButton testa_;
    protected Thread th_;

    /**  ADDED FROM PrintGame ********************************************************* */
    protected final static boolean create_labyrinth_ = false;  // Switch, nur derzeit nötig

    //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_;    
    protected boolean ready_to_run_;
    /**  ADDED FROM PrintGame ********************************************************* */
    
    
    /** Initializes the applet JApplet */
    public void init() {
        
        getContentPane().setLayout( null );
        this.setSize(width, height );
        String abs_filename = getParameter("abs_filename");
        abs_filename = "Game.xml";
        ready_to_run_ = false;
        // START TESTENVI
        testa_ = new JButton();
        getContentPane().add( testa_);
        // END TESTENVI
        loadImages();
        
        rule_tree_panel_ = new RuleTreePanel( brick_images_ );
        rules_brick_panel_ = new RulesBrickPanel( brick_images_ );
        rule_tree_panel_.setPreferredSize( new Dimension(250,height-10 ) );
        
        rule_tree_scrollpane_ = new JScrollPane( rule_tree_panel_ );
        
        print_labyrinth_ = new PrintLabyrinth(brick_images_, robot_, null);
        
        getContentPane().add( rule_tree_scrollpane_ );
        getContentPane().add( rules_brick_panel_ );
        getContentPane().add( print_labyrinth_ );
        
        rule_tree_scrollpane_.setBounds(5, 5, 268, height-10+1);
        rules_brick_panel_.setBounds(280, 5, 320, 75);
        print_labyrinth_.setBounds(280,90,400,400);
        // START TESTENVI
        testa_.setBounds( 610,5,70,30);
        
        testa_.setText("Oldta");
        testa_.addActionListener(new java.awt.event.ActionListener()
                {
                  public void actionPerformed(java.awt.event.ActionEvent evt)
                  {
                    System.out.println("Rule Tree -->");
                    instruct_list_ = new InstructionList();
                    LinkedList listi = TUGLabyrinth.this.rule_tree_panel_.getRuleList();
                    for( int i = 0; i< listi.size(); i++)
                    {
                        Instruction dummy = ((ConditionRulePanel)listi.get(i)).getInstruction() ;
                        instruct_list_.addInstruction( dummy );
                    }
                    ready_to_run_ = true;
                    th_.run();
                  }
                });
               
        // END TESTENVI
        URL new_url = null;
        try
        {    
          new_url = new URL(getDocumentBase(),abs_filename);
        }
        catch( MalformedURLException ex )
        {
          System.err.println(ex.getMessage());
        }
        String file_name = new_url.toString();
        level_handler_= new LevelHandler();
        level_handler_.loadGameXmlFile(file_name);
        th_ = new Thread(this);
        
    }

    /**
     * This method is called from within the init() method to initialize the
     * form. WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void loadImages()
    {
       brick_images_ = new HashMap();
       // load the images which are display at the brick_rules panel
       brick_images_.put("CONDITION_DEFAULT",loadImage("images.jpg"));
       brick_images_.put("CONDITION_HOVER",loadImage("images1.jpg"));
       brick_images_.put("ACTION_DEFAULT",loadImage("images2.jpg"));
       brick_images_.put("ACTION_HOVER",loadImage("images3.jpg"));
       brick_images_.put("ARROW_UP",loadImage("arrow_up.gif"));
       brick_images_.put("ARROW_DOWN",loadImage("arrow_down.gif"));
       brick_images_.put("ARROW_LEFT",loadImage("arrow_left.gif"));
       brick_images_.put("ARROW_RIGHT",loadImage("arrow_right.gif"));
       brick_images_.put("FREE_GROUND",loadImage("free_ground.gif"));
       brick_images_.put("WALL_GROUND",loadImage("wall_ground.gif"));

       brick_images_.put("EMPTY_FLOOR",loadImage("floor_empty.gif"));
       brick_images_.put("FLOOR_1",loadImage("floor_1.gif"));
       brick_images_.put("FLOOR_2",loadImage("floor_2.gif"));
       brick_images_.put("FLOOR_3",loadImage("floor_3.gif"));
       brick_images_.put("X_BUTTON",loadIcon("x_button.gif"));
       
       brick_images_.put("COND_NONE",loadImage("cond_none.gif"));
       brick_images_.put("COND_GREEN",loadImage("cond_green.gif"));
       brick_images_.put("COND_BLUE",loadImage("cond_blue.gif"));
       
       brick_images_.put("LAB_WAY",loadImage("way_3.jpg" ));
       brick_images_.put("LAB_WALL",loadImage("way_2.jpg" ));
       brick_images_.put("LAB_ROBOT",loadImage("robot_template.gif" ));
       brick_images_.put("LAB_DIAMOND",loadImage("diamond.gif" ));
       
       
    }
    private Image loadImage( String name)
    {
        ImageIcon icon = null;
        try
        {
          icon = new ImageIcon(new URL(getCodeBase(),name));
          return icon.getImage();
        }
        catch(MalformedURLException e)
        {
          System.out.println("Failed to create URL:\n" + e);
          return null;
        }
        
    }
    private ImageIcon loadIcon( String name )
    {
        ImageIcon icon = null;
        try
        {
          icon = new ImageIcon(new URL(getCodeBase(),name));
          return icon;
        }
        catch(MalformedURLException e)
        {
          System.out.println("Failed to create URL:\n" + e);
          return null;
        }
        
    }
//  -----------------------------------------------------------------------------
  	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(0, 0, true, true, false),
  	                                            new Action(0, 0, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //2
  	  instruction = new Instruction(new Condition(0, 0, false, true, true),
  	                                new Action(0, 0, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //3
  	  instruction = new Instruction(new Condition(0, 0, true, false, true),
  	                                new Action(0, 0, Action.MOVE_RIGHT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //4
  	  instruction = new Instruction(new Condition(0, 0, false, false, true),
  	                                new Action(0, 1, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //5
  	  instruction = new Instruction(new Condition(0, 0, true, false, false),
  	                                new Action(0, 1, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //6
  	  instruction = new Instruction(new Condition(0, 0, false, true, false),
  	                                new Action(0, 1, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //7
  	  instruction = new Instruction(new Condition(0, 0, true, true, true),
  	                                new Action(1, 0, Action.MOVE_BACK));
  	  instruct_list_.addInstruction(instruction);
  	
  	
  	// B in condition or/and action
  	  //8
  	  instruction = new Instruction(new Condition(1, 0, true, true, false),
  	                                new Action(1, 0, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //9
  	  instruction = new Instruction(new Condition(1, 0, false, true, true),
  	                                new Action(1, 0, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //10
  	  instruction = new Instruction(new Condition(1, 0, true, false, true),
  	                                new Action(1, 0, Action.MOVE_RIGHT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //11
  	  instruction = new Instruction(new Condition(1, 1, false, false, true),
  	                                new Action(0, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //12
  	  instruction = new Instruction(new Condition(1, 1, true, false, false),
  	                                new Action(0, 2, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //13
  	  instruction = new Instruction(new Condition(1, 1, false, true, false),
  	                                new Action(0, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //14
  	  instruction = new Instruction(new Condition(1, 2, false, false, true),
  	                                new Action(1, 0, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //15
  	  instruction = new Instruction(new Condition(1, 2, true, false, false),
  	                                new Action(1, 0, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //16
  	  instruction = new Instruction(new Condition(1, 2, false, true, false),
  	                                new Action(1, 0, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //Vier Weg Kreuzung
  	  //1
  	  instruction = new Instruction(new Condition(0, 0, false, false, false),
  	                                new Action(0, 1, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //2
  	  instruction = new Instruction(new Condition(1, 1, false, false, false),
  	                                new Action(0, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //3
  	  instruction = new Instruction(new Condition(1, 2, false, false, false),
  	                                new Action(0, 3, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //4
  	  instruction = new Instruction(new Condition(1, 3, false, false, false),
  	                                new Action(1, 0, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	
  	  //Loops bei 3 Weg Kreuzungen
  	  instruction = new Instruction(new Condition(0, 1, false, false, true),
  	                                new Action(1, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  instruction = new Instruction(new Condition(0, 1, false, true, false),
  	                                new Action(1, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  instruction = new Instruction(new Condition(0, 1, true, false, false),
  	                                new Action(1, 2, Action.MOVE_AHEAD));
  	  instruct_list_.addInstruction(instruction);
  	
  	  //Loops bei 4 Weg Kreuzungen
  	  instruction = new Instruction(new Condition(0, 1, false, false, false),
  	                                new Action(0, 2, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	  instruction = new Instruction(new Condition(0, 2, false, false, false),
  	                                new Action(1, 3, Action.MOVE_LEFT));
  	  instruct_list_.addInstruction(instruction);
  	
  	}
  	 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_.setMode(TuringMachine.FASTFORWARD);
  	        // Zeichnen des Labyrinths
  	        print_labyrinth_.setLabyrinthField( labyrinth_field_);
  	        print_labyrinth_.setRobot( robot_ );

  	        //turing_machine_.setMode(TuringMachine.SINGLE_STEP);
  	        repaint();
  	        Thread.sleep(50);
  	        if( ready_to_run_ ) {
  	          System.out.println("Turing Maschine started.");
  	          turing_machine_.start(print_labyrinth_);
  	          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());
  	    }
  	  }
  	  
 	
}


