package be.iminds.ilabt.jfed.util;

import com.google.inject.*;
import javafx.fxml.FXMLLoader;

import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * User: twalcari
 * Date: 8/10/2016
 * Time: 11:09
 */
public class GuiceContext {
    private final Object contextRoot;
    protected Injector injector;
    private final Supplier<Collection<Module>> modules;

    public GuiceContext(Object contextRoot, Supplier<Collection<Module>> modules) {
        this.contextRoot = Objects.requireNonNull(contextRoot);
        this.modules = Objects.requireNonNull(modules);
    }

    public void injectMembers(Object obj) {
        this.injector.injectMembers(obj);
    }

    public <T> T getInstance(Class<T> cls) {
        return this.injector.getInstance(cls);
    }

    public final void init() {
        HashSet<Module> allModules = new HashSet<>();
        allModules.addAll(this.modules.get());
        allModules.add(new GuiceContext.FXModule());
        this.injector = Guice.createInjector(allModules);
        this.injectMembers(this.contextRoot);
    }

    private class FXModule extends AbstractModule {
        private FXModule() {
        }

        protected void configure() {
        }

        @Provides
        FXMLLoader provideFxmlLoader() {
            FXMLLoader loader = new FXMLLoader();
            loader.setControllerFactory(GuiceContext.this::getInstance);
            return loader;
        }
    }
}
