package edu.uprm.walsaip.vte.core.util.file;

import static java.nio.ByteOrder.LITTLE_ENDIAN;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class FileChannelReaderUtil implements FileReaderUtil {
	ByteBuffer byteBuffer = null;
	ByteBuffer shortBuffer = null;
	
	ByteBuffer intBuffer = null;
	
	ByteBuffer floatBuffer = null;
	
	ByteBuffer doubleBuffer = null;
	FileChannel channel = null;
	FileInputStream stream = null;
	
	public FileChannelReaderUtil(FileInputStream stream,FileChannel channel) {
		this.stream = stream;
		this.channel = channel;
		byteBuffer = ByteBuffer.allocate(1);
		byteBuffer.order(LITTLE_ENDIAN);
		shortBuffer = ByteBuffer.allocate(2);
		shortBuffer.order(LITTLE_ENDIAN);
		intBuffer = ByteBuffer.allocate(4);
		intBuffer.order(LITTLE_ENDIAN);
		floatBuffer = ByteBuffer.allocate(4);
		floatBuffer.order(LITTLE_ENDIAN);
		doubleBuffer = ByteBuffer.allocate(8);
		doubleBuffer.order(LITTLE_ENDIAN);
		
	}
	
	
	@Override
	public byte readByte() throws IOException {
		byteBuffer.rewind();
		channel.read(byteBuffer);
		byteBuffer.rewind();
		return byteBuffer.get();
	}

	@Override
	public byte readByte(int position) throws IOException {
		channel.position(position);
		return readByte();
	}

	@Override
	public double readDouble() throws IOException {
		doubleBuffer.rewind();
		channel.read(doubleBuffer);
		doubleBuffer.rewind();
		return doubleBuffer.getDouble();
	}

	@Override
	public double readDouble(int position) throws IOException {
		channel.position(position);
		return readDouble();
	}

	@Override
	public float readFloat(int position) throws IOException {
		channel.position(position);
		return readFloat();
	}

	@Override
	public float readFloat() throws IOException {
		floatBuffer.rewind();
		channel.read(floatBuffer);
		floatBuffer.rewind();
		return floatBuffer.getFloat();
	}

	@Override
	public int readInt(int position) throws IOException {
		channel.position(position);
		return readInt();
	}

	@Override
	public int readInt() throws IOException {
		intBuffer.rewind();
		channel.read(intBuffer);
		intBuffer.rewind();
		return intBuffer.getInt();
	}

	@Override
	public short readShort() throws IOException {
		shortBuffer.rewind();
		channel.read(shortBuffer);
		shortBuffer.rewind();
		return shortBuffer.getShort();
	}

	@Override
	public short readShort(int position) throws IOException {
		channel.position(position);
		return readShort();
	}

	@Override
	public void position(int position) throws IOException {
		channel.position(position);
		
	}


	@Override
	public void close() throws IOException {
		channel.close();
		stream.close();
	}


	@Override
	public long position() throws IOException {
		
		return channel.position();
	}


	@Override
	public long remaining() throws IOException {
		
		return channel.size() - channel.position();
	}
}
