/
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.network.console;


import net.sourceforge.pain.data.type.*;
import net.sourceforge.pain.util.*;
import net.sourceforge.pain.*;

import java.util.*;

public final class Console {

	protected static final int STATE_NEW = -1; //new connection
	protected static final int STATE_ACTIVE = 0; // active connection
	protected static final int STATE_SYSTEM_CLOSED = 1; // connection marked to be closed from system
	protected static final int STATE_REMOTE_CLOSED_1 = 2; // remotely closed connection
	protected static final int STATE_REMOTE_CLOSED_2 = 3; //

	public static int MAX_INACTIVE_TIME = 6000; // in pulses

	private Object playerId = null;

	protected Object rawCommand = null;

	protected LinkedList input = new LinkedList();
	protected ConsoleAdapter adapter = null;
	protected int expireTime = 0; // in net.sourceforge.pain.Time pulses
	protected int state = STATE_NEW;

	protected boolean hasBufferedOutput = false;

//	private Map attributes = new HashMap();

	boolean newLineProcessingStarted = true;

	protected Console(ConsoleAdapter adapter) {
		this.adapter = adapter;
	}

//	protected ConsoleAdapter getAdapter() {
//		return adapter;
//	}

	public boolean isRawMode() {
		return rawCommand != null;
	}

	public boolean isCommandMode() {
		return rawCommand == null;
	}

	public void setRawMode(Object rawCommand) {
		this.rawCommand = rawCommand;
	}

	public void setCommandMode() {
		rawCommand = null;
	}

	public Object getRawCommand() {
		return rawCommand;
	}

	public String popInputLine() {
		if (input.isEmpty()) {
			return null;
		}
		return (String) input.removeFirst();
	}

	public Console out(String text) {
		if (text == null) {
			Log.warn("Console: out 'null'");
			return this;
		}
		if (!hasBufferedOutput && !isRawMode() && !newLineProcessingStarted) { //new console output should starts from new line
			adapterOut(ConsoleAdapter.NEW_LINE);
		}
		hasBufferedOutput = true;
		newLineProcessingStarted = false;
		adapterOut(text);
		return this;
	}

	private void adapterOut(String text) {
		if (adapter != null) {
			adapter.outText(text);
		}
	}

	public Player getPlayer() {
		return (Player) (playerId == null ? null : Core.getDB().getObject(playerId));
	}

	public void setPlayer(Player newPlayer) {
		if (playerId != null && newPlayer != null) {
			throw new RuntimeException("Owner redefinition not supported!");
		}
		if (playerId == null && newPlayer == null) {
			throw new RuntimeException("BUG, newPlayer is null!");
		}
		playerId = newPlayer == null ? null : newPlayer.getOid();
	}


	public void flushOutput() {
		if (!hasBufferedOutput) {
			return;
		}
		if (adapter != null) {
			try {
				adapter.flush();
			} catch (Exception e) {
				Log.error(e.getMessage(), e); // todo: revise ignorance
			}
		}
		hasBufferedOutput = false;
	}

	public void pushInputLine(String line) {
		input.addFirst(line);
	}
}