/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.logic.event.console;

import net.sourceforge.pain.*;
import net.sourceforge.pain.util.*;
import net.sourceforge.pain.util.rom.*;
import net.sourceforge.pain.network.console.*;
import net.sourceforge.pain.data.type.*;
import net.sourceforge.pain.data.prototype.*;
import net.sourceforge.pain.logic.fn.*;
import net.sourceforge.pain.logic.fn.util.*;
import net.sourceforge.pain.logic.fn.factory.*;

import java.util.*;

/**
 * PAiN MUD CODEBASE
 * User: fmike
 * Date: Jan 17, 2003
 * Time: 3:45:58 AM
 */
public final class RegistrationShell extends CommandHandler {

	public static final int INIT = 1;
	public static final int CONFIRM_NAME = 2;
	public static final int GET_PASS = 3;
	public static final int REPEAT_PASS = 4;
	public static final int CHOOSE_RACE = 5;

	private String name;
	private String password;
	private Console console;

	private int state = INIT;
	private Race race;

	public RegistrationShell(String login, Console console) {
		this.name = Utils.formatName(login);
		this.console = console;
	}

	public void processCommand() throws Exception {
		boolean ok = false;
		try {
			switch (state) {
				case INIT:
					console.setRawMode(this);
					askNameConfirm();
					break;
				case CONFIRM_NAME:
					checkNameConfirm();
					break;
				case GET_PASS:
					getPass();
					break;
				case REPEAT_PASS:
					checkPass();
					break;
				case CHOOSE_RACE:
					checkRace();
					break;
				default:
					throw new RuntimeException("unknon state:" + state);
			}
			ok = true;
		} finally {
			if (!ok) {
				ConsoleFn.forceDisconnect(console);
			}
		}
	}

	private void askNameConfirm() {
		MessageOutFn.out(console, "Do you want to be known here as {w" + name + "{x (y/n)?:");
		state = CONFIRM_NAME;
	}

	public void checkNameConfirm() throws Exception {
		String reply = console.popInputLine().toUpperCase();
		if (reply.equals("Y") || reply.equals("YE") || reply.equals("YES")) {
			askPass();
		} else if (reply.equals("N") || reply.equalsIgnoreCase("NO")) {
			new LoginShell().run(console);
		} else {
			MessageOutFn.out(console, "Please enter YES or NO:");
		}
	}

	private void askPass() {
		MessageOutFn.out(console, "Enter your password:");
		state = GET_PASS;
	}

	private void getPass() {
		String line = console.popInputLine();
		if (line == null || line.length() < 5) {
			MessageOutFn.outln(console, "{rERROR: password must be at least 5 characters long{x");
			askPass();
		} else {
			password = line;
			MessageOutFn.out(console, "Repeat password:");
			state = REPEAT_PASS;
		}
	}

	private void checkPass() throws Exception {
		String line = console.popInputLine();
		if (!password.equals(line)) {
			MessageOutFn.outln(console, "passwords do not match!");
			askPass();
		} else {
			askRace();
		}
	}

	private void askRace() throws Exception {
		state = CHOOSE_RACE;
		List sortedRaces = getSortedRaces();
		if (sortedRaces.isEmpty()) {
			register();
		} else {
			int i = 1;
			MessageOutFn.outln(console, "Choose your race: ");
			for (Iterator it = sortedRaces.iterator(); it.hasNext(); i++) {
				final Race race = (Race) it.next();
				MessageOutFn.outln(console, i + ". " + race.getName());
			}
		}
	}

	private void checkRace() throws Exception {
		String line = console.popInputLine();
		int num;
		try {
			num = Integer.parseInt(line.trim());
		} catch (Exception e) {
			MessageOutFn.outln(console, "Illegal option: " + line);
			askRace();
			return;
		}

		List sortedRaces = getSortedRaces();
		if (num > sortedRaces.size() || num < 1) {
			MessageOutFn.outln(console, "Illegal option: " + line);
			askRace();
			return;
		}
		race = (Race) sortedRaces.get(num - 1);
		register();
	}

	private void register() throws Exception {
		Log.debug("RegShell: Creating player: " + name);
		Prototype proto = Core.getWorld().getPrototypesRegistry().getPrototypeByVnum("player");
		Player p = (Player) GlobalFactory.createObject(proto).addRole(Player.class);
		p.setLogin(name.toLowerCase());
		p.setPassword(password);
		Core.getWorld().getPlayersRegistry().addPlayer(p);

		((LifeForm) p.getRole(LifeForm.class)).setRace(race);
		final Interactive i = p.asInteractive();
		i.setName(Utils.formatName(name));
		i.setDesc(i.getName());
		i.setTargetList(TargetList.addNameToList(i.getTargetList(), name));
		Log.debug("RegShell: new player created:" + p.getLogin());
		p.setQuitSpace(Core.getWorld().getDefaultBirthSpace());
		RelocateFn.addToSpace(Core.getWorld().getPlayersQuitSpace(), p.asLocated());
		ConsoleFn.loginUser(console, p);
		console.setCommandMode();
	}

	public static List getSortedRaces() {
		Set races = Core.getWorld().getRaces();
		List sortedRaces = new ArrayList(races);
		if (races.size() > 1) {
			Comparator c = new Comparator() {
				public int compare(Object o1, Object o2) {
					return ((Race) o1).getName().compareTo(((Race) o2).getName());
				}
			};
			Collections.sort(sortedRaces, c);
		}
		return sortedRaces;

	}
}