using System.IO;

namespace ComponentAce.Compression.Libs.zlib;

public class ZInputStream : BinaryReader
{
	protected ZStream z = new ZStream();

	protected int bufsize = 512;

	protected int flush;

	protected byte[] buf;

	protected byte[] buf1 = new byte[1];

	protected bool compress;

	internal Stream in_Renamed;

	internal bool nomoreinput;

	public virtual int FlushMode
	{
		get
		{
			return flush;
		}
		set
		{
			flush = value;
		}
	}

	public virtual long TotalIn => z.total_in;

	public virtual long TotalOut => z.total_out;

	internal void InitBlock()
	{
		flush = 0;
		buf = new byte[bufsize];
	}

	public ZInputStream(Stream in_Renamed)
		: base(in_Renamed)
	{
		InitBlock();
		this.in_Renamed = in_Renamed;
		z.inflateInit();
		compress = false;
		z.next_in = buf;
		z.next_in_index = 0;
		z.avail_in = 0;
	}

	public ZInputStream(Stream in_Renamed, int level)
		: base(in_Renamed)
	{
		InitBlock();
		this.in_Renamed = in_Renamed;
		z.deflateInit(level);
		compress = true;
		z.next_in = buf;
		z.next_in_index = 0;
		z.avail_in = 0;
	}

	public override int Read()
	{
		if (read(buf1, 0, 1) == -1)
		{
			return -1;
		}
		return buf1[0] & 0xFF;
	}

	public int read(byte[] b, int off, int len)
	{
		if (len == 0)
		{
			return 0;
		}
		z.next_out = b;
		z.next_out_index = off;
		z.avail_out = len;
		int num;
		do
		{
			if (z.avail_in == 0 && !nomoreinput)
			{
				z.next_in_index = 0;
				z.avail_in = SupportClass.ReadInput(in_Renamed, buf, 0, bufsize);
				if (z.avail_in == -1)
				{
					z.avail_in = 0;
					nomoreinput = true;
				}
			}
			num = ((!compress) ? z.inflate(flush) : z.deflate(flush));
			if (nomoreinput && num == -5)
			{
				return -1;
			}
			if (num != 0 && num != 1)
			{
				throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg);
			}
			if (nomoreinput && z.avail_out == len)
			{
				return -1;
			}
		}
		while (z.avail_out == len && num == 0);
		return len - z.avail_out;
	}

	public long skip(long n)
	{
		int num = 512;
		if (n < num)
		{
			num = (int)n;
		}
		byte[] array = new byte[num];
		return SupportClass.ReadInput(BaseStream, array, 0, array.Length);
	}

	public override void Close()
	{
		in_Renamed.Close();
	}
}