Private Sub PicGame_MouseDown(sender As Object, e As MouseEventArgs) Handles picGame.MouseDown
        If SelectionMode Then
            HandleSelectionMode(e)
            Return
        End If

        If e.Button = MouseButtons.Left Then
            ' Handle actions when the left mouse button is clicked
            HandleGateClicked(e.X, e.Y)
            HandleBaddyClicked(e.X, e.Y) ' Ensure this line is added

            ' Start the selection process
            isSelecting = True
            selectionStartPoint = e.Location
            selectionEndPoint = e.Location
            selectionRectangle = GetRectangle(selectionStartPoint, selectionEndPoint)

            ' Reset selection data only if not in copy-paste operation
            If Not isCopying Then
                selectionData = Nothing
                selectionStartCell = New Point(-1, -1)
                copiedSelectionData = Nothing
                copiedSelectionType = ""
            End If

            ' Check if selection starts from a wall or the space between walls
            Dim offsetX As Integer = (selectionStartPoint.X - INDENT) Mod (SQSizeX + WALL_THICKNESS)
            Dim offsetY As Integer = (selectionStartPoint.Y - INDENT) Mod (SQSizeY + WALL_THICKNESS)
            selectionStartedOnWall = (offsetX < WALL_THICKNESS) OrElse (offsetY < WALL_THICKNESS)

            ' Adjust the selection start point to snap to the grid
            selectionStartPoint = GetGridAlignedPoint(selectionStartPoint)

            ' Determine if the user starts the selection on a floor or a wall
            Dim clickedX As Integer = (e.X - INDENT) \ (SQSizeX + WALL_THICKNESS)
            Dim clickedY As Integer = (e.Y - INDENT) \ (SQSizeY + WALL_THICKNESS)

            If clickedX >= 0 AndAlso clickedX < SQCOUNTX AndAlso clickedY >= 0 AndAlso clickedY < SQCOUNTY Then
                If Not IsMouseOverWall(e.X, e.Y) Then
                    ' The starting selection is on the floor
                    SnapToFloor = True
                Else
                    ' Starting on a wall
                    SnapToFloor = False
                End If
            End If
        ElseIf e.Button = MouseButtons.Right Then
            ' Hide properties displays
            UcBaddyProps.Visible = False
            krKeys.Visible = False
        End If

        If isSelectionReadyToDrag Then
            If selectionRectangle.Contains(e.Location) Then
                If e.Button = MouseButtons.Left Then
                    SaveStateForUndo()
                    isDraggingSelection = True
                    selectionOffset = New Point(e.X - selectionRectangle.Location.X, e.Y - selectionRectangle.Location.Y)
                    selectionStartCell = New Point(
            (selectionRectangle.Location.X - INDENT) \ (SQSizeX + WALL_THICKNESS),
            (selectionRectangle.Location.Y - INDENT) \ (SQSizeY + WALL_THICKNESS))
                    picGame.Capture = True
                    Cursor = Cursors.SizeAll
                ElseIf e.Button = MouseButtons.Right Then
                    ' Show context menu if right-clicking inside the selection
                    Dim menuPosition As Point = e.Location
                    ctmMenu.Show(picGame, menuPosition)
                End If
            End If
        ElseIf isInSelectionMode Then
            ' Start selecting a new area
            If e.Button = MouseButtons.Left Then
                isSelecting = True
                selectionStartPoint = e.Location
                selectionEndPoint = e.Location
                selectionRectangle = GetRectangle(selectionStartPoint, selectionEndPoint)

                ' Reset selection data only if not in copy-paste operation
                If Not isCopying Then
                    selectionData = Nothing
                    selectionStartCell = New Point(-1, -1)
                    copiedSelectionData = Nothing
                    copiedSelectionType = ""
                End If

                ' Reset the cycle
                isSelectionExpandedToWalls = False
                isSelectionExpandedToFloors = False

                ' Adjust the selection start point to snap to the grid
                selectionStartPoint = GetGridAlignedPoint(selectionStartPoint)
            ElseIf e.Button = MouseButtons.Right Then
                If selectionRectangle.Contains(e.Location) Then
                    Dim menuPosition As Point = e.Location
                    ctmMenu.Show(picGame, menuPosition)
                End If
            Else
                TurnOffSelectionMode()
            End If
        Else
            ' Normal mouse down processing
            If e.Button = MouseButtons.Right Then
                isRightMouseDown = True
                rightMouseDownPosition = e.Location
                rightMouseDownTime = Date.Now
                If Not isActionInProgress Then
                    isActionInProgress = True
                    SaveStateForUndo()
                End If
            ElseIf e.Button = MouseButtons.Left Then
                isLeftMouseDown = True
                UpdateHighlight(e.X, e.Y)
                Dim itemPickedUp As Boolean = False

                If isMouseInsideGrid Then
                    If Not isActionInProgress Then
                        isActionInProgress = True
                        SaveStateForUndo()
                    End If

                    If highlightedWallX Then
                        ' Handle vertical wall item pickup
                        If highlightedX >= 0 AndAlso highlightedX < verticalWallItems.Length AndAlso
           highlightedY >= 0 AndAlso highlightedY < verticalWallItems(0).Length Then
                            If verticalWallItems(highlightedX)(highlightedY) IsNot Nothing Then
                                isDraggingItem = True
                                draggedItem = verticalWallItems(highlightedX)(highlightedY)
                                draggedItemIsWall = True
                                draggedItemIsVerticalWall = True
                                draggedItemIsVerticalWall = True
                                draggedItemOriginalX = highlightedX
                                draggedItemOriginalY = highlightedY
                                verticalWallItems(highlightedX)(highlightedY) = Nothing
                                verticalWalls(highlightedX)(highlightedY) = True
                                picGame.Capture = True
                                itemPickedUp = True
                            End If
                        End If
                    ElseIf highlightedWallY Then
                        ' Handle horizontal wall item pickup
                        If highlightedX >= 0 AndAlso highlightedX < horizontalWallItems.Length AndAlso
           highlightedY >= 0 AndAlso highlightedY < horizontalWallItems(0).Length Then
                            If horizontalWallItems(highlightedX)(highlightedY) IsNot Nothing Then
                                isDraggingItem = True
                                draggedItem = horizontalWallItems(highlightedX)(highlightedY)
                                draggedItemIsWall = True
                                draggedItemIsVerticalWall = False
                                draggedItemOriginalX = highlightedX
                                draggedItemOriginalY = highlightedY
                                horizontalWallItems(highlightedX)(highlightedY) = Nothing
                                horizontalWalls(highlightedX)(highlightedY) = True
                                picGame.Capture = True
                                itemPickedUp = True
                            End If
                        End If
                    Else
                        ' Handle floor item pickup
                        If highlightedX >= 0 AndAlso highlightedX < placedItems.Length AndAlso
           highlightedY >= 0 AndAlso highlightedY < placedItems(0).Length Then
                            If placedItems(highlightedX)(highlightedY) IsNot Nothing Then
                                isDraggingItem = True
                                draggedItem = placedItems(highlightedX)(highlightedY)
                                draggedItemIsWall = False
                                draggedItemOriginalX = highlightedX
                                draggedItemOriginalY = highlightedY
                                placedItems(highlightedX)(highlightedY) = Nothing
                                picGame.Capture = True
                                itemPickedUp = True
                            End If
                        End If
                    End If

                    If itemPickedUp Then
                        redoStack.Clear()
                    Else
                        ' Add wall or edge style handling
                        If rdoEdge.Checked Then
                            isLeftMouseDown = True
                            SetEdgeStyleAtMousePosition(e.X, e.Y)
                        Else
                            isLeftMouseDown = True
                            AddWallAtMousePosition(e.X, e.Y)
                        End If
                    End If
                End If
            End If
        End If

        ' Check if the krKeys control is visible and the click is outside the cell with the gate
        If krKeys.Visible And IsOnGate = False Then
            Dim clickedX As Integer = (e.X - INDENT) \ (SQSizeX + WALL_THICKNESS)
            Dim clickedY As Integer = (e.Y - INDENT) \ (SQSizeY + WALL_THICKNESS)

            If clickedX >= 0 AndAlso clickedX < placedItems.Length AndAlso
   clickedY >= 0 AndAlso clickedY < placedItems(0).Length Then
                Dim clickedItem As ItemInfo = placedItems(clickedX)(clickedY)
                If clickedItem Is Nothing OrElse clickedItem.ImageKey <> "picGate" Then
                    krKeys.Visible = False
                End If
            Else
                krKeys.Visible = False
            End If
        End If

        ' Check if the UcBaddyProps control is visible and the click is outside the cell with the Baddy
        If UcBaddyProps.Visible AndAlso Not IsOnBaddy Then
            Dim clickedX As Integer = (e.X - INDENT) \ (SQSizeX + WALL_THICKNESS)
            Dim clickedY As Integer = (e.Y - INDENT) \ (SQSizeY + WALL_THICKNESS)

            If clickedX >= 0 AndAlso clickedX < placedItems.Length AndAlso
   clickedY >= 0 AndAlso clickedY < placedItems(0).Length Then
                Dim clickedItem As ItemInfo = placedItems(clickedX)(clickedY)
                If Not clickedItem.ImageKey.StartsWith("picBaddy") Then
                    UcBaddyProps.Visible = False
                End If
            Else
                UcBaddyProps.Visible = False
            End If
        End If
    End Sub
    Private Sub PicGame_MouseMove(sender As Object, e As MouseEventArgs) Handles picGame.MouseMove
        isCursorOnPicGame = True

        If isDraggingSelection Then
            ' Existing code for dragging selection
            If isCopying Then
                If copiedSelectionData Is Nothing Then
                    Return
                End If
            Else
                If selectionData Is Nothing Then
                    CaptureSelectionData()
                End If
            End If

            ' Calculate new cell positions
            Dim newX As Integer = e.X - selectionOffset.X
            Dim newY As Integer = e.Y - selectionOffset.Y

            Dim cellX As Integer = (newX - INDENT) \ (SQSizeX + WALL_THICKNESS)
            Dim cellY As Integer = (newY - INDENT) \ (SQSizeY + WALL_THICKNESS)

            ' Ensure cellX and cellY are within bounds
            If isCopying Then
                cellX = Math.Max(0, Math.Min(SQCOUNTX - copiedSelectionData.selectionWidth, cellX))
                cellY = Math.Max(0, Math.Min(SQCOUNTY - copiedSelectionData.selectionHeight, cellY))
                selectionRectangle.Width = (copiedSelectionData.selectionWidth * (SQSizeX + WALL_THICKNESS)) - WALL_THICKNESS
                selectionRectangle.Height = (copiedSelectionData.selectionHeight * (SQSizeY + WALL_THICKNESS)) - WALL_THICKNESS
            Else
                cellX = Math.Max(0, Math.Min(SQCOUNTX - selectionData.selectionWidth, cellX))
                cellY = Math.Max(0, Math.Min(SQCOUNTY - selectionData.selectionHeight, cellY))
                selectionRectangle.Width = (selectionData.selectionWidth * (SQSizeX + WALL_THICKNESS)) - WALL_THICKNESS
                selectionRectangle.Height = (selectionData.selectionHeight * (SQSizeY + WALL_THICKNESS)) - WALL_THICKNESS
            End If

            ' Update selection rectangle position
            selectionRectangle.X = INDENT + (cellX * (SQSizeX + WALL_THICKNESS))
            selectionRectangle.Y = INDENT + (cellY * (SQSizeY + WALL_THICKNESS))

            ' Store cell positions for use in MouseUp
            draggedSelectionCellX = cellX
            draggedSelectionCellY = cellY

        ElseIf isDraggingItem Then
            ' Update the mouse position to the current cursor position
            mouseX = e.X
            mouseY = e.Y

            ' Snap the item to the nearest wall and center it
            UpdateHighlight(e.X, e.Y)
            If draggedItemIsWall Then
                If draggedItemIsVerticalWall Then
                    mouseX = INDENT + (highlightedX * (SQSizeX + WALL_THICKNESS)) - (WALL_THICKNESS \ 2) + 4
                    mouseY = INDENT + (highlightedY * (SQSizeY + WALL_THICKNESS)) + (WALL_THICKNESS \ 2) + (SQSizeY \ 2)
                Else
                    mouseX = INDENT + (highlightedX * (SQSizeX + WALL_THICKNESS)) + (WALL_THICKNESS \ 2) + (SQSizeX \ 2)
                    mouseY = INDENT + (highlightedY * (SQSizeY + WALL_THICKNESS)) - (WALL_THICKNESS \ 2) + 4
                End If
            Else
                mouseX = INDENT + (highlightedX * (SQSizeX + WALL_THICKNESS)) + (WALL_THICKNESS \ 2) + (SQSizeX \ 2)
                mouseY = INDENT + (highlightedY * (SQSizeY + WALL_THICKNESS)) + (WALL_THICKNESS \ 2) + (SQSizeY \ 2)
            End If

        ElseIf isInSelectionMode Then
            If isSelecting Then
                Dim newEndPoint = e.Location

                ' Adjust the snap behavior based on where we started the selection
                If SnapToFloor Then
                    selectionStartPoint = GetGridAlignedPoint(selectionStartPoint)
                    newEndPoint = GetGridAlignedPoint(newEndPoint, isFloor:=True)
                Else
                    selectionStartPoint = GetGridAlignedPoint(selectionStartPoint, isWall:=True)
                    newEndPoint = GetGridAlignedPoint(newEndPoint, isWall:=True)
                End If

                selectionRectangle = GetRectangle(selectionStartPoint, newEndPoint)
            End If
        Else
            UpdateHighlight(e.X, e.Y)

            If isRightMouseDown Then
                If rdoEdge.Checked Then
                    If isMouseInsideGrid Then
                        RemoveEdgeStyleAtMousePosition(e.X, e.Y)
                    End If
                Else
                    Dim deltaX As Integer = e.X - rightMouseDownPosition.X
                    Dim deltaY As Integer = e.Y - rightMouseDownPosition.Y
                    Dim distanceSquared As Integer = (deltaX * deltaX) + (deltaY * deltaY)
                    If distanceSquared > CLICK_DRAG_THRESHOLD_SQUARED Then
                        RemoveObjectAtMousePosition(e.X, e.Y, removeWalls:=True, removeItems:=False)
                    End If
                End If
            End If
            If isLeftMouseDown Then
                If rdoEdge.Checked Then
                    If isMouseInsideGrid Then
                        SetEdgeStyleAtMousePosition(e.X, e.Y)
                    End If
                Else
                    AddWallAtMousePosition(e.X, e.Y)
                End If
            End If
        End If

        UpdateStatusBar(e.X, e.Y)
    End Sub
    Private Sub PicGame_MouseUp(sender As Object, e As MouseEventArgs) Handles picGame.MouseUp
        If isDraggingSelection Then
            ' Completing selection dragging
            If e.Button = MouseButtons.Left Then
                ' Save the state before modifying the data model
                If Not isRestoringState Then
                    SaveStateForUndo()
                End If

                isDraggingSelection = False
                picGame.Capture = False
                Cursor = Cursors.Default

                If selectionRectangle.IsEmpty Then
                    Return
                End If

                ' Convert cursor position to cell coordinates
                Dim cellX As Integer = (e.X - INDENT) \ (SQSizeX + WALL_THICKNESS)
                Dim cellY As Integer = (e.Y - INDENT) \ (SQSizeY + WALL_THICKNESS)

                ' Paste data using cell coordinates
                PasteSelectionDataTo(New Point(cellX, cellY), False, copiedSelectionType = "Edge")

                isCopying = False
                isSelectionReadyToDrag = False

                ' Reset selection-related variables to prevent issues with future operations
                selectionData = Nothing
                selectionStartCell = New Point(-1, -1)
                copiedSelectionData = Nothing
                copiedSelectionType = ""
                isCopying = False
                isSelectionReadyToDrag = False
                isDraggingSelection = False

                ' Clear the redo stack since we've made a new change
                redoStack.Clear()
            End If
        ElseIf isInSelectionMode AndAlso isSelecting Then
            If e.Button = MouseButtons.Left Then
                ' Finalizing the selection rectangle
                isSelecting = False
                selectionEndPoint = e.Location

                ' Finalize selection snapping based on the type of click
                selectionEndPoint = If(SnapToFloor, GetGridAlignedPoint(selectionEndPoint, isFloor:=True), GetGridAlignedPoint(selectionEndPoint, isWall:=True))

                selectionRectangle = GetRectangle(selectionStartPoint, selectionEndPoint)

                ' Check if the selection needs to be adjusted
                selectionRectangle = AdjustSelectionRectangleToWalls(selectionRectangle)

                ' Reset selection-related variables
                selectionData = Nothing
                selectionStartCell = New Point(-1, -1)
                copiedSelectionData = Nothing
                copiedSelectionType = ""
                isCopying = False
                isSelectionReadyToDrag = False
                isDraggingSelection = False

                If selectionRectangle.IsEmpty Then
                    TurnOffSelectionMode()
                End If
            End If
        Else
            ' Normal mouse up processing
            If e.Button = MouseButtons.Left Then
                If isDraggingItem Then
                    ' Save the state before modifying the data model
                    If Not isRestoringState Then
                        SaveStateForUndo()
                    End If

                    isDraggingItem = False
                    picGame.Capture = False
                    Cursor.Current = Cursors.Default

                    ' Snap the item to the grid position
                    UpdateHighlight(e.X, e.Y)
                    If isMouseInsideGrid Then
                        If draggedItemIsWall Then
                            If draggedItemIsVerticalWall Then
                                If highlightedX >= 0 AndAlso highlightedX < verticalWallItems.Length AndAlso
                   verticalWallItems(highlightedX) IsNot Nothing AndAlso
                   highlightedY >= 0 AndAlso highlightedY < verticalWallItems(0).Length Then

                                    If Not IsVerticalWallConnectedToEdge(New Point(highlightedX, highlightedY)) OrElse IsFlipperItem(draggedItem.ImageKey) Then
                                        verticalWallItems(highlightedX)(highlightedY) = draggedItem
                                        verticalWalls(highlightedX)(highlightedY) = False
                                    Else
                                        ReturnItemToOriginalLocation()
                                    End If
                                End If
                            Else
                                If highlightedX >= 0 AndAlso highlightedX < horizontalWallItems.Length AndAlso
                   horizontalWallItems(highlightedX) IsNot Nothing AndAlso
                   highlightedY >= 0 AndAlso highlightedY < horizontalWallItems(0).Length Then

                                    If Not IsHorizontalWallConnectedToEdge(New Point(highlightedX, highlightedY)) OrElse IsFlipperItem(draggedItem.ImageKey) Then
                                        horizontalWallItems(highlightedX)(highlightedY) = draggedItem
                                        horizontalWalls(highlightedX)(highlightedY) = False
                                    Else
                                        ReturnItemToOriginalLocation()
                                    End If
                                End If
                            End If
                        Else
                            If highlightedX >= 0 AndAlso highlightedX < placedItems.Length AndAlso
                   highlightedY >= 0 AndAlso highlightedY < placedItems(0).Length Then

                                placedItems(highlightedX)(highlightedY) = draggedItem
                            End If
                        End If
                    End If

                    ' Clear redo stack since we've made a new change
                    redoStack.Clear()

                    ' Invalidate the picGame control to refresh the display

                End If

                isLeftMouseDown = False
                isActionInProgress = False

            ElseIf e.Button = MouseButtons.Right Then
                If isRightMouseDown Then
                    isRightMouseDown = False

                    If rdoEdge.Checked Then
                        UpdateHighlight(e.X, e.Y)
                        If isMouseInsideGrid Then
                            If Not highlightedWallX AndAlso Not highlightedWallY Then
                                If highlightedX >= 0 AndAlso highlightedX < SQCOUNTX AndAlso highlightedY >= 0 AndAlso highlightedY < SQCOUNTY Then
                                    floorsUseEdgeStyle(highlightedX)(highlightedY) = False

                                End If
                            End If
                        End If
                    Else
                        Dim deltaX As Integer = e.X - rightMouseDownPosition.X
                        Dim deltaY As Integer = e.Y - rightMouseDownPosition.Y
                        Dim distanceSquared As Integer = (deltaX * deltaX) + (deltaY * deltaY)
                        If distanceSquared < CLICK_DRAG_THRESHOLD_SQUARED Then
                            RemoveObjectAtMousePosition(e.X, e.Y, removeWalls:=False, removeItems:=True)
                        End If
                    End If

                    isActionInProgress = False
                End If

                ' Check if the right-click is outside the selected area
                If isInSelectionMode AndAlso Not selectionRectangle.Contains(e.Location) Then
                    TurnOffSelectionMode()
                End If
            End If
        End If
    End Sub
