package com.publicuhc;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.publicuhc.commands.CommandModule;
import com.publicuhc.commands.routing.Router;
import com.publicuhc.configuration.Configurator;
import com.publicuhc.configuration.ConfigurationModule;
import com.publicuhc.translate.Translate;
import com.publicuhc.translate.TranslateModule;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;

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

public abstract class FrameworkJavaPlugin extends JavaPlugin {

    private Configurator m_configurator;
    private Translate m_translate;
    private Router m_router;

    public final void onEnable() {
        List<AbstractModule> modules = initialModules();
        if(modules == null) {
            modules = new ArrayList<AbstractModule>();
        }
        if(initUseDefaultBindings()){
            modules.add(new CommandModule());
            modules.add(new ConfigurationModule());
            modules.add(new TranslateModule());
        }
        Injector injector = Guice.createInjector(modules);
        injector.injectMembers(this);
        onFrameworkEnable();
    }

    /**
     * Called when the framework is initialized
     */
    public void onFrameworkEnable() {
    }

    /**
     * Return a list of extra modules to initialize DI with.
     * Override this method to change the extra modules to load with.
     * @return the list of modules
     */
    public List<AbstractModule> initialModules() {
        return null;
    }

    /**
     * If returns true will include default modules on init.
     * If false you must specify all the bindings for the framework
     * @return whether to use the defaults or not
     */
    public boolean initUseDefaultBindings() {
        return true;
    }

    /**
     * Set the router by injection
     * @param router the router object
     */
    @Inject
    private void setRouter(Router router) {
        m_router = router;
    }

    /**
     * Set the configurator by injection
     * @param configurator the configurator object
     */
    @Inject
    private void setConfigurator(Configurator configurator) {
        m_configurator = configurator;
    }

    /**
     * Set the translate by injection
     * @param translate the translate object
     */
    @Inject
    private void setTranslate(Translate translate) {
        m_translate = translate;
    }

    /**
     * <b>ONLY USE THIS AFTER onEnable HAS BEEN CALLED. (onFrameworkEnable and later) otherwise it will return null</b>
     * @return the router object
     */
    public Router getRouter() {
        return m_router;
    }
    /**
     * <b>ONLY USE THIS AFTER onEnable HAS BEEN CALLED. (onFrameworkEnable and later) otherwise it will return null</b>
     * @return the configurator object
     */
    public Configurator getConfigurator() {
        return m_configurator;
    }

    /**
     * <b>ONLY USE THIS AFTER onEnable HAS BEEN CALLED. (onFrameworkEnable and later) otherwise it will return null</b>
     * @return the translate object
     */
    public Translate getTranslate() {
        return m_translate;
    }
}

@@ -466,36 +466,134 @@
 kit.
-plugin.PluginDescriptionFile
+Server;%0Aimport org.bukkit.plugin.Plugin;%0Aimport org.bukkit.plugin.PluginDescriptionFile;%0Aimport org.bukkit.plugin.PluginLoader
 ;%0Aim
@@ -924,16 +924,362 @@
 outer;%0A%0A
+    /**%0A     * This method is intended for unit testing purposes. Its existence may be temporary.%0A     * @see org.bukkit.plugin.java.JavaPlugin%0A     */%0A    protected FrameworkJavaPlugin(PluginLoader loader, Server server, PluginDescriptionFile pdf, File file1, File file2) %7B%0A        super(loader, server, pdf, file1, file2);%0A    %7D%0A%0A    @Override%0A
     publ
@@ -1294,22 +1294,20 @@
  void on
-Enable
+Load
 () %7B%0A   
@@ -1447,32 +1447,255 @@
 e%3E();%0A        %7D%0A
+        final Plugin plugin = this;%0A        modules.add(new AbstractModule() %7B%0A            @Override%0A            protected void configure() %7B%0A                bind(Plugin.class).toInstance(plugin);%0A            %7D%0A        %7D);%0A
         if(initU
@@ -1988,22 +1988,20 @@
 ramework
-Enable
+Load
 ();%0A    
@@ -2047,25 +2047,20 @@
 work is 
-initializ
+load
 ed%0A     
@@ -2089,22 +2089,20 @@
 ramework
-Enable
+Load
 () %7B%0A   
@@ -3279,38 +3279,36 @@
 SE THIS AFTER on
-Enable
+Load
  HAS BEEN CALLED
@@ -3313,38 +3313,36 @@
 ED. (onFramework
-Enable
+Load
  and later) othe
@@ -3507,38 +3507,36 @@
 SE THIS AFTER on
-Enable
+Load
  HAS BEEN CALLED
@@ -3541,38 +3541,36 @@
 ED. (onFramework
-Enable
+Load
  and later) othe
@@ -3804,22 +3804,20 @@
 ramework
-Enable
+Load
  and lat

switch init to the onLoad method and trigger a onFrameworkLoad instead added constuctor for unit testing bind plugin on load for DI