/*
 * This file is part of MoreMaterials.
 * 
 * Copyright (c) 2012 Andre Mohren (IceReaper)
 * 
 * The MIT License
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package net.morematerials;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import net.morematerials.commands.DebugExecutor;
import net.morematerials.commands.GeneralExecutor;
import net.morematerials.commands.GiveExecutor;
import net.morematerials.listeners.MMListener;
import net.morematerials.manager.FurnaceRecipeManager;
import net.morematerials.manager.HandlerManager;
import net.morematerials.manager.SmpManager;
import net.morematerials.manager.UpdateManager;
import net.morematerials.manager.UtilsManager;
import net.morematerials.manager.AssetManager;
import net.morematerials.metrics.Metrics;
import net.morematerials.metrics.Metrics.Graph;
import net.morematerials.metrics.Metrics.Plotter;
import org.bukkit.plugin.Plugin;

import org.bukkit.plugin.java.JavaPlugin;
import org.getspout.spout.player.SimpleFileManager;
import org.getspout.spoutapi.SpoutManager;

public class MoreMaterials extends JavaPlugin {

	private HandlerManager handlerManager;
	private SmpManager smpManager;
	private UtilsManager utilsManager;
	private AssetManager assetManager;
	private UpdateManager updateManager;
	private FurnaceRecipeManager furnaceRecipeManager;
	private static List<File> cached = new ArrayList<File>();

	@Override
	public void onEnable() {
		// Try to create the required folders.
		File file;
		this.getDataFolder().mkdirs();
		String[] folders = { "materials", "handlers", "handlers/src", "handlers/bin", "cache" };
		for (String folder : folders) {
			file = new File(this.getDataFolder(), folder);
			if (!file.exists()) {
				file.mkdirs();
			}
		}

		// Initialize all managers.
		this.utilsManager = new UtilsManager(this);
		this.assetManager = new AssetManager(this);
		this.handlerManager = new HandlerManager(this);
		this.furnaceRecipeManager = new FurnaceRecipeManager();
		this.smpManager = new SmpManager(this);
		this.updateManager = new UpdateManager(this);
		this.smpManager.init();

		// Metrics.
		if (this.getConfig().getBoolean("Metrics", true)) {
			try {
				Metrics metrics = new Metrics(this);

				// It might be interesting to see how many custom materials we have at all!
				Graph materialGraph = metrics.createGraph("Number of custom materials");
				materialGraph.addPlotter(new Plotter("Materials") {
					@Override
					public int getValue() {
						return getSmpManager().getTotalMaterials();
					}
				});
				
				int totalPackages = 0;
				// At last - this is interesting for the SMP creators, we can show which SMP files are used how often!
				Graph packagesGraph = metrics.createGraph("Most used SMP packages");
				for (String fileName : (new File(this.getDataFolder().getPath(), "materials")).list()) {
					if (fileName.endsWith(".smp")) {
						totalPackages++;
						packagesGraph.addPlotter(new Plotter(fileName.substring(0, fileName.lastIndexOf("."))) {
							@Override
							public int getValue() {
								return 1;
							}
						});
					}
				}

				// Also its nice to see how many packages people have installed at once.
				Graph packageCountGraph = metrics.createGraph("Number of SMP packages");
				final int showPackages = totalPackages;
				packageCountGraph.addPlotter(new Plotter("Packages") {
					@Override
					public int getValue() {
						return showPackages;
					}
				});
				
				metrics.start();
				this.utilsManager.log("Stat tracking activated!");
			} catch (Exception exception) {
				this.utilsManager.log("Stat tracking error!", Level.SEVERE);
			}
		}
		
		//private Map<Plugin,  List<File>> preLoginCache = new HashMap<Plugin,  List<File>>();
		Class x = SimpleFileManager.class;
		try{
		Field f = x.getDeclaredField("preLoginCache");
		f.setAccessible(true);
		Map<Plugin,  List<File>> gg = (Map<Plugin,  List<File>>) f.get(SpoutManager.getFileManager());
		gg.remove(this);
		f.set(SpoutManager.getFileManager(), gg);
		} catch(Exception ex) {
			ex.printStackTrace();
		}

		// Registered events.
		this.getServer().getPluginManager().registerEvents(new MMListener(this), this);

		// Register chat commands.
		this.getCommand("mm").setExecutor(new GeneralExecutor(this));
		this.getCommand("mmdebug").setExecutor(new DebugExecutor(this));
		this.getCommand("mmgive").setExecutor(new GiveExecutor(this));
	}

	public HandlerManager getHandlerManager() {
		return this.handlerManager;
	}

	public SmpManager getSmpManager() {
		return this.smpManager;
	}

	public UtilsManager getUtilsManager() {
		return this.utilsManager;
	}

	public AssetManager getAssetManager() {
		return this.assetManager;
	}
	
	public UpdateManager getUpdateManager() {
		return this.updateManager;
	}

	public FurnaceRecipeManager getFurnaceRecipeManager() {
		return this.furnaceRecipeManager;
	}
	
	public static List<File> getCached() {
		List<File> toRet = new ArrayList<File>();
		toRet.addAll(cached);
		return toRet;
	}

	public static void addToCache(MoreMaterials plugin, File cacheFile) {
		cached.add(cacheFile);
	}

}

@@ -1245,40 +1245,8 @@
 le;%0A
-import java.lang.reflect.Field;%0A
 impo
@@ -1326,30 +1326,8 @@
 st;%0A
-import java.util.Map;%0A
 impo
@@ -1984,41 +1984,8 @@
 ter;
-%0Aimport org.bukkit.plugin.Plugin;
 %0A%0Aim
@@ -2027,103 +2027,8 @@
 gin;
-%0Aimport org.getspout.spout.player.SimpleFileManager;%0Aimport org.getspout.spoutapi.SpoutManager;
 %0A%0Apu
@@ -4605,433 +4605,8 @@
 %0A%09%09%7D
-%0A%09%09%0A%09%09//private Map%3CPlugin,  List%3CFile%3E%3E preLoginCache = new HashMap%3CPlugin,  List%3CFile%3E%3E();%0A%09%09Class x = SimpleFileManager.class;%0A%09%09try%7B%0A%09%09Field f = x.getDeclaredField(%22preLoginCache%22);%0A%09%09f.setAccessible(true);%0A%09%09Map%3CPlugin,  List%3CFile%3E%3E gg = (Map%3CPlugin,  List%3CFile%3E%3E) f.get(SpoutManager.getFileManager());%0A%09%09gg.remove(this);%0A%09%09f.set(SpoutManager.getFileManager(), gg);%0A%09%09%7D catch(Exception ex) %7B%0A%09%09%09ex.printStackTrace();%0A%09%09%7D
 %0A%0A%09%09

Revert "And the award for the messiest fix goes to..."