/**
 * This code, and the development history behind it can be found at:
 * http://www.github.com/wimplash/kataBankOCR-java
 */
package com.blogspot.activeactive.kata;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Entry {
  private final List<String> lines = new ArrayList<String>();

  public boolean addLine(final String line) {
    validateLine(line);
    if (isFull()) {
      return false;
    } else {
      lines.add(line);
      return true;
    }
  }

  protected List<String[]> getCharacters() {
    if (! isFull()) {
      throw new IllegalStateException("The characters in an Entry can only be"
          + " retrieved when the Entry has been fully populated.");
    }
    final List<String[]> characters = new ArrayList<String[]>();
    for (int i = 0; i < 9; i++) {
      final String[] result = new String[4];
      for (int j = 0; j < 4; j++) {
        result[j] = lines.get(j).substring(i * 3, (i + 1) * 3);
      }
      characters.add(result);
    }
    return characters;
  }

  public int getChecksum() {
    final List<Integer> digits = getDigits();
    int checksum = 0;
    for (int i = 0; i < digits.size(); i++) {
      final int digit = digits.get(digits.size() - (i + 1));
      if (digit == Numeral.UNKNOWN.value) {
        throw new IllegalStateException("The entry contains illegible digits");
      }
      checksum += (i + 1) * digit;
    }
    return checksum;
  }

  public List<Integer> getDigits() {
    final List<Integer> digits = new ArrayList<Integer>();
    for (final String[] character : getCharacters()) {
      digits.add(Numeral.decode(character).value);
    }
    return digits;
  }

  public List<String> getLines() {
    return Collections.unmodifiableList(lines);
  }

  public boolean isFull() {
    return lines.size() == 4;
  }

  public boolean isValid() {
    return (getChecksum() % 11) == 0;
  }

  public boolean hasIllegibleDigits() {
    return getDigits().contains(Numeral.UNKNOWN.value);
  }

  @Override
  public String toString() {
    if (isFull()) {
      final StringBuffer buff = new StringBuffer();
      for (final Integer digit : getDigits()) {
        buff.append(digit);
      }
      if (! isValid()) {
        buff.append(" ERR");
      }
      return buff.toString();
    } else {
      final StringBuffer buff = new StringBuffer("incomplete:");
      for (final String line : lines) {
        buff.append(System.getProperty("line.separator"));
        buff.append(line);
      }
      return buff.toString();
    }
  }

  private void validateLine(final String line) {
    if (line == null) {
      throw new IllegalArgumentException("The line parameter is required and"
          + " must not be null-valued.");
    }
    if (line.length() != 27) {
      throw new IllegalArgumentException("Each valid line contained in the"
          + " lines parameter must contain exactly 27 characters.");
    }
    if (! line.replaceAll("[|_ ]", "").equals("")) {
      throw new IllegalArgumentException("Each valid line contained in the"
          + " lines parameter may only contain underscore (\"_\")"
          + " characters, pipe (\"|\") characters, or spaces (\" \").");
    }
  }
}

@@ -1065,24 +1065,140 @@
 hecksum() %7B%0A
+    if (hasIllegibleDigits()) %7B%0A      throw new IllegalStateException(%22The entry contains illegible digits%22);%0A    %7D%0A
     final Li
@@ -1364,140 +1364,8 @@
 ));%0A
-      if (digit == Numeral.UNKNOWN.value) %7B%0A        throw new IllegalStateException(%22The entry contains illegible digits%22);%0A      %7D%0A
     

use hasIllegibleDigits in getChecksum