# -*- coding: utf-8 -*-#

WXVER = '2.9'
import wxversion
wxversion.select(WXVER)

import wx
import wx.lib.scrolledpanel as scrolled
import wx.stc as st

class STC(st.StyledTextCtrl):
    def __init__(self, *args, **kwargs):
        super(STC, self).__init__(*args, **kwargs)

#        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.Bind(wx.EVT_MOUSEWHEEL, self.moveparentpanel)
        
    def moveparentpanel(self, event):
        self.GetParent().GetEventHandler().ProcessEvent(event)
        event.Skip()
        
    def OnKeyPressed(self, event):
        curStc = event.GetEventObject()
#        print curStc.GetCurrentLine()
#        privious = None
        if curStc.GetCurrentLine() == 0:
            allitems = [w.GetWindow() for w in self.GetGrandParent().Autosizer.GetChildren() if w.GetWindow() is not None]
#            useNextone = False
            
            for item in allitems:
                if isinstance(item, wx.stc.StyledTextCtrl):
                    if curStc == item:
                        previous.SetFocus()
#                        useNextone = True
                        break
#                    elif useNextone == False:
#                        curStc.SetFocus()
                    else:
                        previous = item
#                useNextone = False
        event.Skip()
        
    def AutoIndent(self):
        """Indent from the current position to match the indentation
        of the previous line.
        @postcondition: proper type of white space is added from current pos
                        to match that of indentation in above line
        """
        cpos = self.GetCurrentPos()
        line, pos = self.GetCurLine()
        # Check if a special purpose indenter has been registered
        if line != "":
            txt = self.PythonIndenter(cpos, self.GetIndentChar())
            txt = txt.replace('\n', self.GetEOLChar())
        else:
            # Default Indenter
            line = self.GetCurrentLine()
            text = self.GetTextRange(self.PositionFromLine(line), cpos)
            if text.strip() == u'':
                self.AddText(self.GetEOLChar() + text)
                self.EnsureCaretVisible()
                return
            indent = self.GetLineIndentation(line)
            i_space = indent / self.GetTabWidth()
            ndent = self.GetEOLChar() + self.GetIndentChar() * i_space
            txt = ndent + ((indent - (self.GetTabWidth() * i_space)) * u' ')

        self.AddText(txt)
        self.EnsureCaretVisible()
        
    def OnKeyDown(self, event):
       if not (event.ControlDown() and event.GetKeyCode() == wx.WXK_TAB):
           event.Skip()
           return
       flag = wx.NavigationKeyEvent.IsForward
       if event.ShiftDown():
           flag = 0
       self.Navigate(flag)

###    def autoindent(self):
###        pos = self.GetCurrentPos()
###        line = self.GetCurrentLine()
###        if line:
###            level = self.GetLineIndentation(line - 1)
###            if self.GetLine(line - 1).strip().endswith(":"):
###                level += 6
###                self.SetLineIndentation(line, level)
###    #            self.GotoPos(pos + level)
###                self.GotoPos(pos + len(self.GetLine(line)) - 1)
###
###    def OnKeyPressed(self, event):
###        if not (event.ControlDown() and event.GetKeyCode() == wx.WXK_TAB):
###           event.Skip()
###           return
###        flag = wx.NavigationKeyEvent.IsForward
###        if event.ShiftDown():
###            flag = 0
###        self.Navigate(flag)
###        
###        try:
###            if event.KeyCode == wx.WXK_RETURN:
###                wx.CallAfter(self.autoindent)
###            elif (
###                chr(event.KeyCode) in string.letters or
###                event.KeyCode == 32 and event.ControlDown()
###            ):
###
###                self.timer.Stop()
###                self.timer.Start(200, True)
###        except ValueError:
###            pass
###        event.Skip() 

#    def OnKeyPressed(self, event):
#        curStc = event.GetEventObject()
#        print curStc.GetCurrentLine()
#        privious = None
#        if curStc.GetCurrentLine() == 0:
#            allitems = [w.GetWindow() for w in self.GetGrandParent().Autosizer.GetChildren() if w.GetWindow() is not None]
#            useNextone = False
#            for item in allitems: # except GA part
#                if isinstance(item, wx.stc.StyledTextCtrl):
#                    if curStc == item:
#                        previous.SetFocus()
#                        useNextone = True
#                        break
#                    elif useNextone:
#                        curStc.SetFocus()
#                    else:
#                        previous = item
#                useNextone = False

    def OnRightDown(self, e):
        control = e.GetEventObject()
        sizer = control.GetContainingSizer()
        print control
        print sizer
        print self.GetGrandParent().GetItemIndex(sizer, control)


class TestPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        self.Autosizer = wx.FlexGridSizer(cols=2)
        self.Autosizer.SetFlexibleDirection(wx.VERTICAL)

        self.scrolled_panel = scrolled.ScrolledPanel(self, -1,
                    style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER, name="panel1")
        self.scrolled_panel.SetAutoLayout(1)
        self.scrolled_panel.SetupScrolling()

        self.scrolled_panel.SetSizer(self.Autosizer)

        self.ctrlsDict = {}
        self.ctrlsReverstDic = {}

        for x in range(5):
            self.AddControl(x)

        panelSizer = wx.BoxSizer(wx.VERTICAL)
        panelSizer.Add(self.scrolled_panel, 1, wx.EXPAND)
#        panelSizer.Add(btn)
        self.SetSizer(panelSizer)

        btn = wx.Button(self, wx.ID_ANY, label="add control")
        btn.Bind(wx.EVT_BUTTON, self.AddControl)
        
        self.Autosizer.Add(btn)
        self.Autosizer.AddSpacer(10)
        

        btn = wx.Button(self, wx.ID_ANY, label="Print Text")
        btn.Bind(wx.EVT_BUTTON, self.OnTest)

    def OnTest(self, event):
        for item in self.ctrlsReverstDic: # ctrlsDict:
            control = wx.FindWindowById(item)
            print control.GetLabelText()

    def AddControl(self, no):
        text = wx.Button(self.scrolled_panel, id=wx.NewId(), label='Added control - %s' % no, size=(22,21), style=wx.NO_BORDER)
#        text = wx.StaticText(self.scrolled_panel, label='Added control - %s' % no)
        editor = STC(self.scrolled_panel)
        editor.Text = """1
2
3
4
5"""
        self.Autosizer.Add(text)
        self.Autosizer.Add(editor)

        self.Layout()
        self.ctrlsReverstDic[text.GetId()] = editor.GetId()

    def GetItemIndex(self, sizer, item):
        """
        Returns the index of the given *item* within the sizer. Does not
        search recursively.  The *item* parameter can be either a window
        or a sizer.  An assertion is raised if the item is not found in
        the sizer.
        """
        sItem = sizer.GetItem(item)
        assert sItem is not None, "Item not found in the sizer."
        allItems = sizer.Children
        idx = 0
        for i in allItems:
            if i.this == sItem.this:
                break
            idx += 1
        return idx



from wx.lib.mixins.inspection import InspectionMixin

class AnApp(wx.App, InspectionMixin):
    def OnInit(self):
        self.Init() # InspectionMixin

        return True

if __name__ == '__main__':

    app = AnApp()
    frame = wx.Frame(None)
    panel = TestPanel(frame)
    frame.Show()
    app.MainLoop()