#Region " Select "

    ' Methods related to ctmMenu
    Private Sub BtnSelect_Click(sender As Object, e As EventArgs) Handles btnSelect.Click
        If isInSelectionMode Then
            ' Exiting selection mode
            isInSelectionMode = False
            isSelecting = False
            isSelectionReadyToDrag = False
            selectionRectangle = Rectangle.Empty
            picGame.Cursor = Cursors.Default
            picGame.Invalidate()
        Else
            ' Entering selection mode
            isInSelectionMode = True
            isSelecting = False
            isSelectionReadyToDrag = False
            selectionRectangle = Rectangle.Empty
            picGame.Cursor = Cursors.Cross
        End If
    End Sub
#End Region

#Region " ctmMenu Opened, ctmMenu Closed "

    Private Sub ctmMenu_Opened(sender As Object, e As EventArgs) Handles ctmMenu.Opened
        AddHandler ctmMenu.Closed, AddressOf ctmMenu_Closed
        ' Check the selection area
        If selectionRectangle.IsEmpty Then
            ' Disable the Clear, Copy, Move menus if there's no selection
            mnuClear.Enabled = False
            mnuCopy.Enabled = False
            Return
        Else
            mnuClear.Enabled = True
            mnuCopy.Enabled = True
        End If

        ' Capture the selection data if not already captured
        If selectionData Is Nothing Then
            CaptureSelectionData()
        End If

        ' Initialize booleans for item categories
        Dim hasEdge As Boolean = False
        Dim hasBaddies As Boolean = False
        Dim hasBlockStoppers As Boolean = False
        Dim hasBlocks As Boolean = False
        Dim hasCoins As Boolean = False
        Dim hasKeys As Boolean = False
        Dim hasWarps As Boolean = False
        Dim hasFlippers As Boolean = False
        Dim hasLasers As Boolean = False
        Dim hasWalls As Boolean = False

        ' Loop through the selection data
        For x As Integer = 0 To selectionData.selectionWidth - 1
            For y As Integer = 0 To selectionData.selectionHeight - 1
                ' Check Edge
                If selectionData.floorsUseEdgeStyle(x)(y) Then
                    hasEdge = True
                End If

                ' Check placedItems
                Dim placedItem As ItemInfo = selectionData.placedItems(x)(y)
                If placedItem IsNot Nothing Then
                    Dim imageKey As String = placedItem.ImageKey
                    If IsBaddieItem(imageKey) Then
                        hasBaddies = True
                    ElseIf IsBlockStopperItem(imageKey) Then
                        hasBlockStoppers = True
                    ElseIf IsBlockItem(imageKey) Then
                        hasBlocks = True
                    ElseIf IsCoinItem(imageKey) Then
                        hasCoins = True
                    ElseIf IsKeyItem(imageKey) Then
                        hasKeys = True
                    ElseIf IsWarpItem(imageKey) Then
                        hasWarps = True
                    ElseIf isFlipperItems(imageKey) Then
                        hasFlippers = True
                    ElseIf IsLaserItem(imageKey) Then
                        hasLasers = True
                    End If
                End If
            Next
        Next

        ' Check vertical walls and wall items
        If selectionData.verticalWalls IsNot Nothing Then
            For x As Integer = 0 To selectionData.verticalWalls.Length - 1
                For y As Integer = 0 To selectionData.verticalWalls(x).Length - 1
                    If selectionData.verticalWalls(x)(y) Then
                        hasWalls = True
                    End If
                    Dim wallItem As ItemInfo = selectionData.verticalWallItems(x)(y)
                    If wallItem IsNot Nothing Then
                        Dim imageKey As String = wallItem.ImageKey
                        If isFlipperItems(imageKey) Then
                            hasFlippers = True
                        ElseIf IsLaserItem(imageKey) Then
                            hasLasers = True
                        End If
                    End If
                Next
            Next
        End If

        ' Check horizontal walls and wall items
        If selectionData.horizontalWalls IsNot Nothing Then
            For x As Integer = 0 To selectionData.horizontalWalls.Length - 1
                For y As Integer = 0 To selectionData.horizontalWalls(x).Length - 1
                    If selectionData.horizontalWalls(x)(y) Then
                        hasWalls = True
                    End If
                    Dim wallItem As ItemInfo = selectionData.horizontalWallItems(x)(y)
                    If wallItem IsNot Nothing Then
                        Dim imageKey As String = wallItem.ImageKey
                        If isFlipperItems(imageKey) Then
                            hasFlippers = True
                        ElseIf IsLaserItem(imageKey) Then
                            hasLasers = True
                        End If
                    End If
                Next
            Next
        End If

        ' Set enabled state of menu items in Clear menu
        mnuClearEdge.Enabled = hasEdge
        mnuClearBaddies.Enabled = hasBaddies
        mnuClearBlockStoppers.Enabled = hasBlockStoppers
        mnuClearBlocks.Enabled = hasBlocks
        mnuClearCoins.Enabled = hasCoins
        mnuClearKeys.Enabled = hasKeys
        mnuClearWarps.Enabled = hasWarps
        mnuClearFlippers.Enabled = hasFlippers
        mnuClearLasers.Enabled = hasLasers
        mnuClearWalls.Enabled = hasWalls
        mnuClearAll.Enabled = True ' "Clear All" is always enabled
    End Sub

    Private Sub ctmMenu_Closed(sender As Object, e As ToolStripDropDownClosedEventArgs)
        If isInSelectionMode Then
            Dim menuPosition = picGame.PointToClient(MousePosition)
            ctmMenu.Show(picGame, menuPosition)
        End If
    End Sub

