package be.iminds.ilabt.jfed.ui.javafx;

import javafx.fxml.FXMLLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Provider;
import java.io.IOException;
import java.net.URL;

/**
 * User: twalcari
 * Date: 5/21/2015
 * Time: 09:00
 */
public class GuiceFXMLUtil {
    private static final Logger LOG = LoggerFactory.getLogger(GuiceFXMLUtil.class);

    private static final String FXML_SUFFIX = ".fxml";

    private final Provider<FXMLLoader> fxmlLoaderProvider;

    @Inject
    GuiceFXMLUtil(Provider<FXMLLoader> fxmlLoaderProvider) {
        this.fxmlLoaderProvider = fxmlLoaderProvider;
    }


    public <R extends javafx.scene.Parent, C> Result<R, C> createFromFXML(Class<C> clazz) {
        FXMLLoader loader = fxmlLoaderProvider.get();
        loader.setLocation(getFXMLUrl(clazz));

        try {
            R root = loader.load();
            C controller = loader.getController();

            return new Result<>(root, controller);
        } catch (IOException ex) {
            LOG.error("Could not load FXML-file for {}", clazz.getName(), ex);
            throw new RuntimeException(ex);
        }
    }

    public static class Result<R extends javafx.scene.Parent, C> {
        private final R root;
        private final C controller;

        public Result(R root, C controller) {
            this.root = root;
            this.controller = controller;
        }

        public R getRoot() {
            return root;
        }

        public C getController() {
            return controller;
        }
    }

    public static URL getFXMLUrl(Class clazz) {
        //we expect the FXML-file to be named exactly like the class-name. ex: ExperimenterGUI.java --> ExperimenterGUI.fxml
        final String fxmlFileName = clazz.getSimpleName() + FXML_SUFFIX;
        URL fxmlUrl = clazz.getResource(fxmlFileName);

        if (fxmlUrl == null && clazz.getSimpleName().endsWith("Controller")) {
            //'Controller' is 10 characters

            fxmlUrl = clazz.getResource(clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 10) + FXML_SUFFIX);
        }

        if (fxmlUrl == null) {
            throw new NullPointerException("Could not resolve fxml-file '" + fxmlFileName + "' for class '" + clazz + "'");
        }

        return fxmlUrl;
    }

}
