import wx
def OnMarginClick(evt, text_id):
    # fold and unfold as needed
    CurrentWidget = wx.FindWindowById(text_id)
    if evt.GetMargin() == 2:
        if evt.GetShift() and evt.GetControl():
            FoldAll(text_id)
        else:
            lineClicked = CurrentWidget.LineFromPosition(evt.GetPosition())

            if CurrentWidget.GetFoldLevel(lineClicked) & wx.stc.STC_FOLDLEVELHEADERFLAG:
                if evt.GetShift():
                    CurrentWidget.SetFoldExpanded(lineClicked, True)
                    Expand(text_id,lineClicked, True, True, 1)
                elif evt.GetControl():
                    if CurrentWidget.GetFoldExpanded(lineClicked):
                       CurrentWidget.SetFoldExpanded(lineClicked, False)
                       Expand(text_id,lineClicked, False, True, 0)
                    else:
                        CurrentWidget.SetFoldExpanded(lineClicked, True)
                        Expand(text_id,lineClicked, True, True, 100)
                else:
                    CurrentWidget.ToggleFold(lineClicked)
    evt.Skip()



def FoldAll(text_id):
    CurrentWidget = wx.FindWindowById(text_id)
    lineCount = CurrentWidget.GetLineCount()
    expanding = True

    # find out if we are folding or unfolding
    for lineNum in range(lineCount):
         if CurrentWidget.GetFoldLevel(lineNum) & wx.stc.STC_FOLDLEVELHEADERFLAG:
             expanding = not CurrentWidget.GetFoldExpanded(lineNum)
             break

    lineNum = 0

    while lineNum < lineCount:
        level = CurrentWidget.GetFoldLevel(lineNum)
        if level & wx.stc.STC_FOLDLEVELHEADERFLAG and \
           (level & wx.stc.STC_FOLDLEVELNUMBERMASK) == wx.stc.STC_FOLDLEVELBASE:

            if expanding:
                CurrentWidget.SetFoldExpanded(lineNum, True)
                lineNum = Expand(text_id,lineNum, True)
                lineNum = lineNum - 1
            else:
                lastChild = CurrentWidget.GetLastChild(lineNum, -1)
                CurrentWidget.SetFoldExpanded(lineNum, False)

                if lastChild > lineNum:
                    CurrentWidget.HideLines(lineNum+1, lastChild)

        lineNum = lineNum + 1



def Expand(text_id,line, doExpand, force=False, visLevels=0, level=-1):
    CurrentWidget = wx.FindWindowById(text_id)
    lastChild = CurrentWidget.GetLastChild(line, level)
    line = line + 1

    while line <= lastChild:
        if force:
            if visLevels > 0:
                CurrentWidget.ShowLines(line, line)
            else:
                CurrentWidget.HideLines(line, line)
        else:
            if doExpand:
                CurrentWidget.ShowLines(line, line)

        if level == -1:
            level = CurrentWidget.GetFoldLevel(line)

        if level & wx.stc.STC_FOLDLEVELHEADERFLAG:
            if force:
                if visLevels > 1:
                    CurrentWidget.SetFoldExpanded(line, True)
                else:
                    CurrentWidget.SetFoldExpanded(line, False)

                line = Expand(text_id ,line, doExpand, force, visLevels-1)

            else:
                if doExpand and CurrentWidget.GetFoldExpanded(line):
                    line = Expand(text_id, line, True, force, visLevels-1)
                else:
                    line = Expand(text_id, line, False, force, visLevels-1)
        else:
            line = line + 1

    return line