#End Region

#Region " Copy "
    Private Sub mnuCopy_Click(sender As Object, e As EventArgs) Handles mnuCopy.Click
        If Not isRestoringState Then SaveStateForUndo()
        If selectionRectangle.IsEmpty Then
            Return
        End If

        CaptureSelectionData()
        copiedSelectionData = CloneSelectionData(selectionData)
        isCopying = True

        ' Extract the selection type from the sender's name
        Dim menuItem = CType(sender, ToolStripMenuItem)
        copiedSelectionType = menuItem.Name.Substring(7) ' Remove the "mnuCopy" prefix

        ' Filter the selection data based on the selection type
        Select Case copiedSelectionType
            Case "All"
            ' Do nothing, keep all items
            Case "Baddies"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Baddies"))
            Case "BlockStoppers"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("BlockStoppers"))
            Case "Blocks"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Blocks"))
            Case "Coins"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Coins"))
            Case "Keys"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Keys"))
            Case "Warps"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Warps"))
            Case "Flippers"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Flippers"))
            Case "Lasers"
                FilterSelectionDataForItemTypes(selectionData, GetItemKeysForType("Lasers"))
            Case "Edge"
            ' Handle edge separately if needed
            Case "Walls"
                ' Handle walls separately if needed
            Case Else
                ' Handle other cases
        End Select

        ' Proceed with copying the filtered selection data
        copiedSelectionData = CloneSelectionData(selectionData)

        ' Get cursor position in picGame coordinates
        Dim cursorPosInPicGame = picGame.PointToClient(Cursor.Position)

        ' Adjust selection rectangle to center on the cursor
        selectionRectangle.Location = New Point(
        cursorPosInPicGame.X - (selectionRectangle.Width \ 2),
        cursorPosInPicGame.Y - (selectionRectangle.Height \ 2))

        ' Recalculate selectionOffset based on new rectangle position
        selectionOffset = New Point(
        Cursor.Position.X - picGame.PointToScreen(selectionRectangle.Location).X,
        Cursor.Position.Y - picGame.PointToScreen(selectionRectangle.Location).Y)

        ' Automatically start dragging the selection
        isSelectionReadyToDrag = True
        isDraggingSelection = True
        picGame.Capture = True
        Cursor = Cursors.SizeAll
        picGame.Invalidate()

        ' Handle pasting logic
        AddHandler picGame.MouseUp, Sub(mouseSender As Object, mouseEventArgs As MouseEventArgs)
                                        ' Paste data
                                        PasteSelectionDataTo(New Point(cursorPosInPicGame.X, cursorPosInPicGame.Y), False, copiedSelectionType = "Edge")
                                        isSelectionReadyToDrag = False
                                        isDraggingSelection = False
                                        picGame.Capture = False
                                        Cursor = Cursors.Default
                                        picGame.Invalidate()
                                    End Sub
    End Sub
    Private Sub CaptureSelectionData()
        If selectionRectangle.IsEmpty Then
            Return
        End If

        ' Use the exact selection rectangle coordinates rather than recalculating
        Dim startCellX As Integer = (selectionRectangle.X - INDENT) \ (SQSizeX + WALL_THICKNESS)
        Dim startCellY As Integer = (selectionRectangle.Y - INDENT) \ (SQSizeY + WALL_THICKNESS)

        ' Calculate width and height in cells while preserving the wall snapping
        Dim widthInCells As Integer = Math.Ceiling((selectionRectangle.Width + WALL_THICKNESS) / (SQSizeX + WALL_THICKNESS))
        Dim heightInCells As Integer = Math.Ceiling((selectionRectangle.Height + WALL_THICKNESS) / (SQSizeY + WALL_THICKNESS))

        ' Initialize selectionData with the preserved dimensions
        selectionData = New SelectionData With {
        .selectionWidth = widthInCells,
        .selectionHeight = heightInCells
    }

        ' Capture placed items and floor edge styles
        selectionData.placedItems = New ItemInfo(selectionData.selectionWidth - 1)() {}
        selectionData.floorsUseEdgeStyle = New Boolean(selectionData.selectionWidth - 1)() {}
        For x As Integer = 0 To selectionData.selectionWidth - 1
            selectionData.placedItems(x) = New ItemInfo(selectionData.selectionHeight - 1) {}
            selectionData.floorsUseEdgeStyle(x) = New Boolean(selectionData.selectionHeight - 1) {}
            For y As Integer = 0 To selectionData.selectionHeight - 1
                Dim srcX As Integer = startCellX + x
                Dim srcY As Integer = startCellY + y
                If srcX >= 0 AndAlso srcX < SQCOUNTX AndAlso srcY >= 0 AndAlso srcY < SQCOUNTY Then
                    selectionData.placedItems(x)(y) = placedItems(srcX)(srcY)
                    selectionData.floorsUseEdgeStyle(x)(y) = floorsUseEdgeStyle(srcX)(srcY)
                Else
                    selectionData.placedItems(x)(y) = Nothing
                    selectionData.floorsUseEdgeStyle(x)(y) = False
                End If
            Next
        Next

        ' Capture internal vertical walls (excluding boundary walls)
        If selectionData.selectionWidth > 1 Then
            Dim numVertWalls As Integer = selectionData.selectionWidth - 2
            selectionData.verticalWalls = New Boolean(numVertWalls)() {}
            selectionData.verticalWallItems = New ItemInfo(numVertWalls)() {}
            For x As Integer = 0 To numVertWalls
                selectionData.verticalWalls(x) = New Boolean(selectionData.selectionHeight - 1) {}
                selectionData.verticalWallItems(x) = New ItemInfo(selectionData.selectionHeight - 1) {}
                For y As Integer = 0 To selectionData.selectionHeight - 1
                    Dim wallX As Integer = startCellX + x + 1
                    Dim wallY As Integer = startCellY + y

                    ' Ensure indices are within bounds
                    If wallX >= 0 AndAlso wallX < verticalWalls.Length AndAlso wallY >= 0 AndAlso wallY < verticalWalls(0).Length Then
                        selectionData.verticalWalls(x)(y) = verticalWalls(wallX)(wallY)
                        selectionData.verticalWallItems(x)(y) = verticalWallItems(wallX)(wallY)
                    Else
                        selectionData.verticalWalls(x)(y) = False
                        selectionData.verticalWallItems(x)(y) = Nothing
                    End If
                Next
            Next
        Else
            ' No internal vertical walls to capture
            selectionData.verticalWalls = Nothing
            selectionData.verticalWallItems = Nothing
        End If

        ' Capture internal horizontal walls (excluding boundary walls)
        If selectionData.selectionHeight > 1 Then
            Dim numHorizWalls As Integer = selectionData.selectionHeight - 2
            selectionData.horizontalWalls = New Boolean(selectionData.selectionWidth - 1)() {}
            selectionData.horizontalWallItems = New ItemInfo(selectionData.selectionWidth - 1)() {}
            For x As Integer = 0 To selectionData.selectionWidth - 1
                selectionData.horizontalWalls(x) = New Boolean(numHorizWalls) {}
                selectionData.horizontalWallItems(x) = New ItemInfo(numHorizWalls) {}
                For y As Integer = 0 To numHorizWalls
                    Dim wallX As Integer = startCellX + x
                    Dim wallY As Integer = startCellY + y + 1

                    ' Ensure indices are within bounds
                    If wallX >= 0 AndAlso wallX < horizontalWalls.Length AndAlso wallY >= 0 AndAlso wallY < horizontalWalls(0).Length Then
                        selectionData.horizontalWalls(x)(y) = horizontalWalls(wallX)(wallY)
                        selectionData.horizontalWallItems(x)(y) = horizontalWallItems(wallX)(wallY)
                    Else
                        selectionData.horizontalWalls(x)(y) = False
                        selectionData.horizontalWallItems(x)(y) = Nothing
                    End If
                Next
            Next
        Else
            ' No internal horizontal walls to capture
            selectionData.horizontalWalls = Nothing
            selectionData.horizontalWallItems = Nothing
        End If

        ' Store the selection start cell
        selectionStartCell = New Point(startCellX, startCellY)
    End Sub

    Private Sub PasteSelectionDataTo(newCell As Point, removeOldData As Boolean, copyEdge As Boolean)
        If copiedSelectionData Is Nothing Then
            Return
        End If

        ' Keep the original selection rectangle dimensions
        Dim newRect As New Rectangle(
        INDENT + (newCell.X * (SQSizeX + WALL_THICKNESS)),
        INDENT + (newCell.Y * (SQSizeY + WALL_THICKNESS)),
        selectionRectangle.Width,  ' Use original width
        selectionRectangle.Height  ' Use original height
    )

        selectionRectangle = newRect

        ' Ensure the new position is within bounds
        newCell.X = Math.Max(0, Math.Min(SQCOUNTX - copiedSelectionData.selectionWidth, newCell.X))
        newCell.Y = Math.Max(0, Math.Min(SQCOUNTY - copiedSelectionData.selectionHeight, newCell.Y))

        ' Paste placed items and floor edge styles
        For x As Integer = 0 To copiedSelectionData.selectionWidth - 1
            For y As Integer = 0 To copiedSelectionData.selectionHeight - 1
                If newCell.X + x < SQCOUNTX AndAlso newCell.Y + y < SQCOUNTY Then
                    If copiedSelectionData.placedItems(x)(y) IsNot Nothing Then
                        placedItems(newCell.X + x)(newCell.Y + y) = copiedSelectionData.placedItems(x)(y)
                    End If
                    If copyEdge AndAlso copiedSelectionData.floorsUseEdgeStyle(x)(y) Then
                        floorsUseEdgeStyle(newCell.X + x)(newCell.Y + y) = True
                    End If
                End If
            Next
        Next

        ' Paste internal vertical walls, if any
        If copiedSelectionData.verticalWalls IsNot Nothing AndAlso Not removeOldData Then
            For x As Integer = 0 To copiedSelectionData.verticalWalls.Length - 1
                For y As Integer = 0 To copiedSelectionData.verticalWalls(x).Length - 1
                    Dim targetX As Integer = newCell.X + x
                    Dim targetY As Integer = newCell.Y + y

                    If targetX >= 0 AndAlso targetX < verticalWalls.Length AndAlso targetY >= 0 AndAlso targetY < verticalWalls(0).Length Then
                        verticalWalls(targetX)(targetY) = copiedSelectionData.verticalWalls(x)(y)
                        If copiedSelectionData.verticalWallItems(x)(y) IsNot Nothing Then
                            verticalWallItems(targetX)(targetY) = copiedSelectionData.verticalWallItems(x)(y)
                        End If
                    End If
                Next
            Next
        End If

        ' Paste internal horizontal walls, if any
        If copiedSelectionData.horizontalWalls IsNot Nothing AndAlso Not removeOldData Then
            For x As Integer = 0 To copiedSelectionData.horizontalWalls.Length - 1
                For y As Integer = 0 To copiedSelectionData.horizontalWalls(x).Length - 1
                    Dim targetX As Integer = newCell.X + x
                    Dim targetY As Integer = newCell.Y + y

                    If targetX >= 0 AndAlso targetX < horizontalWalls.Length AndAlso targetY >= 0 AndAlso targetY < horizontalWalls(0).Length Then
                        horizontalWalls(targetX)(targetY) = copiedSelectionData.horizontalWalls(x)(y)
                        If copiedSelectionData.horizontalWallItems(x)(y) IsNot Nothing Then
                            horizontalWallItems(targetX)(targetY) = copiedSelectionData.horizontalWallItems(x)(y)
                        End If
                    End If
                Next
            Next
        End If

        ' Update the selection rectangle to the new position
        selectionRectangle = New Rectangle(
        INDENT + (newCell.X * (SQSizeX + WALL_THICKNESS)),
        INDENT + (newCell.Y * (SQSizeY + WALL_THICKNESS)),
        (copiedSelectionData.selectionWidth * (SQSizeX + WALL_THICKNESS)) - WALL_THICKNESS,
        (copiedSelectionData.selectionHeight * (SQSizeY + WALL_THICKNESS)) - WALL_THICKNESS
    )

        ' Remove old data if moving
        If removeOldData Then
            ClearSelectedArea()
        End If

        picGame.Invalidate()
    End Sub
    Private Function CloneSelectionData(original As SelectionData) As SelectionData
        Dim clone As New SelectionData With {
        .selectionWidth = original.selectionWidth,
        .selectionHeight = original.selectionHeight
    }

        ' Clone placedItems
        If original.placedItems IsNot Nothing Then
            clone.placedItems = original.placedItems.Select(Function(row) row.ToArray()).ToArray()
        End If

        ' Clone floorsUseEdgeStyle
        If original.floorsUseEdgeStyle IsNot Nothing Then
            clone.floorsUseEdgeStyle = original.floorsUseEdgeStyle.Select(Function(row) row.ToArray()).ToArray()
        End If

        ' Clone verticalWalls and verticalWallItems
        If original.verticalWalls IsNot Nothing Then
            clone.verticalWalls = original.verticalWalls.Select(Function(row) CType(row.Clone(), Boolean())).ToArray()
        End If

        If original.verticalWallItems IsNot Nothing Then
            clone.verticalWallItems = original.verticalWallItems.Select(Function(row) row.ToArray()).ToArray()
        End If

        ' Clone horizontalWalls and horizontalWallItems
        If original.horizontalWalls IsNot Nothing Then
            clone.horizontalWalls = original.horizontalWalls.Select(Function(row) CType(row.Clone(), Boolean())).ToArray()
        End If

        If original.horizontalWallItems IsNot Nothing Then
            clone.horizontalWallItems = original.horizontalWallItems.Select(Function(row) row.ToArray()).ToArray()
        End If

        Return clone
    End Function

    Private Sub DrawSelectionData(g As Graphics, baseCellX As Integer, baseCellY As Integer, data As SelectionData)
        Dim xOrigin As Integer = INDENT
        Dim yOrigin As Integer = INDENT

        Dim colorMatrix As New Imaging.ColorMatrix With {
            .Matrix33 = 0.5F  ' Set opacity to 50%
            }
        Dim imgAttributes As New Imaging.ImageAttributes()
        imgAttributes.SetColorMatrix(colorMatrix, Imaging.ColorMatrixFlag.Default, Imaging.ColorAdjustType.Bitmap)

        For x As Integer = 0 To data.selectionWidth - 1
            For y As Integer = 0 To data.selectionHeight - 1
                If data.placedItems(x)(y) IsNot Nothing Then
                    Dim img As Image = GetImageByKey(data.placedItems(x)(y).ImageKey)
                    If img IsNot Nothing Then
                        ImageAnimator.UpdateFrames(img)
                        Dim xPos As Integer = xOrigin + ((baseCellX + x) * (SQSizeX + WALL_THICKNESS)) + (WALL_THICKNESS \ 2)
                        Dim yPos As Integer = yOrigin + ((baseCellY + y) * (SQSizeY + WALL_THICKNESS)) + (WALL_THICKNESS \ 2)
                        Dim destRect As New Rectangle(xPos, yPos, SQSizeX, SQSizeY)
                        g.DrawImage(img, destRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttributes)
                    End If
                End If
            Next
        Next

        ' Draw vertical wall items
        If data.verticalWallItems IsNot Nothing Then
            For x As Integer = 0 To data.verticalWallItems.Length - 1
                For y As Integer = 0 To data.verticalWallItems(x).Length - 1
                    If data.verticalWallItems(x)(y) IsNot Nothing Then
                        Dim img As Image = GetImageByKey(data.verticalWallItems(x)(y).ImageKey)
                        If img IsNot Nothing Then
                            ImageAnimator.UpdateFrames(img)
                            Dim wallX As Integer = xOrigin + ((baseCellX + x + 1) * (SQSizeX + WALL_THICKNESS)) - (WALL_THICKNESS \ 2)
                            Dim wallY As Integer = yOrigin + ((baseCellY + y) * (SQSizeY + WALL_THICKNESS)) + (WALL_THICKNESS \ 2)
                            Dim wallWidth As Integer = WALL_THICKNESS
                            Dim wallHeight As Integer = SQSizeY

                            Dim newWidth As Integer = img.Width
                            Dim newHeight As Integer = wallHeight

                            Dim centeredX As Integer = wallX + ((wallWidth - newWidth) \ 2)
                            Dim drawRect As New Rectangle(centeredX, wallY, newWidth, newHeight)
                            g.DrawImage(img, drawRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttributes)
                        End If
                    End If
                Next
            Next
        End If

        ' Draw horizontal wall items
        If data.horizontalWallItems IsNot Nothing Then
            For x As Integer = 0 To data.horizontalWallItems.Length - 1
                For y As Integer = 0 To data.horizontalWallItems(x).Length - 1
                    If data.horizontalWallItems(x)(y) IsNot Nothing Then
                        Dim img As Image = GetImageByKey(data.horizontalWallItems(x)(y).ImageKey)
                        If img IsNot Nothing Then
                            ImageAnimator.UpdateFrames(img)
                            Dim wallX As Integer = xOrigin + ((baseCellX + x) * (SQSizeX + WALL_THICKNESS)) + (WALL_THICKNESS \ 2)
                            Dim wallY As Integer = yOrigin + ((baseCellY + y + 1) * (SQSizeY + WALL_THICKNESS)) - (WALL_THICKNESS \ 2)
                            Dim wallWidth As Integer = SQSizeX
                            Dim wallHeight As Integer = WALL_THICKNESS

                            Dim newWidth As Integer = wallWidth
                            Dim newHeight As Integer = img.Height

                            Dim centeredY As Integer = wallY + ((wallHeight - newHeight) \ 2)
                            Dim drawRect As New Rectangle(wallX, centeredY, newWidth, newHeight)
                            g.DrawImage(img, drawRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttributes)
                        End If
                    End If
                Next
            Next
        End If
    End Sub

