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

"""Subclass of PyModulePane, which is generated by wxFormBuilder."""

#import wx
import wx
import wx.stc
import app
from ctx import theContext as context
import tran
from app.ui import pane
from activity.models.ui import ui as ui

CLOSE_PANE_ID = wx.ID_HIGHEST + 100


# Implementing PyModulePane
class PyModulePane(ui.PyModulePane):
    """Implements method pane editor"""

    #command ids: run
    _saveCode = wx.Window.NewControlId()
    _undoCode = wx.Window.NewControlId()
    _redoCode = wx.Window.NewControlId()
    _copyCode = wx.Window.NewControlId()
    _cutCode = wx.Window.NewControlId()
    _pasteCode = wx.Window.NewControlId()
    _deleteCode = wx.Window.NewControlId()
    _toggleFull = wx.Window.NewControlId()
    _navigator = wx.Window.NewControlId()

    def _create_toolbars(self):
        """Create custom toolbar"""
        self.m_localToolbar = wx.aui.AuiToolBar(self, wx.ID_ANY, wx.DefaultPosition,
            wx.DefaultSize, wx.aui.AUI_TB_HORZ_LAYOUT)
        self.m_save = self.m_localToolbar.AddTool(self._saveCode,
            u"save project", wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR),
            wx.NullBitmap, wx.ITEM_NORMAL, u"Save", wx.EmptyString, None)
        self.m_localToolbar.AddSeparator()
        self.m_undo = self.m_localToolbar.AddTool(self._undoCode, u"tool",
            wx.ArtProvider.GetBitmap(wx.ART_UNDO, wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL,
            u"Undo", wx.EmptyString, None)
        self.m_redo = self.m_localToolbar.AddTool(self._redoCode, u"tool",
            wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL,
            u"Redo", wx.EmptyString, None)
        self.m_localToolbar.AddSeparator()
        self.m_copy = self.m_localToolbar.AddTool(self._copyCode, u"copy",
            wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL,
            u"Copy", wx.EmptyString, None)
        self.m_cut = self.m_localToolbar.AddTool(self._cutCode, u"cut", wx.ArtProvider.GetBitmap(
            wx.ART_CUT, wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL, u"Cut", wx.EmptyString, None)
        self.m_paste = self.m_localToolbar.AddTool(self._pasteCode, u"paste",
            wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR), wx.NullBitmap,
            wx.ITEM_NORMAL, u"Paste", wx.EmptyString, None)
        self.m_localToolbar.AddSeparator()
        self.m_delete = self.m_localToolbar.AddTool(self._deleteCode, u"delete",
            wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL,
            u"Delete", wx.EmptyString, None)
        self.m_localToolbar.AddSeparator()
        self.m_fullScreen = self.m_localToolbar.AddTool(self._toggleFull, u"tool",
            wx.ArtProvider.GetBitmap(u"gtk-fullscreen", wx.ART_TOOLBAR), wx.NullBitmap, wx.ITEM_NORMAL,
            u"Toggle fullscreen", wx.EmptyString, None)
        self.m_localToolbar.AddSeparator()
        self.m_navigator = self.m_localToolbar.AddTool(self._navigator, u"tool", wx.Bitmap(u"app/res/method.xpm",
            wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_NORMAL, u"insert call", wx.EmptyString, None)
        self.m_localToolbar.Realize()
        self.m_toolbarSizer.Add(self.m_localToolbar, 0, wx.ALL, 5)
        self.Layout()
        # Connect Events
        self.m_editor.Bind(wx.EVT_KILL_FOCUS, self.OnLeaveFocus)
        self.m_editor.Bind(wx.EVT_SET_FOCUS, self.OnGetFocus)

    def __init__(self, parent, mainframe, method):
        """Intialization of method editor"""
        super(PyModulePane, self).__init__(parent)
        self._mainframe = mainframe
        self._object = method
        self._types = {}
        self._notebook = parent

        self._create_toolbars()
        self.m_editor.SetText(method._content)
        self.m_editor.Initialize(self._types)
        """
        if method.note:
            self.m_editor.AnnotationSetVisible(wx.stc.STC_ANNOTATION_BOXED)
            self.m_editor.AnnotationSetText(0, method.note)"""
        self.m_editor.SetReadOnly(method._readOnly)
        #self.m_editor.SendMsg(2540, wp="Prueba de anotacion", lp=long(0))
        #self.m_editor.SendMsg(2548, wp=1, lp=long(0))
        self.Layout()
        wx.stc.EVT_STC_CHANGE(self.m_editor,
            self.m_editor.GetId(), self.OnEditorChange)

        #self.Bind(EVT_STC_STYLENEEDED, self.handleStyleNeeded,
        #id=self.m_editor.GetId())
        frame = context.frame

        self.Bind(wx.EVT_MENU, frame.CloseCurrentDocPane, id=CLOSE_PANE_ID)
        self.Bind(wx.EVT_MENU, self.OnDeleteCode, id=self._deleteCode)
        self.Bind(wx.EVT_MENU, self.OnUndoCode, id=self._undoCode)
        self.Bind(wx.EVT_MENU, self.OnRedoCode, id=self._redoCode)
        self.Bind(wx.EVT_MENU, self.OnCopyCode, id=self._copyCode)
        self.Bind(wx.EVT_MENU, self.OnPasteCode, id=self._pasteCode)
        self.Bind(wx.EVT_MENU, self.OnCutCode, id=self._cutCode)
        self.Bind(wx.EVT_MENU, self.OnSaveCode, id=self._saveCode)
        self.Bind(wx.EVT_MENU, self.OnFullScreen, id=self._toggleFull)

        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateDeleteCode, id=self._deleteCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUndoCode, id=self._undoCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateRedoCode, id=self._redoCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCopyCode, id=self._copyCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdatePasteCode, id=self._pasteCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCutCode, id=self._cutCode)
        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateSaveCode, id=self._saveCode)

        self.m_editor.popup_handler = self
        self._fullScreen = None

        aTable = wx.AcceleratorTable([
            wx.AcceleratorEntry(wx.ACCEL_ALT | wx.ACCEL_CTRL, ord('F'), self._toggleFull),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('W'), CLOSE_PANE_ID),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('S'), self._saveCode),
            wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_DELETE, self._deleteCode)
        ])
        self.SetAcceleratorTable(aTable)

    def Refresh(self):
        """Update editor from external changes (like undo/redo)"""
        self.m_editor.SetText(self._object._content)
        if wx.__version__ >= '3.0.0':
            self.m_editor.SetModified(False)

    def PreDelete(self):
        """Remove toolbar first in order to avoid gtk-collision at close"""
        #self.m_editor.Destroy()
        self.m_localToolbar.Destroy()

    def Popup(self, editor, text=None):
        """Shows a custom popup"""
        menu = wx.Menu()
        if text:
            # in the future, we need to show a complete floating dialog here
            # we receive "this->" or "object." here ..
            pass
        else:
            menu.Append(self._mainframe.editProperties.GetId(),
            "test menu", "Edit relation properties")
        pos = editor.GetCurrentPos()
        p = editor.PointFromPosition(pos)
        editor.PopupMenu(menu, p)
        menu.Destroy()

    def OnNavigator(self, event):
        """Navigate throug the class structure"""
        pos = self.m_editor.GetCurrentPos()
        p = self.m_editor.PointFromPosition(pos)
        p = self.m_editor.ClientToScreen(p)
        dialog = app.ui.dlg.CodeNavigator(self, self._object)
        dialog.Move(p)
        if dialog.ShowModal() != wx.ID_OK:
            return
        pass

    def OnUndoCode(self, event):
        """Edit undo"""
        self.m_editor.Undo()

    def OnRedoCode(self, event):
        """Edit redo"""
        self.m_editor.Redo()

    def OnUpdatePasteCode(self, event):
        """Edit paste?"""
        event.Enable(self.m_editor.CanPaste())

    def OnUpdateCopyCode(self, event):
        """Edit copy?"""
        (b, e) = self.m_editor.GetSelection()
        event.Enable(b != e)

    def OnUpdateCutCode(self, event):
        """Edit cut?"""
        if self._object._readOnly:
            event.Enable(False)
        else:
            (b, e) = self.m_editor.GetSelection()
            event.Enable(b != e)

    def OnUpdateRedoCode(self, event):
        """Edit redo?"""
        if self.m_editor.CanRedo():
            event.SetText("Redo edit")
            event.Enable(True)
        else:
            event.SetText("Can't redo")
            event.Enable(False)

    def OnUpdateUndoCode(self, event):
        """Edit undo?"""
        if self.m_editor.CanUndo():
            event.SetText("Undo edit")
            event.Enable(True)
        else:
            event.SetText("Can't undo")
            event.Enable(False)

    def OnUpdateDeleteCode(self, event):
        """Edit delete?"""
        event.Enable(not self._object._readOnly)

    def Enabled(self, event):
        """Joker event"""
        event.Enable(True)

    def Disabled(self, event):
        """Joker event"""
        event.Enable(False)

    def UpdateModifiedTitle(self):
        """Update the tile after modifications"""
        if not self._fullScreen:
            i = self._notebook.GetPageIndex(self)
            s = self._notebook.GetPageText(i)
            m = '[modified] '
            if self.m_editor.IsModified():
                if s.find(m) == wx.NOT_FOUND:
                    self._notebook.SetPageText(i, m + s)
            else:
                if s.find(m) != wx.NOT_FOUND:
                    s = s.replace(m, '')
                    self._notebook.SetPageText(i, s)

    def OnEditorChange(self, event):
        """Called when editor status change"""
        if not self._fullScreen:
            self.UpdateModifiedTitle()

    @tran.TransactionalMethod('edit method')
    def Commit(self):
        """Update document"""
        text = self.m_editor.GetText()
        o = self._object
        if text == o._content:
            return False
        o.SaveState()
        o._content = text
        o.project.SetModified(True)
        o.ExportPythonCodeFiles()
        return True

    def OnDeleteCode(self, event):
        """Handle delete key"""
        (b, e) = self.m_editor.GetSelection()
        if b == e:
            self.m_editor.CharRight()
        self.m_editor.DeleteBack()

    def OnCopyCode(self, event):
        """Handle a copy event"""
        self.m_editor.Copy()

    def OnPasteCode(self, event):
        """Handle a paste event"""
        self.m_editor.Paste()

    def OnCutCode(self, event):
        """Handle a paste event"""
        self.m_editor.Cut()

    def OnUpdateSaveCode(self, event):
        """Handles update event"""
        event.Enable(self.m_editor.IsModified())

    def OnSaveCode(self, event):
        """Handles save event"""
        self.Commit()
        self.m_editor.ResetModified()
        self.UpdateModifiedTitle()

    def OnFullScreen(self, event):
        """ShowFullscreen"""
        if self._fullScreen:
            self._fullScreen.LeaveFullScreen()
            wx.YieldIfNeeded()
            self._fullScreen.Close(True)
            self._fullScreen = None
            self.UpdateModifiedTitle()
        else:
            self._fullScreen = pane.FullScreen(self)
        self.m_editor.SetFocus()

    def handleStyleNeeded(self, event):
        """Handle scintylla events"""
        wnd = self.m_editor
        pos = wnd.GetCurrentPos()
        if pos == 0:
            return
        if wnd.GetCharAt(pos - 1) == wx.T(':'):
            lnno = wnd.GetCurrentLine()
            iden = wnd.GetLineIndentation(lnno - 1)
            wnd.SetLineIndentation(lnno, iden)

            # = self.m_editor.GetFoldLevel(lnno - 1)
        # if this is not a normal line
        #self.m_editor.SetFoldLevel(lnno,LastIndent)
        #pass


    #def AutoIdent(self, event):
    #    """Handle enter"""
    #    key = event.GetKeyCode()
    #    wnd = self.m_editor
    #    if key == wx.WXK_NUMPAD_ENTER or key == wx.WXK_RETURN:
    #        if wnd.GetCharAt(wnd.GetCurrentPos() - 1) == 58:
    #            line = wnd.GetCurrentLine() + 1
    #            wnd.SetLineIndentation(line,
    #                wnd.GetLineIndentation(line) + wnd.GetTabWidth())
    #    event.Skip()



