#### Bzip2 Implementation
#### Copyright (C) 2023-2024 Remilia Scarlet
#### Copyright (C) 2015 Jaime Olivares
#### Copyright (c) 2011 Matthew Francis
#### MIT License
####
#### Ported from the Java implementation by Matthew Francis:
#### https://github.com/MateuszBartosiewicz/bzip2.
####
#### Ported by Remilia Scarlet from the C# implementation by Jamie Olivares:
#### http://github.com/jaime-olivares/bzip2

module RemiLib::Compression::BZip2
  # A 256 entry Move-to-Front transformer.
  private class MoveToFront
    @mtf : Array(UInt8)

    # Creates a new `MoveToFront` instance.
    def initialize
      @mtf = Array(UInt8).new(256, &.to_u8!)
    end

    # Moves `value` to the head of the MTF list (forward Move To Front
    # transform).  Returns the position the value moved from.
    @[AlwaysInline]
    def valueToFront(value : UInt8) : Int32
      index : Int32 = 0
      tmp : UInt8 = @mtf.unsafe_fetch(0)
      tmp2 : UInt8 = 0

      unless value == tmp
        @mtf.unsafe_put(0, value)
        while value != tmp
          index += 1
          tmp2 = tmp
          tmp = @mtf.unsafe_fetch(index)
          @mtf.unsafe_put(index, tmp2)
        end
      end

      index
    end

    # Gets the value at `index` and moves it to the front of the MTF list
    # (inverse Move To Front transform).  This returns the value at the given
    # `index`.
    @[AlwaysInline]
    def indexToFront(index : Int32) : UInt8
      ret = @mtf[index]
      @mtf[1, index] = @mtf[0, index]
      @mtf.unsafe_put(0, ret)
      ret
    end
  end
end
