<?php

namespace LowEntryUE4PHP\Classes\Internal;

use LowEntryUE4PHP\LowEntry;


class CompressionByteArrayBuffer
{
	/** @var int[] Byte array */
	public $buffer;
	
	/** @var int */
	public $length = 0;
	
	
	/**
	 * @param null|int $initialSize
	 * @param null|int $maxInitialSize
	 */
	public function __construct($initialSize = null, $maxInitialSize = null)
	{
		if(isset($initialSize))
		{
			if(isset($maxInitialSize))
			{
				$initialSize = ($initialSize <= $maxInitialSize) ? $initialSize : $maxInitialSize;
				$this->buffer = LowEntry::createArray((($initialSize > 0) ? $initialSize : 32), 0);
			}
			else
			{
				$this->buffer = LowEntry::createArray((($initialSize > 0) ? $initialSize : 32), 0);
			}
		}
		else
		{
			$this->buffer = LowEntry::createArray(32, 0);
		}
	}
	
	
	/**
	 * @param int $index
	 */
	public function access($index)
	{
		if($index >= \count($this->buffer))
		{
			$newSize = \count($this->buffer);
			while($index >= $newSize)
			{
				$newSize = ($newSize >= 1073741823) ? 2147483647 : $newSize * 2;
			}
			$this->buffer = LowEntry::arraysCopyOf($this->buffer, $newSize, 0);
		}
		if(($index + 1) > $this->length)
		{
			$this->length = $index + 1;
		}
	}
	
	
	/**
	 * @param int       $index
	 * @param int|int[] $value        Byte or Byte array
	 * @param null|int  $valuesOffset Used when $value is a Byte array
	 * @param null|int  $length       Used when $value is a Byte array
	 */
	public function set($index, $value, $valuesOffset = null, $length = null)
	{
		if(isset($valuesOffset) && isset($length) && is_array($value))
		{
			$this->access($index + ($length - 1));
			LowEntry::systemArrayCopy($value, $valuesOffset, $this->buffer, $index, $length);
		}
		else
		{
			$this->access($index);
			$this->buffer[$index] = $value;
		}
	}
	
	
	/**
	 * @param int $index
	 *
	 * @return int Byte
	 */
	public function get($index)
	{
		if($index >= \count($this->buffer))
		{
			return 0;
		}
		return $this->buffer[$index];
	}
	
	
	/**
	 * @param null|int $length
	 *
	 * @return int[] Byte array
	 */
	public function getData($length = null)
	{
		if(isset($length))
		{
			return LowEntry::arraysCopyOf($this->buffer, $length, 0);
		}
		else
		{
			return LowEntry::arraysCopyOf($this->buffer, $this->length, 0);
		}
	}
}
