import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Random;

import net.minecraft.client.Minecraft;

public class SAPI {
	private static Minecraft instance;
	public static boolean usingText = false;
	
	static {
		showText();
	}
	
	public static void showText() {
		if (!usingText) {
			System.out.println("Using ShockAhPI r5");
			usingText = true;
		}
	}
	
	public static Minecraft getMinecraftInstance() {
		if (instance == null) {
			try {
				ThreadGroup group = Thread.currentThread().getThreadGroup();
				int count = group.activeCount();
				Thread[] threads = new Thread[count];
				group.enumerate(threads);
				for (int i = 0; i < threads.length; i++)
				if (threads[i].getName().equals("Minecraft main thread")) {
					Field field = Thread.class.getDeclaredField("target");
					field.setAccessible(true);
					instance = (Minecraft)field.get(threads[i]);
					break;
				}
			} catch (Exception e) {e.printStackTrace();}
		}
		return instance;
	}
	
	/*
	 * Harvest Intercept API
	 */
	
	private static ArrayList<IInterceptHarvest> harvestIntercepts = new ArrayList<IInterceptHarvest>();
	public static void interceptAdd(IInterceptHarvest intercept) {
		harvestIntercepts.add(intercept);
	}
	public static boolean interceptHarvest(fd world, gs player, Loc loc, int blockID, int meta) {
		for (IInterceptHarvest inter : harvestIntercepts) {
			if (inter.canIntercept(world,player,loc,blockID,meta)) {
				inter.intercept(world,player,loc,blockID,meta);
				return true;
			}
		}
		return false;
	}
	public static void drop(fd world, Loc loc, iz stack) {
		if (world.B) return;
		
		for (int i2 = 0; i2 < stack.a; i2++) {
			float f1 = 0.7F;
			double d1 = world.r.nextFloat() * f1 + (1.0F - f1) * 0.5D;
			double d2 = world.r.nextFloat() * f1 + (1.0F - f1) * 0.5D;
			double d3 = world.r.nextFloat() * f1 + (1.0F - f1) * 0.5D;
			hl localhj = new hl(world, loc.x() + d1, loc.y() + d2, loc.z() + d3, new iz(stack.c,1,stack.i()));
			localhj.c = 10;
			world.b(localhj);
		}
	}
	
	/*
	 * BlockSet Intercept API
	 */
	
	private static ArrayList<IInterceptBlockSet> setIntercepts = new ArrayList<IInterceptBlockSet>();
	public static void interceptAdd(IInterceptBlockSet intercept) {
		setIntercepts.add(intercept);
	}
	public static int interceptBlockSet(fd world, Loc loc, int blockID) {
		for (IInterceptBlockSet inter : setIntercepts) {
			if (inter.canIntercept(world,loc,blockID)) {
				return inter.intercept(world,loc,blockID);
			}
		}
		return blockID;
	}
	
	/*
	 * Reach API
	 */
	
	private static ArrayList<IReach> reaches = new ArrayList<IReach>();
	public static void reachAdd(IReach reach) {
		reaches.add(reach);
	}
	public static float reachGet() {
		iz inHand = getMinecraftInstance().h.c.b();
		
		for (IReach reach : reaches) {
			if (reach.reachItemMatches(inHand)) return reach.getReach(inHand);
		}
		return 4F;
	}
	
	/*
	 * Dungeon API
	 */
	
	private static ArrayList<String> dngMobs = new ArrayList<String>();
	private static ArrayList<DungeonLoot> dngItems = new ArrayList<DungeonLoot>();
	private static ArrayList<DungeonLoot> dngGuaranteed = new ArrayList<DungeonLoot>();
	private static boolean dngAddedMobs = false, dngAddedItems = false;
	
