# -*- coding: utf-8 -*-
"""
    The moo Editor
    ~~~~~~~~~~~~~~

    :copyright: 2005-2008 by The PIDA Project
    :license: GPL 2 or later (see README/COPYING/LICENSE)

"""

# Standard Libs
import os
import gtk
import gobject
import re
from gtk import gdk

# UGLY UGLY workarround as suggested by muntyan_
# this will be changed someday when therue will be a correct 
# api for this.
from pida.core.environment import home, workspace_name

SYS_DATA = os.environ.get("XDG_DATA_DIRS", 
                          "/usr/share:/usr/local/share")

MOO_DATA_DIRS=os.pathsep.join((
                str(home()/'moo'),
                os.path.join(os.path.dirname(__file__), "shared"),
                os.pathsep.join([os.path.join(x, "moo") 
                                for x in SYS_DATA.split(os.pathsep)]),
                "/usr/share/moo",
                "/usr/local/share/moo",
                "/usr/share/pida",
                "/usr/local/share/pida",
                ))

os.environ['MOO_DATA_DIRS'] = MOO_DATA_DIRS

def _load_pix(fn):
    #XXX: not zip save
    path = os.path.join(os.path.dirname(__file__), 'pixmaps', fn)
    return gtk.gdk.pixbuf_new_from_file(path)

_PIXMAPS = {
    'bookmark':              _load_pix('bookmark.png'),
    'debugger_breakpoint':   _load_pix('breakpoint.png'),
    'debugger_position':     _load_pix('breakpoint.png'),
}

# Moo Imports
try:
    import moo
except ImportError:
    moo = None
# PIDA Imports
from pida.ui.views import PidaView
from pida.core.editors import EditorService, EditorActionsConfig
from pida.core.actions import TYPE_NORMAL, TYPE_TOGGLE
from pida.core.events import EventsConfig
from pida.core.document import DocumentException
from pida.core.options import OptionsConfig, choices
from pida.ui.completer import (PidaCompleter, PidaCompleterWindow, 
    SuggestionsList)
from pygtkhelpers.gthreads import GeneratorTask, gcall, AsyncTask
from pida.core.languages import Suggestion
from pida.ui.languages import PidaDocWindow

# locale
from pida.core.locale import Locale
locale = Locale('mooedit')
_ = locale.gettext

from .langs import build_mapping, MAPPINGS

class MooeditMain(PidaView):
    """Main Mooedit View.

       This View contains a gtk.Notebook for displaying buffers.
    """

    def create_ui(self):
        self._embed = MooeditEmbed(self)
        se
lf.add_main_widget(self._embed)

    #AA Needs implementing
    #EA really? I didn't see it called anytime.
    #   Did it with relay to the service for now.
    def grab_input_focus(self):
        print "\n\ngrab_input_focus\n\n"
        self.svc.grab_focus()
        pass




class MooeditOptionsConfig(OptionsConfig):

    def create_options(self):
       
 self.create_option(
            'display_type',
            _('Display notebook title'),
            choices({'filename':_('Filename'), 'fullpath':_('Full path'), 
                     'project_or_filename':_('Project relative path or filename')}),
            'project_or_filename',
            _('Text to display in the Notebook'),
        )
        self.create_option(
            'autocomplete',
            _('Enable Autocompleter'),
            bool,
            True,
            _('Shall the Autocompleter be active'),
        )
        self.create_option(
            'auto_chars',
            _('Autocompleter chars'),
            int,
            3,
            _('Open Autocompleter after howmany characters'),
        )
        self.create_option(
            'auto_attr',
            _('On attribute'),
            bool,
            True,
            _('Open Autocompleter after attribute accessor'),
        )


