package org.ansj.util;

import java.io.IOException;
import java.io.Reader;

/**
 * 我又剽窃了下jdk...职业嫖客 为了效率这个流的操作是不支持多线程的,要么就是长时间不写这种东西了。发现好费劲啊 这个reader的特点。。只会输入
 * 句子不会输出\r\n .会有一个start来记录当前返回字符串。起始偏移量
 * 
 * @author ansj
 * 
 */
public class AnsjReader extends Reader {

	private Reader in;

	private char cb[];

	private static int defaultCharBufferSize = 8192;

	/**
	 * Creates a buffering character-input stream that uses an input buffer of
	 * the specified size.
	 * 
	 * @param in
	 *            A Reader
	 * @param sz
	 *            Input-buffer size
	 * 
	 * @exception IllegalArgumentException
	 *                If {@code sz <= 0}
	 */
	public AnsjReader(Reader in, int sz) {
		super(in);
		if (sz <= 0) {
			throw new IllegalArgumentException("Buffer size <= 0");
		}
		this.in = in;
		cb = new char[sz];
	}

	/**
	 * Creates a buffering character-input stream that uses a default-sized
	 * input buffer.
	 * 
	 * @param in
	 *            A Reader
	 */
	public AnsjReader(Reader in) {
		this(in, defaultCharBufferSize);
	}

	/** Checks to make sure that the stream has not been closed */
	private void ensureOpen() throws IOException {
		if (in == null) {
			throw new IOException("Stream closed");
		}
	}

	/**
	 * 为了功能的单一性我还是不实现了
	 */
	@Override
	public int read(char cbuf[], int off, int len) throws IOException {
		throw new IOException("AnsjBufferedReader not support this interface! ");
	}

	private int start = 0;
	private int tempStart = 0;

	/**
	 * 读取一行数据。ps 读取结果会忽略 \n \r
	 */
	public String readLine() throws IOException {

		ensureOpen();

		StringBuilder sb = null;

		start = tempStart;

		firstRead = true;

		while (true) {

			tempLen = 0;
			ok = false;

			readString();
			// if (tempLen != 0)
			// System.out.println(new String(cb, tempOffe, tempLen));

			if (!isRead && (tempLen == 0 || len == 0)) {
				if (sb != null) {
					return sb.toString();
				}
				return null;
			}

			if (!isRead) { // 如果不是需要读状态，那么返回
				tempStart += tempLen;
				if (sb == null) {
					return new String(cb, tempOffe, tempLen);
				} else {
					sb.append(cb, tempOffe, tempLen);
					return sb.toString();
				}
			}

			if (tempLen == 0) {
				continue;
			}

			// 如果是需要读状态那么读取
			if (sb == null) {
				sb = new StringBuilder();
			}
			sb.append(cb, tempOffe, tempLen);
			tempStart += tempLen;
		}

	}

	int offe = 0;
	int len = 0;

	boolean isRead = false;
	boolean ok = false;
	boolean firstRead = true;

	int tempOffe;
	int tempLen;

	private void readString() throws IOException {

		if (offe <= 0) {
			if (offe == -1) {
				isRead = false;
				return;
			}

			len = in.read(cb);
			if (len <= 0) { // 说明到结尾了
				isRead = false;
				return;
			}
		}

		isRead = true;

		char c = 0;
		int i = offe;
		for (; i < len; i++) {
			c = cb[i];
			if (c != '\r' && c != '\n') {
				break;
			}
			if (!firstRead) {
				i++;
				tempStart++;
				offe = i;
				tempOffe = offe;
				isRead = false;
				return;
			}
			tempStart++;
			start++;
		}

		if (i == len) {
			isRead = true;
			offe = 0;
			return;
		}

		firstRead = false;

		offe = i;

		for (; i < len; i++) {
			c = cb[i];
			if (c == '\n' || c == '\r') {
				isRead = false;
				break;
			}
		}

		tempOffe = offe;
		tempLen = i - offe;

		if (i == len) {
			if (len < cb.length) { // 说明到结尾了
				isRead = false;
				offe = -1;
			} else {
				offe = 0;
			}
		} else {
			offe = i;
		}

	}

	@Override
	public void close() throws IOException {
		synchronized (lock) {
			if (in == null) {
				return;
			}
			try {
				in.close();
			} finally {
				in = null;
				cb = null;
			}
		}
	}

	public int getStart() {
		return this.start;
	}

}
