import org.jibble.pircbot.*;
import java.util.regex.*;
import java.util.*;

public class Bot extends PircBot {
	public Bot() {
		this.setName("stp_jarvur");
		ticks = 0;
		climate = 0;
		needsReset = true;
		playerInfo = new HashMap<String,PlayerInfo>();
		loginList = new HashMap<String,String>();
		notInGame = new HashSet<String>();
	}

	String username = "test";
	String password = "test";

	boolean playing = false;
	String talkto = null;
	String talkchan = null;

	Map<String,PlayerInfo> playerInfo;
	Map<String,String> loginList;
	Set<String> notInGame;
	PlayerInfo myself = null;
	boolean needsReset;

	int ticks;
	double climate;

	public void onMessage(String channel, String sender,
			String login, String hostname, String message) {

		if (!playing) {
			Pattern foo = Pattern.compile("^NEW (.+)");
			loginList.clear();
			Matcher m = foo.matcher(message);
			if (m.matches()) {
				talkto = sender + "!" + login + "@" + hostname;
				talkchan = channel;
				try {
					sendMessage(sender, "LOGIN " + username + " " +
						AeSimpleSHA1.SHA1(m.group(1) + password));
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
				playing = true;
			}
		} else if (talkto.equals(sender+"!"+login+"@"+hostname)) {
			Pattern statePat = Pattern.compile("^STATE (.+)");
			Pattern thingyPat = Pattern.compile("(.+)\\[(.+)\\]");
			Matcher mat = statePat.matcher(message);
			if (mat.matches()) {
				if (needsReset) {
					needsReset = false;
					myself = null;
					Iterator<String> a = playerInfo.keySet().iterator();
					notInGame.clear();
					if (a.hasNext()) {
						String n;
						for(n = a.next(); a.hasNext(); n = a.next()) {
							notInGame.add(n);
						}
					}
				}
				String[] updates = mat.group(1).split("\\s*;\\s*");

				int i;
				for(i=0; i<updates.length; i++) {
					mat = thingyPat.matcher(updates[i]);
					if (mat.matches()) {
						String name = mat.group(1);
						String[] info = mat.group(2).split("\\s*,\\s*");
						int j;
						HashMap<String,String> inf = new HashMap<String,String>();
						for(j=0; j<info.length; j++) {
							String[] bits = info[j].split("=");
							inf.put(bits[0], bits[1]);
						}
						if (name.equals("CLIMATE")) {
							ticks = Integer.parseInt(inf.get("t"));
							climate = Double.parseDouble(inf.get("s"));
						} else if (inf.containsKey("i") && inf.containsKey("c")) {
							PlayerInfo np = new PlayerInfo();
							np.industry = Integer.parseInt(inf.get("i"));
							np.cash = Integer.parseInt(inf.get("c"));
							playerInfo.put(name, np);
							notInGame.remove(name);
						}
					}
				}
			} else if (message.matches("^ENDTICK$")) {
				needsReset = true;
				Iterator<String> a = notInGame.iterator();
				String n;
				if (a.hasNext()) {
					for(n = a.next(); a.hasNext(); n = a.next()) {
						playerInfo.remove(n);
					}
				}
				if (playerInfo.containsKey(username)) {
					myself = playerInfo.get(username);
				} else {
					myself = null;
				}
				if (myself != null) {
					doStuff();
				} else {
					playing = false;
				}
			} else if (message.startsWith("PLAYERS")) {
				// Parse player list.
				String[] bits = message.substring(8).split(",");
				int i;
				for(i=0; i<bits.length; i++) {
					String[] bits2 = bits[i].split("=");
					loginList.put(bits2[0], bits2[1]);
				}
			} else if (message.matches("(GOOD|BAD)END$")) {
				talkto = null;
				talkchan = null;
				playing = false;
			} else if (message.matches("RESET")) {
				talkto = null;
				talkchan = null;
				playing = false;
			}
		} else if (loginList.containsKey(sender) && playerInfo.containsKey(loginList.get(sender))) {
			// Another bot, which is still playing.
			if (message.toUpperCase().startsWith("DONATE")) {
				onDonate(loginList.get(sender), toInt(message.substring(7)));
			} else if (message.toUpperCase().startsWith("INVEST")) {
				onInvest(loginList.get(sender), toInt(message.substring(7)));
			} else if (message.toUpperCase().startsWith("CUTBACK")) {
				onCutBack(loginList.get(sender), toInt(message.substring(8)));
			}
		}
	}

	public int toInt(String s) {
		try {
			return Integer.parseInt(s);
		} catch (Throwable e) {
			return 0;
		}
	}

	public void donate(int amount) {
		sendMessage(talkchan, "DONATE " + amount);
	}

	public void invest(int amount) {
		sendMessage(talkchan, "INVEST " + amount);
	}

	public void cutback(int amount) {
		sendMessage(talkchan, "CUTBACK " + amount);
	}

	public void onDonate(String user, int amount) {
		System.out.println("ACTION: " + user + " DONATE " + amount);
	}

	public void onInvest(String user, int amount) {
		System.out.println("ACTION: " + user + " INVEST " + amount);
	}

	public void onCutBack(String user, int amount) {
		System.out.println("ACTION: " + user + " CUTBACK " + amount);
	}

	public void doStuff() {
		donate(myself.cash);
	}
}
