package scanner;

import java.io.InputStream;
import java.io.FilterInputStream;
import java.io.IOException;

/**
 * Replaces Lisp comments with newlines in an input stream.
 */
public class LispFilterStream extends FilterInputStream {

    private boolean inQuote;
    private int nextCharacter;

    public LispFilterStream(InputStream in) {
        super(in);
        inQuote = false;
        nextCharacter = 0;
    }

    @Override
    public int read() throws IOException {
        nextCharacter = super.read();

        if (haveEnteredComment()) {
            consumeAllBytesInComment();
        } else if (haveEncounteredStringBoundary()) {
            inQuote = (!inQuote);
        }

        return nextCharacter;
    }

    private void consumeAllBytesInComment() throws IOException {
        while (stillInComment()) {
            nextCharacter = super.read();
        }
    }

    private boolean stillInComment() {
        return (nextCharacter != '\n') && (nextCharacter != -1);
    }

    private boolean haveEnteredComment() {
        return (nextCharacter == ';') && (!inQuote);
    }

    private boolean haveEncounteredStringBoundary() {
        return nextCharacter == '\"';
    }

}