package vermilion;

import java.util.ArrayList;
import JSSPF.*;

public class SystemPluginManager
{
    // The system preference name we use to find the main system modules.
    public static final String STARTUP_PLUGINS_PREF = "Startup Plugins";

    // Stores the list of system plugin instances created at startup.
    private ArrayList<PluginClassVermilion> system = new ArrayList<PluginClassVermilion>();

    private PluginClassManager pluginSource;

    public SystemPluginManager()
    {
        pluginSource = new PluginClassManager("plugins/", false);
    }

    public PluginClassVermilion getPlugin(String pluginName)
    {
        PluginClassBase base = pluginSource.getPlugin(pluginName);
        if (base instanceof PluginClassVermilion) return (PluginClassVermilion) base;
        return null;
    }

    public ArrayList<PluginClassDef> getPluginList()
    {
        return pluginSource.getPluginList();
    }

    /**
     * Creates instances of plugins listed as startup plugins and initialises
     * them, allowing them to build GUIs, connect to system components etc.
     */
    public void loadSystem()
    {
        // Load startup plugins and call initialise on them.
        UsefulFileObjectList startupPlugins = (UsefulFileObjectList) Main.settings.getValue(STARTUP_PLUGINS_PREF);
        if (startupPlugins != null)
        {
            for (int x = 0; x < startupPlugins.size(); x++)
            {
                UsefulFileObjectSimple obj = (UsefulFileObjectSimple) startupPlugins.get(x);
                String str = obj.strValue;
                PluginClassVermilion oBase = (PluginClassVermilion) getPlugin(str);
                if (oBase != null)
                {
                    oBase.initialise();
                    system.add(oBase);
                }
            }
        }
    }

    /**
     * Called during reinitialisation or closing, unloads each system plugin
     * loaded at startup.
     */
    public void unloadSystem()
    {
        // Load startup plugins and call initialise on them.
        for (PluginClassVermilion oBase : system)
        {
            oBase.deinitialise();
        }

        system.clear();
    }

    /**
     * Calls documentLoaded on all system plugins, so they can
     * read from the composition and create runtime data.
     */
    public void documentLoaded()
    {
        for (PluginClassVermilion oBase : system)
        {
            oBase.documentLoaded();
        }
    }

    /**
     * Calls documentSaving on all system plugins, so they can
     * write a representation of runtime data into the composition.
     */
    public void documentSaving()
    {
        for (PluginClassVermilion oBase : system)
        {
            oBase.documentSaving();
        }
    }

    /**
     * Sends a message to all system plugins, allowing communication between
     * system plugins for situations where information must be passed or a
     * document update requires systems to refresh their data.
     * @param message A string indicating what has happened.
     */
    public void sendMessage(String message)
    {
        for (PluginClassVermilion oBase : system)
        {
            oBase.processMessage(message);
        }
    }
}