#End Region
    Private Function IsBaddieItem(imageKey As String) As Boolean
        Return imageKey = "picBaddy1" OrElse imageKey = "picBaddy2" OrElse imageKey = "picBaddy3" OrElse imageKey = "picBaddy4"
    End Function

    Private Function IsBlockStopperItem(imageKey As String) As Boolean
        Return imageKey = "picBlockStopper1"
    End Function

    Private Function IsBlockItem(imageKey As String) As Boolean
        Return imageKey = "picBlock1"
    End Function

    Private Function IsCoinItem(imageKey As String) As Boolean
        Return imageKey = "picCoin"
    End Function

    Private Function IsKeyItem(imageKey As String) As Boolean
        Return imageKey = "picKey"
    End Function

    Private Function IsWarpItem(imageKey As String) As Boolean
        Return imageKey = "picWarp" OrElse imageKey = "picWarp2"
    End Function

    Private Function isFlipperItems(imageKey As String) As Boolean
        Return imageKey = "picFlipper1" OrElse imageKey = "picFlipper2" OrElse imageKey = "picFlipper3" OrElse imageKey = "picFlipper4"
    End Function

    Private Function IsLaserItem(imageKey As String) As Boolean
        Return imageKey = "picLaser1" OrElse imageKey = "picLaser2"
    End Function

    Private Sub mnuCancel_Click(sender As Object, e As EventArgs) Handles mnuCancel.Click
        TurnOffSelectionMode()
    End Sub

    Private Function GetItemKeysForType(type As String) As String()
        Select Case type
            Case "Baddies"
                Return New String() {"picBaddy1", "picBaddy2", "picBaddy3", "picBaddy4"}
            Case "BlockStoppers"
                Return New String() {"picBlockStopper1"}
            Case "Blocks"
                Return New String() {"picBlock1"}
            Case "Coins"
                Return New String() {"picCoin"}
            Case "Keys"
                Return New String() {"picKey"}
            Case "Warps"
                Return New String() {"picWarp", "picWarp2"}
            Case "Flippers"
                Return New String() {"picFlipper1", "picFlipper2", "picFlipper3", "picFlipper4"}
            Case "Lasers"
                Return New String() {"picLaser1", "picLaser2"}
            Case Else
                Return New String() {}
        End Select
    End Function

    Private Sub FilterSelectionDataForItemTypes(selectionData As SelectionData, allowedItemKeys As String())
        ' Filter placedItems
        For x As Integer = 0 To selectionData.selectionWidth - 1
            For y As Integer = 0 To selectionData.selectionHeight - 1
                Dim placedItem As ItemInfo = selectionData.placedItems(x)(y)
                If placedItem IsNot Nothing AndAlso Not allowedItemKeys.Contains(placedItem.ImageKey) Then
                    selectionData.placedItems(x)(y) = Nothing
                End If
            Next
        Next

        ' Filter verticalWallItems
        If selectionData.verticalWallItems IsNot Nothing Then
            For x As Integer = 0 To selectionData.verticalWallItems.Length - 1
                For y As Integer = 0 To selectionData.verticalWallItems(x).Length - 1
                    Dim wallItem As ItemInfo = selectionData.verticalWallItems(x)(y)
                    If wallItem IsNot Nothing AndAlso Not allowedItemKeys.Contains(wallItem.ImageKey) Then
                        selectionData.verticalWallItems(x)(y) = Nothing
                    End If
                Next
            Next
        End If

        ' Filter horizontalWallItems
        If selectionData.horizontalWallItems IsNot Nothing Then
            For x As Integer = 0 To selectionData.horizontalWallItems.Length - 1
                For y As Integer = 0 To selectionData.horizontalWallItems(x).Length - 1
                    Dim wallItem As ItemInfo = selectionData.horizontalWallItems(x)(y)
                    If wallItem IsNot Nothing AndAlso Not allowedItemKeys.Contains(wallItem.ImageKey) Then
                        selectionData.horizontalWallItems(x)(y) = Nothing
                    End If
                Next
            Next
        End If

        ' Filter verticalWalls
        If selectionData.verticalWalls IsNot Nothing Then
            For x As Integer = 0 To selectionData.verticalWalls.Length - 1
                For y As Integer = 0 To selectionData.verticalWalls(x).Length - 1
                    If Not allowedItemKeys.Contains("Walls") Then
                        selectionData.verticalWalls(x)(y) = False
                    End If
                Next
            Next
        End If

        ' Filter horizontalWalls
        If selectionData.horizontalWalls IsNot Nothing Then
            For x As Integer = 0 To selectionData.horizontalWalls.Length - 1
                For y As Integer = 0 To selectionData.horizontalWalls(x).Length - 1
                    If Not allowedItemKeys.Contains("Walls") Then
                        selectionData.horizontalWalls(x)(y) = False
                    End If
                Next
            Next
        End If
    End Sub

End Class

Can you identify why in the selection process the selected area shrinks to fit the floors when we've finished selecting? It should stay snapped to the walls.