	public static void dungeonAddMob(String mob) {
		dungeonAddMob(mob,10);
	}
	public static void dungeonAddMob(String mob, int chances) {
		for (int i = 0; i < chances; i++) dngMobs.add(mob);
	}
	public static void dungeonRemoveMob(String mob) {
		for (int i = 0; i < dngMobs.size(); i++) {
			if (dngMobs.get(i).equals(mob)) {
				dngMobs.remove(i);
				i--;
			}
		}
	}
	public static void dungeonRemoveAllMobs() {
		dngAddedMobs = true;
		dngMobs.clear();
	}
	static void dungeonAddDefaultMobs() {
		for (int i = 0; i < 10; i++) dngMobs.add("Skeleton");
		for (int i = 0; i < 20; i++) dngMobs.add("Zombie");
		for (int i = 0; i < 10; i++) dngMobs.add("Spider");
	}
	public static String dungeonGetRandomMob() {
		if (!dngAddedMobs) {
			dungeonAddDefaultMobs();
			dngAddedMobs = true;
		}
		if (dngMobs.isEmpty()) return "Pig";
		return dngMobs.get(new Random().nextInt(dngMobs.size()));
	}
	
	public static void dungeonAddItem(DungeonLoot loot) {
		dungeonAddItem(loot,100);
	}
	public static void dungeonAddItem(DungeonLoot loot, int chances) {
		for (int i = 0; i < chances; i++) dngItems.add(loot);
	}
	public static void dungeonAddGuaranteedItem(DungeonLoot loot) {
		dngGuaranteed.add(loot);
	}
	public static int dungeonGetAmountOfGuaranteed() {
		return dngGuaranteed.size();
	}
	public static DungeonLoot dungeonGetGuaranteed(int index) {
		return dngGuaranteed.get(index);
	}
	public static void dungeonRemoveItem(int id) {
		for (int i = 0; i < dngItems.size(); i++) {
			if (dngItems.get(i).loot.c == id) {
				dngItems.remove(i);
				i--;
			}
		}
		for (int i = 0; i < dngGuaranteed.size(); i++) {
			if (dngGuaranteed.get(i).loot.c == id) {
				dngGuaranteed.remove(i);
				i--;
			}
		}
	}
	public static void dungeonRemoveAllItems() {
		dngAddedItems = true;
		dngItems.clear();
		dngGuaranteed.clear();
	}
	static void dungeonAddDefaultItems() {
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.ay)));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.m),1,4));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.S)));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.R),1,4));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.K),1,4));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.I),1,4));
		for (int i = 0; i < 100; i++) dngItems.add(new DungeonLoot(new iz(gm.au)));
		dngItems.add(new DungeonLoot(new iz(gm.ar)));
		for (int i = 0; i < 50; i++) dngItems.add(new DungeonLoot(new iz(gm.aA),1,4));
		for (int i = 0; i < 5; i++) dngItems.add(new DungeonLoot(new iz(gm.bd)));
		for (int i = 0; i < 5; i++) dngItems.add(new DungeonLoot(new iz(gm.be)));
	}
	public static iz dungeonGetRandomItem() {
		if (!dngAddedItems) {
			dungeonAddDefaultItems();
			dngAddedItems = true;
		}
		if (dngItems.isEmpty()) return null;
		return dngItems.get(new Random().nextInt(dngItems.size())).getStack();
	}
	
	/*
	 * Achievement Pages
	 */
	
	public static int acCurrentPage = 0;
	private static ArrayList<Integer> acHidden = new ArrayList<Integer>();
	private static ArrayList<ACPage> acPages = new ArrayList<ACPage>();
	public static final ACPage acDefaultPage = new ACPage();
	
	public static void acPageAdd(ACPage page) {
		acPages.add(page);
	}
	public static void acHide(ny... achievements) {
		for (ny achievement : achievements) acHidden.add(achievement.e);
	}
	public static boolean acIsHidden(ny achievement) {
		return acHidden.contains(achievement.e);
	}
	public static ACPage acGetPage(ny achievement) {
		if (achievement == null) return null;
		for (ACPage Page : acPages) if (Page.list.contains(achievement.e)) return Page;
		return acDefaultPage;
	}
	public static ACPage acGetCurrentPage() {
		return acPages.get(acCurrentPage);
	}
	public static String acGetCurrentPageTitle() {
		return acGetCurrentPage().title;
	}
	public static void acPageNext() {
		acCurrentPage++;
		if (acCurrentPage > acPages.size()-1) acCurrentPage = 0;
	}
	public static void acPagePrev() {
		acCurrentPage--;
		if (acCurrentPage < 0) acCurrentPage = acPages.size()-1;
	}
}