package rcs.utils;


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

import rcs.utils.CorrectedPipedOutputStream;



/*
 *
 * CorrectedPipedInputStream
 *
 */
public class CorrectedPipedInputStream extends InputStream
{
	CorrectedPipedOutputStream out_stream = null;
	CorrectedPipeData pipe_data = null;
	static final public boolean debug_on = true;
  
        // Constructors
    public CorrectedPipedInputStream()
	{
		out_stream = null;
		pipe_data = new  CorrectedPipeData();
	}

	public CorrectedPipedInputStream(CorrectedPipedOutputStream out)
	{
		out_stream = out;
		pipe_data = out_stream.pipe_data;
		out_stream.in_stream = this;
	}
        // Methods
    public int available()
	{
		if(null == pipe_data)
		{
			return 0;
		}
		if(null == pipe_data.buffer)
		{
			return 0;
		}
		if( pipe_data.length > pipe_data.buffer.length)
		{
			return 0;
		}
		if(pipe_data.offset < pipe_data.length)
		{
			return 0;
		}
		return pipe_data.length - pipe_data.offset;

	}

    public void close()
	{
	}

    public int read()	throws IOException
	{
		if(null == pipe_data)
		{
			throw new IOException();
		}
		while(true)
		{
			if(null != pipe_data.buffer)
			{
				if(pipe_data.buffer.length > 0 && 
					pipe_data.offset < pipe_data.length)
				{
					break;
				}
			}
			try
			{
				pipe_data.wait();
			}
			catch(Exception e)
			{
				e.printStackTrace();
				throw new IOException();
			}
		}
		if(pipe_data.offset < 0)
		{
			throw new IOException();
		}
		if(pipe_data.offset > pipe_data.length)
		{
			throw new IOException();
		}
		if(pipe_data.length > pipe_data.buffer.length)
		{
			throw new IOException();
		}
		int retval = 0;
		synchronized(pipe_data)
		{
			retval = (int)  pipe_data.buffer[pipe_data.offset];
			if(retval < 0)
			{
				retval += 256;
			}
			pipe_data.offset++;
			pipe_data.notifyAll();
		}
		if(debug_on)
		{
				System.out.println("CorrectedPipedInputStream.read() returning "+retval+". (off = "+pipe_data.offset+", len = "+pipe_data.length+")");
		}
		return retval;
	}

    public int read(byte  b[]) throws IOException
	{
		return read(b,0,b.length);
	}

    public int read(byte  b[], int  off, int  len)	throws IOException
	{
		int bytes_read = 0;
		if(debug_on)
		{
			System.out.println("CorrectedPipedInputStream: pipe_data.buffer = "+new String(pipe_data.buffer,0,off,len) +", pipe_data.offset  = "+pipe_data.offset+", pipe_data.length = "+pipe_data.length);
		}
		if(null == pipe_data)
		{
			throw new IOException();
		}
		while(true)
		{
			if(null != pipe_data.buffer)
			{
				if(pipe_data.buffer.length > 0 && 
					pipe_data.offset < pipe_data.length)
				{
					break;
				}
			}
			try
			{
				pipe_data.wait();
			}
			catch(Exception e)
			{
				e.printStackTrace();
				throw new IOException();
			}
		}
		if(pipe_data.offset < 0)
		{
			throw new IOException();
		}
		if(pipe_data.offset > pipe_data.length)
		{
			throw new IOException();
		}
		if(pipe_data.length > pipe_data.buffer.length)
		{
			throw new IOException();
		}
		synchronized(pipe_data)
		{
			while(bytes_read < len && pipe_data.offset < pipe_data.length)
			{
				b[bytes_read+off] =  pipe_data.buffer[pipe_data.offset];
				pipe_data.offset++;
				bytes_read++;
			}
			pipe_data.notifyAll();
		}
		if(debug_on)
		{
			System.out.println("CorrectedPipedInputStream: b = "+new String(b,0,off,len) +", off  = "+off+", len = "+len+", bytes_read = "+bytes_read);
		}

		return bytes_read;
	}
}