"""Primitive class browser.

XXX TO DO:

- generalize the scrolling listbox with some behavior into a base class
- add popup menu with more options (e.g. doc strings, base classes, imports)
- show function argument list (have to do pattern matching on source)
- should the classes and methods lists also be in the module's menu bar?

"""

import os
import string
import pyclbr
from Tkinter import *
import tkMessageBox
from WindowList import ListedToplevel
from Separator import HSeparator

from ScrolledList import ScrolledList


class ClassBrowser:

    def __init__(self, flist, name, path=[]):
        root = flist.root
        try:
            dict = pyclbr.readmodule(name, path)
        except ImportError, msg:
            tkMessageBox.showerror("Import error", str(msg), parent=root)
            return
        if not dict:
            tkMessageBox.showerror("Nothing to browse",
                "Module %s defines no classes" % name, parent=root)
            return
        self.flist = flist
        self.dict = dict
        self.root = root
        self.top = top = ListedToplevel(root)
        self.top.protocol("WM_DELETE_WINDOW", self.close)
        self.top.bind("<Escape>", self.close)
        top.wm_title("Class Browser - " + name)
        top.wm_iconname("ClBrowser")
        self.sepa = HSeparator(top)
        leftframe, rightframe = self.sepa.parts()
        self.leftframe = leftframe
        self.rightframe = rightframe
        leftframe.pack(side="left", fill="both", expand=1)
        # Create help label
        self.helplabel = Label(leftframe, text="Module %s" % name,
                               relief="groove", borderwidth=2)
        self.helplabel.pack(fill="x")
        # Create top frame, with scrollbar and listbox
        self.classviewer = ClassViewer(
            self.leftframe, self.flist, self)
        # Load the classes
        self.load_classes(dict, name)

    def close(self, event=None):
        self.classviewer = None
        self.methodviewer = None
        self.top.destroy()

    def load_classes(self, dict, module):
        self.classviewer.load_classes(dict, module)
        if self.methodframe:
            self.methodframe.destroy()
            self.methodframe = None
        self.methodviewer = None

    methodframe = None
    methodhelplabel = None
    methodviewer = None

    def show_methods(self, cl):
        if not self.methodframe:
            self.methodframe = Frame(self.rightframe)
            self.methodframe.pack(side="right", expand=1, fill="both")
            self.methodhelplabel = Label(self.methodframe,
                               relief="groove", borderwidth=2)
            self.methodhelplabel.pack(fill="x")
            self.methodviewer = MethodViewer(self.methodframe, self.flist)
        self.methodhelplabel.config(text="Class %s" % cl.name)
        self.methodviewer.load_methods(cl)


class ClassViewer(ScrolledList):

    def __init__(self, master, flist, browser):
        ScrolledList.__init__(self, master, width=40)
        self.flist = flist
        self.browser = browser

    def load_classes(self, dict, module):
        self.clear()
        self.dict = dict
        items = []
        for key, value in dict.items():
            if value.module == module:
                items.append((value.lineno, key, value))
        items.sort()
        for lineno, key, value in items:
            s = key
            if value.super:
                super = []
                for sup in value.super:
                    name = sup.name
                    if sup.module != value.module:
                        name = "%s.%s" % (sup.module, name)
                    super.append(name)
                s = s + "(%s)" % string.join(super, ", ")
            self.append(s)

    def getname(self, index):
        name = self.listbox.get(index)
        i = string.find(name, '(')
        if i >= 0:
            name = name[:i]
        return name

    def getclass(self, index):
        return self.dict[self.getname(index)]

    def on_select(self, index):
        self.show_methods(index)

    def on_double(self, index):
        self.show_source(index)

    def show_methods(self, index):
        cl = self.getclass(index)
        self.browser.show_methods(cl)

    def show_source(self, index):
        cl = self.getclass(index)
        if os.path.isfile(cl.file):
            edit = self.flist.open(cl.file)
            edit.gotoline(cl.lineno)


class MethodViewer(ScrolledList):

    def __init__(self, master, flist):
        ScrolledList.__init__(self, master)
        self.flist = flist

    classinfo = None

    def load_methods(self, cl):
        self.classinfo = cl
        self.clear()
        items = []
        for name, lineno in cl.methods.items():
            items.append((lineno, name))
        items.sort()
        for item, name in items:
            self.append(name)

    def click_event(self, event):
        pass

    def on_double(self, index):
        self.show_source(self.get(index))

    def show_source(self, name):
        if os.path.isfile(self.classinfo.file):
            edit = self.flist.open(self.classinfo.file)
            edit.gotoline(self.classinfo.methods[name])
