VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "TileSubset"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False

'A class that store a subset of the tiles in the map
'The order of the list is not preserved

Option Explicit

'TileIndex refer to the index in TileCollection and TileCollection refer to the coordinates in TileIndex
Dim TileIndex(0 To MapSizeX - 1, 0 To MapSizeZ - 1) As Long
Dim TileCollection() As TileVector

'The number of used elements in TileCollection
Dim NumberOfUsedTiles As Long

Private Sub Class_Initialize()
    ReDim TileCollection(0 To 255)
    Reset
End Sub

Public Sub Reset()
    Static X As Long
    Static Z As Long
    For X = 0 To MapSizeX - 1
        For Z = 0 To MapSizeZ - 1
            TileIndex(X, Z) = -1
        Next Z
    Next X
    NumberOfUsedTiles = 0
End Sub

Public Sub IncludeTile(X As Long, Z As Long)
    Static NewIndex As Long
    If TileIndex(X, Z) = -1 Then
        
        'Insert the tile in the end of the collection
        NewIndex = NumberOfUsedTiles
        NumberOfUsedTiles = NumberOfUsedTiles + 1
        If NumberOfUsedTiles > UBound(TileCollection()) Then
            'Reallocate the collection when running out of space
            ReDim Preserve TileCollection(0 To UBound(TileCollection()) * 2)
        End If
        TileCollection(NewIndex).X = X
        TileCollection(NewIndex).Z = Z
        TileIndex(X, Z) = NewIndex
    End If
End Sub

Public Sub ExcludeTile(X As Long, Z As Long)
    Static LastIndex As Long
    Static OldIndex As Long
    Static LastPos As TileVector
    If TileIndex(X, Z) > -1 Then
        Debug.Assert NumberOfUsedTiles > 0
        
        'Remove the tile in the collection by changing place with the last element
        NumberOfUsedTiles = NumberOfUsedTiles - 1
        LastIndex = NumberOfUsedTiles
        OldIndex = TileIndex(X, Z)
        If OldIndex < LastIndex Then
            LastPos = TileCollection(LastIndex)
            TileCollection(OldIndex) = TileCollection(LastIndex)
            TileIndex(LastPos.X, LastPos.Z) = OldIndex
        End If
        TileIndex(X, Z) = -1
    End If
End Sub

Public Function DoesTileExist(X As Long, Z As Long) As Boolean
    DoesTileExist = (TileIndex(X, Z) > -1)
End Function

Public Function GetNumberOfUsedTiles() As Long
    GetNumberOfUsedTiles = NumberOfUsedTiles
End Function

Public Function GetXUsingIndex(Index As Long) As Long
    Debug.Assert Index >= 0 And Index < NumberOfUsedTiles
    GetXUsingIndex = TileCollection(Index).X
End Function

Public Function GetZUsingIndex(Index As Long) As Long
    Debug.Assert Index >= 0 And Index < NumberOfUsedTiles
    GetZUsingIndex = TileCollection(Index).Z
End Function
