Public Module CommandManager
    Private Property UndoCommands As New Stack(Of ICommand)

    Private Property RedoCommands As New Stack(Of ICommand)

    Private _isRunning As Boolean = False

    ''' <summary>
    ''' 运行命令，并将命令添加至撤销堆栈
    ''' </summary>
    ''' <param name="command"></param>
    Public Sub RunCommand(command As ICommand)
        command.Redo()

        AddUndoCommand(command)
    End Sub


    Public ReadOnly Property IsRuning() As Boolean
        Get
            Return _isRunning
        End Get
    End Property

    Public Function CanUndo() As Boolean
        Return UndoCommands.Count > 0
    End Function

    Public Function CanRedo() As Boolean
        Return RedoCommands.Count > 0
    End Function

    ''' <summary>
    ''' 将命令添加至撤销堆栈
    ''' </summary>
    Public Sub AddUndoCommand(command As ICommand)
        UndoCommands.Push(command)

        If RedoCommands.Count > 0 Then
            ClearRedoCommands()
        End If
    End Sub

    ''' <summary>
    ''' 清空撤销命令堆栈
    ''' </summary>
    Public Sub ClearUndoCommands()
        UndoCommands.Clear()

    End Sub

    ''' <summary>
    ''' 清空重做命令堆栈
    ''' </summary>
    Public Sub ClearRedoCommands()
        RedoCommands.Clear()
    End Sub

    ''' <summary>
    ''' 清空撤销与重做命令堆栈
    ''' </summary>
    Public Sub ClearCommands()
        ClearUndoCommands()
        ClearRedoCommands()
    End Sub

    ''' <summary>
    ''' 执行撤销命令
    ''' </summary>
    Public Sub Undo()
        If UndoCommands.Count <= 0 Then Return
        _isRunning = True
        Dim command As ICommand = UndoCommands.Pop()
        command.Undo()
        RedoCommands.Push(command)
        _isRunning = False
    End Sub


    ''' <summary>
    ''' 执行重做命令
    ''' </summary>
    Public Sub Redo()
        If RedoCommands.Count <= 0 Then Return
        _isRunning = True

        Dim command As ICommand = RedoCommands.Pop()
        command.Redo()

        UndoCommands.Push(command)
        _isRunning = False
    End Sub

End Module
