/*
 * Copyright 2013 Yuichiro Moriguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.morilib.unix.misc;

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

/**
 *
 *
 * @author MORIGUCHI, Yuichiro 2013/06/15
 */
public class TrReader extends Reader {

	//
	private Reader  in;
	private String  source, dest, squeeze;
	private boolean complement, truncate;
	private int pback = -1;

	/**
	 * 
	 * @param in
	 */
	public TrReader(Reader in, String source, String dest,
			String squeeze, boolean complement, boolean truncate) {
		this.in = in;
		this.source = source;
		this.dest   = dest;
		this.squeeze    = squeeze;
		this.complement = complement;
		this.truncate   = truncate;
	}

	private int _read() throws IOException {
		int c;

		if(pback >= 0) {
			c = pback;  pback = -1;
		} else if((c = in.read()) < 0) {
			return -1;
		} else if(source == null) {
			return c;
		} else if(dest != null) {
			c = Tr.tr(source, dest, c, complement, truncate);
		} else {
			while(Tr.indexOf(source, c, complement) >= 0 &&
					(c = in.read()) >= 0);
		}
		return c;
	}

	/* (non-Javadoc)
	 * @see java.io.FilterReader#read()
	 */
	@Override
	public int read() throws IOException {
		int c, d;

		c = _read();
		if(squeeze != null) {
			while((d = _read()) >= 0 && c == d &&
					Tr.indexOf(squeeze, d, complement) >= 0);
			pback = d;
		}
		return c;
	}

	/* (non-Javadoc)
	 * @see java.io.FilterReader#read(char[], int, int)
	 */
	@Override
	public int read(char[] cbuf, int off, int len) throws IOException {
		int c;

		for(int i = 0; i < len; i++) {
			if((c = read()) < 0)  return i > 0 ? i : -1;
			cbuf[i + off] = (char)c;
		}
		return len;
	}

	/* (non-Javadoc)
	 * @see java.io.Reader#close()
	 */
	@Override
	public void close() throws IOException {
		in.close();
	}

}
