// Path: core/src/nkarasch/chessgdx/GameCore.java
// public class GameCore implements ApplicationListener {
// 
// 	public static final String TITLE = "ChessGDX";
// 
// 	private Camera mCameraController;
// 	private ChessLogicController mLogicController;
// 	private BoardController mBoardController;
// 	private PerspectiveRenderer mPerspectiveRenderer;
// 	private OverlayRenderer mOverlayRenderer;
// 
// 	private static Runnable rebootHook;
// 
// 	/**
// 	 * @param rebootHook
// 	 *            game restart hook
// 	 */
// 	public GameCore(final Runnable rebootHook) {
// 		GameCore.rebootHook = rebootHook;
// 	}
// 
// 	@Override
// 	public void create() {
// 		GraphicsSettings.setGraphics();
// 		mCameraController = new Camera();
// 		mOverlayRenderer = new OverlayRenderer(this);
// 		mLogicController = new ChessLogicController(mOverlayRenderer);
// 		mBoardController = new BoardController(mCameraController, mLogicController, mOverlayRenderer);
// 		mPerspectiveRenderer = new PerspectiveRenderer(mCameraController, mBoardController, mLogicController.getPlacement());
// 
// 		Gdx.input.setInputProcessor(new InputMultiplexer(mOverlayRenderer, mBoardController, mCameraController.getOrbitController()));
// 	}
// 
// 	@Override
// 	public void render() {
// 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
// 		mCameraController.update();
// 		mPerspectiveRenderer.render();
// 		mOverlayRenderer.render();
// 	}
// 
// 	@Override
// 	public void resize(int width, int height) {
// 		// requiring restart on resize instead, this would be tedious to set up
// 	}
// 
// 	@Override
// 	public void pause() {
// 		// not supporting mobile
// 	}
// 
// 	@Override
// 	public void resume() {
// 		// not supporting mobile
// 	}
// 
// 	@Override
// 	public void dispose() {
// 		AssetHandler.getInstance().dispose();
// 		mLogicController.dispose();
// 		mOverlayRenderer.dispose();
// 	}
// 
// 	/**
// 	 * Restarts game client
// 	 */
// 	public static void restart() {
// 		Gdx.app.postRunnable(GameCore.rebootHook);
// 	}
// 
// 	/**
// 	 * Restores board back to the new game state
// 	 * 
// 	 * @param isWhite
// 	 *            player color
// 	 */
// 	public void newGame(boolean isWhite) {
// 		mBoardController.setPlayerColor(isWhite);
// 		mBoardController.resetList();
// 		mLogicController.resetPosition();
// 		mOverlayRenderer.getCheckmateDialog().setState(false, false);
// 		mOverlayRenderer.getMoveHistory().resetHistory();
// 	}
// }
// 
// Path: core/src/nkarasch/chessgdx/util/PreferenceStrings.java
// public class PreferenceStrings {
// 	public static final String ENGINE_PATH = "engine_path";
// 	public static final String SEARCH_VALUE = "search_value";
// 	public static final String DEPTH_SEARCH = "depth_search";
// 
// 	public static final String VSYNC = "vsync";
// 	public static final String DISPLAY_WIDTH = "display_width";
// 	public static final String DISPLAY_HEIGHT = "display_height";
// 	public static final String FULLSCREEN = "fullscreen";
// 
// 	public static final String MUSIC_VOLUME = "music_volume";
// 	public static final String EFFECTS_VOLUME = "effects_volume";
// }


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import nkarasch.chessgdx.GameCore;
import nkarasch.chessgdx.util.PreferenceStrings;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
package nkarasch.chessgdx.logiccontroller.backend;




/**
 * Adapted from Rahul A R's "JavaStockfish".
 * https://github.com/rahular/chess-misc
 * /blob/master/JavaStockfish/src/com/rahul/stockfish/Stockfish.java
 * 
 * I've changed it to make best move searches non-blocking so the entire game
 * doesn't halt while the engine is calculating. There is room for improvement.
 */

// TODO make engine process shut down properly after validateEngine is called
public class UCIEngineInterface {

	private final ExecutorService mService;
	private Future<String> mTask;
	private Process mEngineProcess;
	private final ProcessBuilder mProcessBuilder;
	private BufferedReader mProcessReader;
	private OutputStreamWriter mProcessWriter;
	private String mFEN;
	private final String mSearchType;
	private final int mSearchValue;

