/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package java.io;

import intrinsic.flash.utils.ByteArray;

public class InputStreamReader extends Reader {
	
	private InputStream in;
	private String encoding;
	private int pos, count;
	private byte[] buffer = new byte[BUFFER_SIZE];
	
	private static int BUFFER_SIZE = 4096;
	
public InputStreamReader(InputStream in) {
	if (in == null) throw new NullPointerException();
	this.in = in;
	this.encoding = System.getProperty("file.encoding");
}

public InputStreamReader(InputStream in, String encoding) {
	if (in == null) throw new NullPointerException();
	this.in = in;
	this.encoding = encoding;
}

public void close() throws IOException {
	in.close();
}

native ByteArray getArray()/*{
	return buffer.array as ByteArray;
}*/;

private int convert(char[] cbuf, int off, int len, String encoding) {
	if (count == 0) return 0;
	ByteArray array = getArray();
	array.position = pos;
	int toRead = len * 6;
	if (toRead > count) toRead = count;
	String str = array.readMultiByte(toRead, encoding);
	array.position = pos;
	int read = str.length() < len ? str.length() : len;
	if (str.length() > 0) {
		for (int i=0; i<read; i++) {
			cbuf[off++] = str.charAt(i);
		}
		array.writeMultiByte(str.substring(0, read), encoding);
		count -= array.position - pos;
		pos = array.position;
	}
	return read;
}

private int fill(int length) throws IOException {
	if (count > 0) System.arraycopy(buffer, pos, buffer, 0, count);
	pos = 0;
	int read = in.read(buffer, count, Math.min(length, buffer.length - count));
	if (read < 0) {
		if (count > 0) throw new IOException();
	} else {
		count += read;
	}
	return read;
}

public void mark(int readAheadLimit) throws IOException {
	in.mark(readAheadLimit);
}

public int read() throws IOException {
	char[] result = new char[1];
	int read = read(result);
	if (read < 0) return -1;
	return result[0];
}

public int read(char[] cbuf, int off, int len) throws IOException {
	if (off < 0 || len < 0 || off >= cbuf.length || off + len > cbuf.length) {
		throw new IndexOutOfBoundsException();
	}
	int read = 0;
	while (read < len) {
		int converted = convert(cbuf, off, len - read, encoding);
		if (converted == 0) {
			if (fill((len - read) * 6) < 0) {
				if (read == 0) return -1;
				break;
			}
		} else {
			off += converted;
			read += converted;
		}
	}
	return read;
}

public boolean ready() throws IOException {
	return count > 0 || in.available() > 0;
}

public void reset() throws IOException {
	in.reset();
}

public long skip(long n) throws IOException {
	return super.skip(n);
}
}