package meerkat.voting.gui.controllersFX;

/**
 * Created by Laura on 12/16/2016.
 */
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import meerkat.voting.gui.uiFX.GraphicalUI;
import meerkat.voting.gui.ui.uicommands.UICommand;

import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * Utility class for controlling navigation between vistas.
 *
 * All methods on the navigator are static to facilitate
 * simple access from anywhere in the application.
 */
public class VistaNavigator {

    /**
     * Convenience constants for fxml layouts managed by the navigator.
     */
    public static final String MAIN    = "/views/main.fxml";
    public static final String PRINTER    = "/views/printer.fxml";
    public static final String LOADING    = "/views/loading.fxml";
    public static final String EMPTY_START = "/views/empty_start.fxml";
    public static final String WELCOME_SCREEN = "/views/welcome_screen.fxml";
    public static final String CHANNEL_CHOICE = "/views/channel_choice.fxml";
    public static final String VOTING = "/views/voting.fxml";
    public static final String CAST_OR_AUDIT = "/views/castOrAudit.fxml";

    /** The main application layout controller. */
    private static MainController mainController;
    private static PrinterController printerController;
    public static GraphicalUI uiThread;


    /**
     * Stores the main controller for later use in navigation tasks.
     *
     * @param mainController the main application layout controller.
     */
    public static void setMainController(MainController mainController) {
        VistaNavigator.mainController = mainController;
    }

    public static MainController getMainController() {
        return VistaNavigator.mainController;
    }

    /**
     * Stores the printer controller for later use in printing tasks.
     *
     * @param printerController the printer application layout controller.
     */
    public static void setPrinterController(PrinterController printerController) {
        VistaNavigator.printerController = printerController;
    }

    public static PrinterController getPrinterController() {
        return VistaNavigator.printerController;
    }

    /**
     * Stores the thread that controls the UI.
     *
     * @param ui the thread that launched the fx application.
     */
    public static void setUIThread(GraphicalUI ui) {
        VistaNavigator.uiThread = ui;
    }

    /**
     * Stores the command that is requested to be executed.
     *
     * @param command the command that needs to be executed.
     */
    public static void setCurrentCommand(UICommand command) {
        VistaNavigator.mainController.setCurrentCommand(command);
    }

    /**
     * Returns the command that is requested to be executed.
     */
    public static UICommand getCurrentCommand() {
        return VistaNavigator.mainController.getCurrentCommand();
    }

    /**
     * Loads the vista specified by the fxml file into the
     * vistaHolder pane of the main application layout.
     *
     * Previously loaded vista for the same fxml file are not cached.
     * The fxml is loaded anew and a new vista node hierarchy generated
     * every time this method is invoked.
     *
     * A more sophisticated load function could potentially add some
     * enhancements or optimizations, for example:
     *   cache FXMLLoaders
     *   cache loaded vista nodes, so they can be recalled or reused
     *   allow a user to specify vista node reuse or new creation
     *   allow back and forward history like a browser
     *
     * @param fxml the fxml file to be loaded.
     */
    public static void loadVista(String fxml) {
        try {
//            mainController.setVista(FXMLLoader.load(VistaNavigator.class.getResource(fxml)));
//            final BlockingQueue queue = new ArrayBlockingQueue(1);
            Node node = FXMLLoader.load(VistaNavigator.class.getResource(fxml));
            Platform.runLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      mainController.setVista(node);
                                  }
                              }
            );


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Prints the content into the printer application layout.
     *
     * @param content a String with the content that should be printed.
     */
    public static void cleanPrinterFX() {
        Platform.runLater(new Runnable() {
                              @Override
                              public void run() {
                                  printerController.clean();
                              }
                          }
        );
    }

    /**
     * Prints the content into the printer application layout.
     *
     * @param content a String with the content that should be printed.
     */
    public static void printFX(String content) {
        Platform.runLater(new Runnable() {
                              @Override
                              public void run() {
                                  printerController.addContent(content);
                              }
                          }
        );
    }

    /**
     * Prints the content into the printer application layout.
     *
     * @param content a String with the content that should be printed.
     */
    public static void printFX(BufferedImage content) {
        Platform.runLater(new Runnable() {
                              @Override
                              public void run() {
                                  printerController.addContent(content);
                              }
                          }
        );
    }

    /**
     * Loads the 'LOADING' vista
     * vistaHolder pane of the main application layout.
     *
     * The parameter allows to set some special text to show in the new vista.
     *
     * @param text the extra text to show instead of 'loading...'
     */
    public static void loadLoadingVista(String text) {
        try {
            FXMLLoader loader = new FXMLLoader(VistaNavigator.class.getResource(VistaNavigator.LOADING));
            Node node = (Node) loader.load();
            LoadingController loadingController = loader.getController();
            loadingController.setContent(text);
            Platform.runLater(new Runnable() {
                                  @Override
                                  public void run() {
                                      mainController.setVista(node);
                                  }
                              }
            );


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}