package edu.umd.rhsmith.diads.meater.util.console; import static edu.umd.rhsmith.diads.meater.util.Util.indentLines; import static java.lang.String.format; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.LinkedList; import java.util.Scanner; public class Console { // i/o private final PrintStream out; private final Scanner in; // indentation state private int totalIndent; private LinkedList<Integer> indents; private String indentSequence; public Console(InputStream in, OutputStream out, String indentSequence) { this.totalIndent = 0; this.indents = new LinkedList<Integer>(); this.indentSequence = indentSequence; this.out = new PrintStream(out); this.in = new Scanner(in); } public void pushIndent(int level) { if (level < 0 || level >= DIVIDERS.length) { throw new IllegalArgumentException(); } totalIndent += level; indents.addLast(level); } public void popIndent() { totalIndent -= indents.removeLast(); } public int getIndentLevel() { return this.indents.size(); } public void divide(int level) { if (level < 0) { throw new IllegalArgumentException(); } say(DIVIDERS[Math.min(level, DIVIDERS.length - 1)]); } public void sayNoNewline(String message, Object... args) { out.print(indentLines(format(message, args), totalIndent, indentSequence)); } public void say(String message, Object... args) { out.println(indentLines(format(message, args), totalIndent, indentSequence)); } public void warn(String message, Object... args) { out.println(indentLines(format(MSG_WARN_FMT, format(message, args)), totalIndent, indentSequence)); } public void error(String message, Object... args) { out.println(indentLines(format(MSG_ERROR_FMT, format(message, args)), totalIndent, indentSequence)); } public void sayNoNewline(String message) { out.print(indentLines(message, totalIndent, indentSequence)); } public void say(String message) { out.println(indentLines(message, totalIndent, indentSequence)); } public void warn(String message) { out.println(indentLines(format(MSG_WARN_FMT, message), totalIndent, indentSequence)); } public void error(String message) { out.println(indentLines(format(MSG_ERROR_FMT, message), totalIndent, indentSequence)); } /* * -------------------------------- * Prompt user for things * -------------------------------- */ public String prompt(boolean breakOnEmpty) { while (true) { sayNoNewline(MSG_PROMPT); String input = in.nextLine(); if (breakOnEmpty && input.isEmpty()) { break; } else { return input; } } return null; } public <E> E prompt(ConsolePrompter<E> prompt, boolean breakOnEmpty) { while (true) { if (prompt.getPromptText() != null) { sayNoNewline(MSG_PROMPT_FMT, prompt.getPromptText()); } else { sayNoNewline(MSG_PROMPT); } try { String input = in.nextLine(); if (breakOnEmpty && input.isEmpty()) { break; } else { return prompt.accept(input); } } catch (IllegalArgumentException e) { error(e.getMessage()); } } return null; } /* * -------------------------------- * Some constants for output * -------------------------------- */ // prompts private static final String MSG_PROMPT = "> "; private static final String MSG_PROMPT_FMT = "%s > "; // screen dividers private static final String[] DIVIDERS = new String[6]; static { DIVIDERS[0] = "---"; DIVIDERS[1] = "-----"; for (int x = 2; x < DIVIDERS.length; x++) { DIVIDERS[x] = DIVIDERS[x - 1] + DIVIDERS[x - 1]; } } /* * -------------------------------- * Messages * -------------------------------- */ // prefixes for warning, error private static final String MSG_ERROR_FMT = "###Error: %s"; private static final String MSG_WARN_FMT = ">>>Warning: %s"; }