package com.plugin;

import java.applet.Applet;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.swing.JOptionPane;

import com.pkc.settings.Settings;

/**
 * @author Mykolas Juraitis
 */
public class PluginManager extends Applet {

	public PluginManager(int byDimmension_, int byVolume_, int byRatio_, int byMinMax_, int byRandom_)
	{
		Settings.byDimmension = byDimmension_;
		Settings.byVolume = byVolume_;
		Settings.byRatio = byRatio_;
		Settings.byMinMax = byMinMax_;
		Settings.byRandom = byRandom_;
	}

	public final static String PARAM_PREFIX = "-";

	private static Map parameters = new HashMap();

	public static void registerParam(Parameter param) {
		parameters.put(param.getName(), param);
	}

	private static class PluginEntry implements Comparable {

		Plugin plugin;

		int priority;

		public PluginEntry(Plugin plugin, int priority) {
			this.plugin = plugin;
			this.priority = priority;
		}

		public int compareTo(Object o) {
			int priority = ((PluginEntry)o).priority;
			return this.priority < priority ? 1 : this.priority > priority ? -1 : 0;
		}

		public Plugin getPlugin() {
			return plugin;
		}
	}

	public void start() {
		new plugins.GenByCutting.GenByCutting().run();
	//	new plugins.LoadFromThpackFile.ThpackFile().run();
		new plugins.ManualDataEntry.ManualDataEntry().run();
		new plugins.GUI.GUI().run();
	}

	public static void main(String args[]) {
		try {
			List plugins = new ArrayList();
			File files[] = (new File("plugins")).listFiles();
			for (int i = 0; i < files.length; i++)
				if (files[i].isDirectory()) {
					try {
						Properties pluginProperties = new Properties();
						File file = new File(files[i].getAbsolutePath() + File.separator + "plugin.properties");
						if (file.exists()) {
							FileInputStream fileInputStream = new FileInputStream(file);
							pluginProperties.load(fileInputStream);
							fileInputStream.close();
							String className = pluginProperties.getProperty("main");
							Class pluginClass = Class.forName(className);
							Object object = pluginClass.newInstance();
							if (object instanceof Plugin)
								plugins.add(new PluginManager.PluginEntry((Plugin)object, Integer.parseInt(pluginProperties.getProperty("priority"))));
						}
					}
					catch (Exception e) {
						System.out.println("Exception occured while loading plugins: " + e);
						e.printStackTrace();
					}
				}
			// Process command line parameters
			int i = 0;
			processParams:
				while (i < args.length) {
					String param = args[i];
					if (!param.startsWith(PARAM_PREFIX))
						throw new Exception("Invalid option '" + param + "'.\nOption must start with '" + PARAM_PREFIX + "'.");
					param = param.substring(PARAM_PREFIX.length());
					if (param.equals("help")) {
						printHelpScreen(parameters, System.out);
						throw new Exception("");
					}
					Parameter parameter = (Parameter)parameters.get(param);
					if (parameter != null) {
						i++;
						if (args.length - i < parameter.getArgCount())
							throw new Exception("Not enougth arguments for option '" + param + "'");
						for (int k = 0; k < parameter.getArgCount(); k++, i++)
							parameter.setArg(args[i], k);
						parameter.process();
					}
					else
						throw new Exception("Unknown option '" + PARAM_PREFIX + param + "'.\nUse option '-help' to see all available options.");
				}
			// Run plugins
			Collections.sort(plugins);
			while (plugins.size() > 0)
				((PluginEntry)plugins.remove(0)).getPlugin().run();
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
			//e.printStackTrace();
		}
	}

	private static void printHelpScreen(Map parameters, PrintStream output) {
		output.println(Settings.BANNER);
		output.println("USAGE: java " + PluginManager.class.getName() + " [options...]");
		output.println("Available options:");
		for (Iterator params = parameters.keySet().iterator(); params.hasNext(); ) {
			Parameter parameter = (Parameter)parameters.get(params.next());
			output.print("\t" + PARAM_PREFIX + parameter.getName());
			for (int i = 0; i < parameter.getArgCount(); i++)
				output.print(" " + parameter.getArgName(i));
			output.println("\n\t\t" + parameter.getDescription());
		}
	}
}
