/
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.network.console.*;
import net.sourceforge.pain.data.type.*;
import net.sourceforge.pain.logic.fn.*;
import net.sourceforge.pain.logic.fn.util.*;
import net.sourceforge.pain.util.*;


public final class LoginShell extends CommandHandler {

	public static final int INIT = 1;
	public static final int WAIT_LOGIN = 2;
	public static final int WAIT_PASS = 3;

	private int state = INIT;

	private String login = null;
	private int attempts = 0;

	public void run(Console console) throws Exception {
		this.console = console;
		processCommand();
	}

	public void processCommand() throws Exception {
		String line = console.popInputLine();
		if (line != null) {
			line = line.trim();
		}
		Log.debug("LOGIN:line:'" + line + "'");
		switch (state) {
			case INIT:
				console.setRawMode(this);
				LogoFn.showLogo(console);
				askLogin();
				break;
			case WAIT_LOGIN:
				processLogin(line);
				break;
			case WAIT_PASS:
				processPass(line);
				break;
			default :
				throw new RuntimeException("[LOGIN]unknown state:" + state);
		}
	}


	private void processLogin(String line) throws Exception {
		if (line.length() == 0) {
			askLogin();
		} else {
			if (line.length() < 3) {
				MessageOutFn.outln(console, "\n the name you entered is too short: " + line);
				askLogin();
				return;
			}
			login = line;
			Player player = GlobalFindFn.findPlayerByName(login);
			// player login is also is player name, saved in name format with  first letter in uppercase
			if (player != null) {
				login = Utils.formatName(login);
				askPassword();
			} else {
//				MessageOutFn.outln(console, "There is no one with this name in the world");
//				askLogin();
				RegistrationShell regEvent = new RegistrationShell(login, console);
				regEvent.processCommand();
			}

		}
	}

	private void askLogin() {
		MessageOutFn.out(console, "\nEnter login:");
		login = null;
		attempts = 0;
		state = WAIT_LOGIN;
	}

	private void askPassword() {
		MessageOutFn.out(console, "Enter password:");
		state = WAIT_PASS;
	}

	private void processPass(String line) throws Exception {
		if (line == null || line.length() == 0) {
			askLogin();
			return;
		}
		final Player player = GlobalFindFn.findPlayerByName(login);
		if (line.equals(player.getPassword())) {
			loginPlayer(player);
		} else {
			MessageOutFn.out(console, "{rWrong password!{x\n");
			attempts++;
			if (attempts > 2) {
				askLogin();
			} else {
				askPassword();
			}
		}
	}

	private void loginPlayer(Player player) throws Exception {
		// Console is an only object from outer world that had a direct link to Player entry -> we should manually look for it validity
		// such ref about object removal from other place

		Console oldConsole = ConsoleFn.getConsole(player);
		if (oldConsole != null) {
			ConsoleFn.logoutUser(oldConsole);
		}
		ConsoleFn.loginUser(console, player);
	}


}