package org.nwapw.abacus.config;

import com.moandjiezana.toml.Toml;
import com.moandjiezana.toml.TomlWriter;

import java.io.File;
import java.io.IOException;

/**
 * The configuration object that stores
 * options that the user can change.
 */
public class Configuration {

    /**
     * The TOML writer used to write this configuration to a file.
     */
    private static final TomlWriter TOML_WRITER = new TomlWriter();
    /**
     * The TOML reader used to load this config from a file.
     */
    private static final Toml TOML_READER = new Toml();

    /**
     * The implementation of the number that should be used.
     */
    private String numberImplementation = "naive";

    /**
     * Creates a new configuration with the given values.
     * @param numberImplementation the number implementation, like "naive" or "precise"
     */
    public Configuration(String numberImplementation){
        this.numberImplementation = numberImplementation;
    }

    /**
     * Loads a configuration from a given file, keeping non-specified fields default.
     * @param fromFile the file to load from.
     */
    public Configuration(File fromFile){
        if(!fromFile.exists()) return;
        copyFrom(TOML_READER.read(fromFile).to(Configuration.class));
    }

    /**
     * Copies the values from the given configuration into this one.
     * @param otherConfiguration the configuration to copy from.
     */
    public void copyFrom(Configuration otherConfiguration){
        this.numberImplementation = otherConfiguration.numberImplementation;
    }

    /**
     * Saves this configuration to the given file, creating
     * any directories that do not exist.
     * @param file the file to save to.
     */
    public void saveTo(File file){
        if(file.getParentFile() != null) file.getParentFile().mkdirs();
        try {
            TOML_WRITER.write(this, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Gets the number implementation from this configuration.
     * @return the number implementation.
     */
    public String getNumberImplementation() {
        return numberImplementation;
    }

    /**
     * Sets the number implementation for the configuration
     * @param numberImplementation the number implementation.
     */
    public void setNumberImplementation(String numberImplementation) {
        this.numberImplementation = numberImplementation;
    }
}

@@ -152,16 +152,118 @@
 ception;
+%0Aimport java.util.Arrays;%0Aimport java.util.Collection;%0Aimport java.util.HashSet;%0Aimport java.util.Set;
 %0A%0A/**%0A *
@@ -783,16 +783,150 @@
 %22naive%22;
+%0A    /**%0A     * The list of disabled plugins in this Configuration.%0A     */%0A    private Set%3CString%3E disabledPlugins = new HashSet%3C%3E();
 %0A%0A    /*
@@ -1073,16 +1073,76 @@
 recise%22%0A
+     * @param disabledPlugins the list of disabled plugins.%0A
      */%0A
@@ -1189,24 +1189,50 @@
 plementation
+, String%5B%5D disabledPlugins
 )%7B%0A        t
@@ -1272,32 +1272,101 @@
 Implementation;%0A
+        this.disabledPlugins.addAll(Arrays.asList(disabledPlugins));%0A
     %7D%0A%0A    /**%0A 
@@ -1940,32 +1940,105 @@
 Implementation;%0A
+        this.disabledPlugins.addAll(otherConfiguration.disabledPlugins);%0A
     %7D%0A%0A    /**%0A 
@@ -2918,10 +2918,935 @@
 ;%0A    %7D%0A
+%0A    /**%0A     * Gets the list of disabled plugins.%0A     * @return the list of disabled plugins.%0A     */%0A    public Set%3CString%3E getDisabledPlugins() %7B%0A        return disabledPlugins;%0A    %7D%0A%0A    /**%0A     * Adds the given plugin to the disabled plugins list.%0A     * @param pluginClass the plugin to disable.%0A     */%0A    public void disablePlugin(String pluginClass)%7B%0A        disabledPlugins.add(pluginClass);%0A    %7D%0A%0A    /**%0A     * Removes the given plugin from the disabled plugins list.%0A     * @param pluginClass the plugin to enable.%0A     */%0A    public void enablePlugin(String pluginClass)%7B%0A        disabledPlugins.remove(pluginClass);%0A    %7D%0A%0A    /**%0A     * Sets the disabled plugins to be as specified.%0A     * @param newDisabled the new list of disabled plugins.%0A     */%0A    public void setDisabledPlugins(Collection%3CString%3E newDisabled)%7B%0A        disabledPlugins.clear();%0A        disabledPlugins.addAll(newDisabled);%0A    %7D%0A%0A
 %7D%0A

Add the disabled plugins configuration option.