package controller;

import java.io.File;
import java.util.List;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.*;

import simulationObjects.*;

public class MainController extends Application {
    private UserInterface userInterface;
    private static ResourceBundle messages;
    private Timeline animation;
    private GridManager gridManager;
    private GridInfo object = new GridInfo();
    private Patch[][] myGrid=null;

    public static void main(String[] args) throws Exception {

	messages = ResourceBundle.getBundle("messages", Locale.US);
	launch(args);
    }

    @Override
    public void start(Stage s) throws Exception {
	// create our UI
	userInterface = new UserInterface(s, this);
	setSimulationSpeed(.1);
    }

    /**
     * Function to do each game frame
     */
    private EventHandler<ActionEvent> oneFrame = new EventHandler<ActionEvent>() {
	@Override
	public void handle(ActionEvent evt) {
	    stepSimulation();
	}
    };

    /**
     * 
     * change the simulation speed
     * 
     * @param speed
     *            speed of the simulation
     */
    public void setSimulationSpeed(double speed) {
	// set game loop
	KeyFrame frame = new KeyFrame(Duration.millis(100 / speed), oneFrame);
	if (animation == null) {
	    animation = new Timeline();
	}
	animation.stop();
	animation.setCycleCount(Timeline.INDEFINITE);
	animation.getKeyFrames().clear();
	animation.getKeyFrames().add(frame);
	animation.play();
    }

    /**
     * parse the XMLData and check for exceptions
     * 
     * @param XMLData
     *            data to parse
     */
    public void initializeSimulationWithData(File XMLData) {
	try {
	    @SuppressWarnings("unchecked")
	    List<TestCell> gridRows = Parser.parserXml(XMLData
		    .getAbsolutePath());
	    initializeSimulationObjects(gridRows);
	
	} catch (Exception e) {
	    System.out.println(messages.getString("process_file_error"));
	}
    }

    /**
     * take the data array given by the parser and create patches and cell
     * objects
     * 
     * @param gridRows
     *            list given by the parser
     */
    private void initializeSimulationObjects(List<TestCell> gridRows) {
	try {
	    int width = object.getWidth();
	    int height = object.getHeight();
	    Patch[][] grid = new Patch[width][height];
	    for (int j = 0; j < height; j++) {
		String[] currentRow = gridRows.get(j).states.split(" ");

		for (int i = 0; i < width; i++) {

		    // create a patch object at the x and y location
		    // create a cell object
		    String classPathAndName = messages.getString("cell_bundle")
			    + "." + object.getCellType();
		    Class<?> cellClass = Class.forName(classPathAndName);
		    Cell cell = (Cell) cellClass.newInstance();

		    cell.setX(i);
		    cell.setY(j);
		    cell.setState(Integer.parseInt(currentRow[i]));
		    // assign the cell to the patch
		    Patch currentPatch = new Patch(i, j, gridManager);
		    currentPatch.addCell(cell);
		    // add the patch to grid manager
		    grid[i][j] = currentPatch;

		}

	    }
	    myGrid=grid;
	} catch (ClassNotFoundException e) {
	    System.out.println(messages.getString("class_not_found_error"));
	} catch (InstantiationException e) {
	    System.out.println(messages.getString("instantiation_error"));
	} catch (IllegalAccessException e) {
	    System.out.println(messages.getString("illegal_access_error"));
	}

    }


    /**
     * starts the simulation
     */
    public void startSimulation() {
	// start the animation, assuming there is one
	if (animation != null) {
	    animation.play();
	}
    }

    /**
     * stops the simulation
     */
    public void stopSimulation() {
	// stop the animation, assuming there is one
	if (animation != null) {
	    animation.stop();
	}
    }

    /**
     * increment the simulation by one frame
     */
    public void stepSimulation() {
	// tell the grid manager to process cell updates
	// System.out.println("new frame");
    }

}

@@ -593,43 +593,8 @@
 o();
-%0A    private Patch%5B%5D%5B%5D myGrid=null;
 %0A%0A  
@@ -1992,32 +1992,58 @@
 (Exception e) %7B%0A
+%09    e.printStackTrace();%0A
 %09    System.out.
@@ -2440,56 +2440,8 @@
 ();%0A
-%09    Patch%5B%5D%5B%5D grid = new Patch%5Bwidth%5D%5Bheight%5D;%0A
 %09   
@@ -2572,17 +2572,16 @@
  i++) %7B%0A
-%0A
 %09%09    //
@@ -3060,16 +3060,56 @@
 nager);%0A
+%09%09    System.out.println(currentPatch);%0A
 %09%09    cu
@@ -3187,17 +3187,32 @@
 grid
-%5Bi%5D%5Bj%5D = 
+Manager.addPatchAtPoint(
 curr
@@ -3219,16 +3219,17 @@
 entPatch
+)
 ;%0A%0A%09%09%7D%0A%0A
@@ -3239,26 +3239,8 @@
   %7D%0A
-%09    myGrid=grid;%0A
 %09%7D c

Add patch to grid manager instead of having the main controller keep the grid.