using Godot;
using System.Collections.Generic;
using System.Text;

namespace Rokojori
{  
  public partial class BitView
  {
    public static int numBitsForIntVL8( int value )
    {
      return numBytesForUIntVL8( value ) * 8;
    }

    public static int numBytesForUIntVL8( int value )
    {
      var numBits  = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) );
      var numBytes = ( numBits - 1 )/ 7 + 1;

      return numBytes;
    }

    

    public void WriteUIntVL8( int value )
    {
      if ( value < 0 )
      {
        throw new System.Exception( "Value is negative, writing only positive value:" + value );
      }

      var numBits  = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) );
      var numBytes = ( numBits - 1 )/ 7 + 1;
      var position = 0;

      RJLog.Log( "WriteIntVL8", value, "bits:", numBits," >> bytes:", numBytes );

      for ( int b = 0; b < numBytes; b++ )
      {        
        for ( int i = 0; i < 7; i++ )
        {
          WriteBit( BitMath.IsBitSet( value, position ) );
          position++;
        }

        WriteBit( b != ( numBytes - 1 ) );        
      }
    }

    public int ReadUIntVL8()
    {
      var byteValue = ReadByte();
      var intValue  = byteValue & 127; 
      var numShifts = 1;

      while ( byteValue > 127 )
      {
        byteValue = ReadByte();
        var nextIntValue = ( byteValue & 127 ) << ( 7 * numShifts );
        numShifts ++; 
        intValue = intValue | nextIntValue;
      } 

      RJLog.Log( "ReadIntVL8 >> ", intValue );

      return intValue;
    }

    public void WriteIntVL8( int value )
    {
      var isNegative = value < 0;
      var absValue = Mathf.Abs( value );

      WriteBit( isNegative );
      WriteUIntVL8( absValue );
    }

    public int ReadIntVL8()
    {
      var isNegative = ReadBit();
      var absValue = ReadUIntVL8();

      return isNegative ? ( -absValue ) : absValue; 
    }
  }
}