class MooeditPreferences(PidaView):
    """Mooedit Preferences View.

       Here the Mooedit editor preferences dialog is included
       and provided with some buttons.
    """

    label_text = _('Mooedit Preferences')

    icon_name = 'package_utilities'
    
    def create_ui(self):
        prefs = self.svc._editor_instance.prefs_page()
        prefs.emit('init')
        prefs.show()
        vbox = gtk.VBox()
        vbox.pack_start(prefs)
        self._prefs = prefs

        bb = gtk.HButtonBox()

        bb.set_spacing(6)
        bb.set_layout(gtk.BUTTONBOX_END)

        self._apply_but = gtk.Button(stock=gtk.STOCK_APPLY)
        self._apply_but.connect('clicked', self.cb_apply_button_clicked)

        self._ok_but = gtk.Button(stock=gtk.STOCK_OK)
        self._ok_but.connect('clicked', self.cb_ok_button_clicked)

        self._cancel_but = gtk.Button(stock=gtk.STOCK_CANCEL)
        self._cancel_but.connect('clicked', self.cb_cancel_button_clicked)

        bb.pack_start(self._apply_but)
        bb.pack_start(self._cancel_but)
        bb.pack_start(self._ok_but)
        bb.show_all()
        vbox.pack_start(bb)
        vbox.show()
        self.add_main_widget(vbox)

    def cb_ok_button_clicked(self, button):
        self._apply()
        self.svc.show_preferences(self.svc.get_action('mooedit_preferences').set_active(False))

    def cb_apply_button_clicked(self, button):
        self._apply()

    def cb_cancel_button_clicked(self, button):
        self.svc.show_preferences(self.svc.get_action('mooedit_preferences').set_active(False))

    def _apply(self):
        self._prefs.emit('apply')
        self.svc.save_moo_state()
        try:
             self.svc._editor_instance.apply_prefs()
        except AttributeError:
             pass

    def can_be_closed(self):
        self.svc.get_action('mooedit_preferences').set_active(False)


class MooeditEmbed(gtk.Notebook):
    """Mooedit Embed

       This is the actual Notebook that holds our buffers.
    """

    def __init__(self, mooedit):
        gtk.Notebook.__init__(self)
        self.set_scrollable(True)
        self.popup_enable()
        self._mooedit = mooedit
        self.show_all()

    def _create_tab(self, document):
        editor = document.editor
        hb = gtk.HBox(spacing=2)
        editor._label = gtk.Label()
        ns = self._mooedit.svc._get_document_title(document)
        editor._label.set_markup(ns)
        editor._label._markup = ns
        b = gtk.Button()
        b.set_border_width(0)
        b.connect("clicked", self._close_cb, document)
        b.set_relief(gtk.RELIEF_NONE)
        b.set_size_request(20, 20)
        img = gtk.Image()
        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
        b.add(img)
        vb = gtk.VBox()
        vb.pack_start(gtk.Alignment())
        vb.pack_start(b, expand=False)
        vb.pack_start(gtk.Alignment())
        hb.pack_start(editor._label)
        hb.pack_start(vb, expand=False)
        hb.show_all()
        return hb

    def _close_cb(self, btn, document):
        self._mooedit.svc.boss.get_service('buffer').cmd('close_file', document=document)


class MooeditView(gtk.ScrolledWindow):
    """Mooedit View

       A gtk.ScrolledWindow containing the editor instance we get from mooedit.
    """

    def __init__(self, document):
        gtk.ScrolledWindow.__init__(self)
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.set_editor(document.editor)
        self.document = document
        self.line_markers = []
        self.show_all()

    def set_editor(self, editor):
        self.editor = editor
        self.editor.props.buffer.connect('changed', self.on_changed)
        self.add(self.editor)
        self.editor.show()

    def on_changed(self, textbuffer):
        #FIXME: this doesn't work, nor does connect_after work correctly. 
        # this is always one changed event to late. as the markers line position 
        # is updated after this event :(
        self.editor.props.buffer.do_changed(textbuffer)
        for lm in self.line_markers:
            lm.update(lm._moo_marker.get_line()+1)
        return True

    def close(self):
        buf = self.editor.get_buffer()
        for lm in self.line_markers:
            if hasattr(lm, '_moo_marker'):
                lm._moo_marker.props.visible = False
                buf.delete_line_mark(lm._moo_marker)
                del lm._moo_marker
        self.editor.inputter.disconnect()

    def update_marker(self, marker):
        if marker.line == -1:
            