/
codebase/src/net/sourceforge/pain/admin/console/command/
codebase/src/net/sourceforge/pain/data/role/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/util/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
mudlibs/tinylib/
mudlibs/tinylib/area/
mudlibs/tinylib/etc/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/prototype/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/deploy/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/fn/util/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/impl/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/command/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/reset/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/shutdown/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/social/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/util/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
package net.sourceforge.pain.tinylib.logic.event.console;

import net.sourceforge.pain.data.*;
import net.sourceforge.pain.data.role.*;
import net.sourceforge.pain.tinylib.*;
import net.sourceforge.pain.tinylib.data.type.*;
import net.sourceforge.pain.tinylib.logic.fn.*;
import net.sourceforge.pain.tinylib.logic.fn.util.*;
import net.sourceforge.pain.tinylib.util.*;
import net.sourceforge.pain.util.*;

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 = Mudlib.getWorld().getPrototypesRegistry().getPrototypeByVnum("player");
        Player p = (Player) ObjectFactory.createObject(proto).addRole(Player.class);
        p.setLogin(name.toLowerCase());
        p.setPassword(password);
        Mudlib.getWorld().getPlayersRegistry().addPlayer(p);

        ((Creature) p.getRole(Creature.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(Mudlib.getWorld().getDefaultBirthSpace());
        RelocateFn.addToSpace(Mudlib.getWorld().getPlayersQuitSpace(), p.asLocated());
        ConsoleFn.loginUser(console, p);
        console.setCommandMode();
    }

    public static List getSortedRaces() {
        Set races = Mudlib.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;

    }
}