Imports EnvDTE

Public Module TextPaneMacros

    Sub SplitAllWindows()
        ' Description: Splits all text windows

        Dim win As Window
        Dim txtWin As TextWindow
        Dim saveWin As Window = DTE.ActiveWindow

        For Each win In DTE.Windows
            txtWin = GetTextWindow(win)

            If Not txtWin Is Nothing Then
                SplitWindow(txtWin)
            End If
        Next

        saveWin.Activate()
    End Sub

    Sub UnsplitAllWindows()
        ' Description: Unsplits all text windows

        Dim win As Window
        Dim txtWin As TextWindow
        Dim saveWin As Window = DTE.ActiveWindow

        For Each win In DTE.Windows
            txtWin = GetTextWindow(win)

            If Not txtWin Is Nothing Then
                UnSplitWindow(txtWin)
            End If
        Next

        saveWin.Activate()
    End Sub

    Sub SplitWindow(ByVal txtWin As TextWindow, Optional ByVal restoreActive As Boolean = False)
        ' Description: Splits a text window and optionally restores the active window
        '              when finished

        Dim split As Command = DTE.Commands.Item("Window.Split")
        Dim saveWin As Window

        If restoreActive Then
            saveWin = DTE.ActiveWindow
        End If

        txtWin.Parent.Activate()

        If split.IsAvailable And Not IsSecondPaneOpen(txtWin) Then
            DTE.Commands.Raise(split.Guid, split.ID, Nothing, Nothing)
        End If

        If restoreActive Then
            saveWin.Activate()
        End If
    End Sub

    Sub UnSplitWindow(ByVal txtWin As TextWindow, Optional ByVal restoreActive As Boolean = False)
        ' Description: Unsplits a text window and optionally restores the active window
        '              when finished

        Dim split As Command = DTE.Commands.Item("Window.Split")
        Dim saveWin As Window

        If restoreActive Then
            saveWin = DTE.ActiveWindow
        End If

        txtWin.Parent.Activate()

        If split.IsAvailable And IsSecondPaneOpen(txtWin) Then
            DTE.Commands.Raise(split.Guid, split.ID, Nothing, Nothing)
        End If

        If restoreActive Then
            saveWin.Activate()
        End If
    End Sub

    Function IsSecondPaneOpen(ByVal txtWin As TextWindow) As Boolean
        ' Description: Returns whether a second pane is open in a text window

        Return (txtWin.Panes.Count = 2)
    End Function

    Sub ActivateTopPane()
        ' Description: Activates the top pane in the active window

        Dim txtWin As TextWindow = GetTextWindow(DTE.ActiveWindow)
        Dim txtPane As TextPane

        If Not txtWin Is Nothing Then
            txtPane = GetTopPane(txtWin)
            txtPane.Activate()
        End If
    End Sub

    Sub ActivateBottomPane()
        ' Description: Activates the bottom pane in the active window

        Dim txtWin As TextWindow = GetTextWindow(DTE.ActiveWindow)
        Dim txtPane As TextPane

        If Not txtWin Is Nothing Then
            txtPane = GetBottomPane(txtWin)
            txtPane.Activate()
        End If
    End Sub

    Function GetTopPane(ByVal txtWin As TextWindow) As TextPane
        ' Description: Returns the top pane in the text window

        Dim txtPane As TextPane = Nothing

        If txtWin.Panes.Count = 1 Then
            ' Only one pane, so return it
            txtPane = txtWin.ActivePane
        Else
            ' Top pane is always index 2
            txtPane = txtWin.Panes.Item(2)
        End If

        Return txtPane
    End Function

    Function GetBottomPane(ByVal txtWin As TextWindow) As TextPane
        ' Description: Returns the bottom pane in a text window. Returns top pane 
        '              if only one pane is open

        ' Bottom pane is always index 1
        Return txtWin.Panes.Item(1)
    End Function

    Function IsTopPane(ByVal txtPane As TextPane) As Boolean
        ' Description: Returns whether the given TextPane is the top pane

        Dim result As Boolean = False

        If txtPane.Collection.Count = 1 Then
            result = True
        Else
            If txtPane.Selection Is txtPane.Collection.Item(2).Selection Then
                result = True
            End If
        End If

        Return result
    End Function

    Function IsBottomPane(ByVal txtPane As TextPane) As Boolean
        ' Description: Returns whether the given TextPane is the bottom pane

        Dim result As Boolean = False

        If txtPane.Collection.Count = 2 Then
            result = (txtPane.Selection Is txtPane.Collection.Item(1).Selection)
        End If

        Return result
    End Function

End Module