	UCIEngineInterface(String PATH) {
		mProcessBuilder = new ProcessBuilder(PATH);
		mService = Executors.newFixedThreadPool(1);
		startEngine();
		mTask = null;

		Preferences pref = Gdx.app.getPreferences(GameCore.TITLE);
// Path: core/src/nkarasch/chessgdx/GameCore.java
// public class GameCore implements ApplicationListener {
// 
// 	public static final String TITLE = "ChessGDX";
// 
// 	private Camera mCameraController;
// 	private ChessLogicController mLogicController;
// 	private BoardController mBoardController;
// 	private PerspectiveRenderer mPerspectiveRenderer;
// 	private OverlayRenderer mOverlayRenderer;
// 
// 	private static Runnable rebootHook;
// 
// 	/**
// 	 * @param rebootHook
// 	 *            game restart hook
// 	 */
// 	public GameCore(final Runnable rebootHook) {
// 		GameCore.rebootHook = rebootHook;
// 	}
// 
// 	@Override
// 	public void create() {
// 		GraphicsSettings.setGraphics();
// 		mCameraController = new Camera();
// 		mOverlayRenderer = new OverlayRenderer(this);
// 		mLogicController = new ChessLogicController(mOverlayRenderer);
// 		mBoardController = new BoardController(mCameraController, mLogicController, mOverlayRenderer);
// 		mPerspectiveRenderer = new PerspectiveRenderer(mCameraController, mBoardController, mLogicController.getPlacement());
// 
// 		Gdx.input.setInputProcessor(new InputMultiplexer(mOverlayRenderer, mBoardController, mCameraController.getOrbitController()));
// 	}
// 
// 	@Override
// 	public void render() {
// 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
// 		mCameraController.update();
// 		mPerspectiveRenderer.render();
// 		mOverlayRenderer.render();
// 	}
// 
// 	@Override
// 	public void resize(int width, int height) {
// 		// requiring restart on resize instead, this would be tedious to set up
// 	}
// 
// 	@Override
// 	public void pause() {
// 		// not supporting mobile
// 	}
// 
// 	@Override
// 	public void resume() {
// 		// not supporting mobile
// 	}
// 
// 	@Override
// 	public void dispose() {
// 		AssetHandler.getInstance().dispose();
// 		mLogicController.dispose();
// 		mOverlayRenderer.dispose();
// 	}
// 
// 	/**
// 	 * Restarts game client
// 	 */
// 	public static void restart() {
// 		Gdx.app.postRunnable(GameCore.rebootHook);
// 	}
// 
// 	/**
// 	 * Restores board back to the new game state
// 	 * 
// 	 * @param isWhite
// 	 *            player color
// 	 */
// 	public void newGame(boolean isWhite) {
// 		mBoardController.setPlayerColor(isWhite);
// 		mBoardController.resetList();
// 		mLogicController.resetPosition();
// 		mOverlayRenderer.getCheckmateDialog().setState(false, false);
// 		mOverlayRenderer.getMoveHistory().resetHistory();
// 	}
// }
// 
// Path: core/src/nkarasch/chessgdx/util/PreferenceStrings.java
// public class PreferenceStrings {
// 	public static final String ENGINE_PATH = "engine_path";
// 	public static final String SEARCH_VALUE = "search_value";
// 	public static final String DEPTH_SEARCH = "depth_search";
// 
// 	public static final String VSYNC = "vsync";
// 	public static final String DISPLAY_WIDTH = "display_width";
// 	public static final String DISPLAY_HEIGHT = "display_height";
// 	public static final String FULLSCREEN = "fullscreen";
// 
// 	public static final String MUSIC_VOLUME = "music_volume";
// 	public static final String EFFECTS_VOLUME = "effects_volume";
// }


// Path: core/src/nkarasch/chessgdx/logiccontroller/backend/UCIEngineInterface.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import nkarasch.chessgdx.GameCore;
import nkarasch.chessgdx.util.PreferenceStrings;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;

package nkarasch.chessgdx.logiccontroller.backend;




/**
 * Adapted from Rahul A R's "JavaStockfish".
 * https://github.com/rahular/chess-misc
 * /blob/master/JavaStockfish/src/com/rahul/stockfish/Stockfish.java
 * 
 * I've changed it to make best move searches non-blocking so the entire game
 * doesn't halt while the engine is calculating. There is room for improvement.
 */

// TODO make engine process shut down properly after validateEngine is called
public class UCIEngineInterface {

	private final ExecutorService mService;
	private Future<String> mTask;
	private Process mEngineProcess;
	private final ProcessBuilder mProcessBuilder;
	private BufferedReader mProcessReader;
	private OutputStreamWriter mProcessWriter;
	private String mFEN;
	private final String mSearchType;
	private final int mSearchValue;

	UCIEngineInterface(String PATH) {
		mProcessBuilder = new ProcessBuilder(PATH);
		mService = Executors.newFixedThreadPool(1);
		startEngine();
		mTask = null;

		Preferences pref = Gdx.app.getPreferences(GameCore.TITLE);
		if (pref.getBoolean(PreferenceStrings.DEPTH_SEARCH)) {